iOS Swift: How to post a video to twitter?

ios
video
swift
twitterkit

#1

Hi guys,

I wasn’t able to find a proper documentation on how to post a video to twitter in swift from an iOS app. I can’t believe there is no relevant documentation because Twitter focuses so much on video sharing today. Also on stack overflow did not fin relevant up to date answers.

This is what I’ve been trying to do but does not work…

func postVideo() {
                
        Twitter.sharedInstance().logInWithCompletion { session, error in
            if (session != nil) {
                print("signed in as \(session!.userName)");
            } else {
                print("error: \(error!.localizedDescription)");
            }
        }
        
        
        if let userID = Twitter.sharedInstance().sessionStore.session()?.userID {
         var client = TWTRAPIClient(userID: userID)
        
        let text: String = "Testing Video"
        let videoLength: String = "\(self.video.length)"
        print(videoLength)
        
        var initError: NSError?
        var message = ["status": text, "command" : "INIT", "media_type" : "video/mp4", "total_bytes" : videoLength]
        let preparedRequest: NSURLRequest = client.URLRequestWithMethod("POST", URL: self.strUploadUrl, parameters: message, error: &initError)
        client.sendTwitterRequest(preparedRequest, completion: { (urlResponse: NSURLResponse?, responseData: NSData?, error: NSError?) -> Void in
            if error == nil {
                
                do {
                    
                    //var jsonError: NSError?
                    let json: NSDictionary = try (NSJSONSerialization.JSONObjectWithData(responseData!, options: NSJSONReadingOptions(rawValue: 0)) as? NSDictionary)!
                    print("JSON is \(json)")
                    
                    
                    let mediaID = json.objectForKey("media_id_string") as! String
                    
                    client = TWTRAPIClient(userID: userID)
                    var uploadError: NSError?
                    let videoString = self.video.base64EncodedStringWithOptions(NSDataBase64EncodingOptions([]))
                    print("message is \(message)")
    message = ["command" : "APPEND", "media_id" : mediaID, "segment_index" : "0", "media" : videoString]
                    //print("message is \(message)")
                    let preparedRequest = client.URLRequestWithMethod("POST", URL: self.strUploadUrl, parameters: message, error: &uploadError)
                    client.sendTwitterRequest(preparedRequest, completion: { (urlResponse: NSURLResponse?, responseData: NSData?, error: NSError?) -> Void in
                        if error == nil {
                            client = TWTRAPIClient(userID: userID)
                            var finalizeError: NSError?
                            message = ["command":"FINALIZE", "media_id": mediaID]
                            let preparedRequest = client.URLRequestWithMethod("POST", URL: self.strUploadUrl, parameters: message, error: &finalizeError)
                            client.sendTwitterRequest(preparedRequest, completion: { (urlResponse: NSURLResponse?, responseData: NSData?, error: NSError?) -> Void in
                                if error == nil {
                                    client = TWTRAPIClient(userID: userID)
                                    var sendError: NSError?
                                    message = ["status": text, "wrap_links": "true", "media_ids": mediaID]
                                    
                                    let preparedRequest = client.URLRequestWithMethod("POST", URL: self.strStatusUrl, parameters:  message, error: &sendError)
                                    client.sendTwitterRequest(preparedRequest, completion: { (urlResponse: NSURLResponse?, responseData: NSData?, error: NSError?) -> Void in
                                        
                                    })
                                } else {
                                    print("Command FINALIZE failed \n \(error!)")
                                }
                            })
                        } else {
                            print("Command APPEND failed")
                        }
                    })
                }
                    
                catch {
                    print("\(error)")
                }
            }
                
            else {
                print("\(error.debugDescription)Command INIT failed")
            }
        })
        }
 
    }

I would like to address this issue with twitter so if you agree with me that it lacks information about posting video to twitter please let me know. I thought Fabric was meant to make things easy for us!


How to post a video?
#2

@mydaypix You would want to use this from Twitter Kit 2.0 -
[TWTRAPIClient uploadMedia:contentType:completion:]

While we don’t have a full sample yet, I’ve noted that we should add this internally.


#3

@bonnell Thanks for your help and the internal note to add this. I have no idea how to use that, how should I do?


TWTRComposer Video Support
#4

@bonnell Can you put me through a developer at Fabric who can answer me promptly please?


#5

I’d recommend taking a look at the header file which has more information on how to use it, including the syntax. For example:

/**
 *  Uploads media to the media server. Returns a media ID to be used when tweeting.
 *
 *  @param media       The media to upload
 *  @param contentType The HTTP content type of the media that you are uploading.
 *  @param completion  The completion handler to invoke.
 */
- (void)uploadMedia:(NSData *)media contentType:(NSString *)contentType completion:(TWTRMediaUploadResponseCompletion)completion;

#6

@bonnell This is exactly what I’ve done. I had a look at the header file but did not really help me. Your example is objective C but anyway I had a look with swift and did not manage to implement it.

Is there any developer in your team that can show a quick example for the community please ?


#7

I can work on a sample, but it will take a little bit of time.


#8

Thanks Mike! That would be fantastic! :grinning:


#9

@bonnell @andypiper Hello Mike and Andy, do you have any idea when you will be able to provide a sample to the community showing how to post a video to twitter with twitterkit?

I’ve been looking everywhere for a solutions and many developers use workarounds or hacks (most objective C) but none use an “official/conventional” way to post a video with twitterkit.

Thank you so much for your help


#10

I don’t think either of us would be able to commit a specific date to you, as we are spread between timezones and the team has a variety of tasks to prioritise - appreciate that you are keen for a Twitter-provided sample! In the meantime, @bonnell pointed you at the relevant header - apologies that it hasn’t given you enough information to go on for the moment. It is possible that someone more Swift-literate than me might see this thread and be able to give it a go for you, too.


#11

@andypiper Thanks a lot for your answer! I highly appreciate your help on that matter :grinning:


#12

@mydaypix I just copied and pasted your block of code in an iOS project and it actually worked for me. The video I uploaded was recorded with an iPhone.

So I believe that the media you are trying to upload might have an invalid specification. Can you double-check the video specifications and recommendations:

https://dev.twitter.com/rest/public/uploading-media#videorecs

Also I suggest you add an error logging after calling

message = ["status": text, "wrap_links": "true", "media_ids": mediaID]
                                        
let preparedRequest = client.URLRequestWithMethod("POST", URL: self.strStatusUrl, parameters:  message, error: &sendError)
           client.sendTwitterRequest(preparedRequest, completion: { (urlResponse: NSURLResponse?, responseData: NSData?, error: NSError?) -> Void in
                      if (error != nil) {
                                 print (error)
                      }
                                            
            })

You might get a media id even if the media file is invalid. In some cases the error will occur only after calling POST statuses/update.


#13

@mydaypix it may also help you to use this media validation tool and inspector to see whether your video matches the requirements.


#14

@jchahoud Indeed it works. Thanks for pointing me in the right direction! Thanks.
How can I get the upload progress ?


#15

@andypiper @bonnell It works thanks for your help. I can get the upload progress though, how to check the upload progress? I can’t find that in your documentation…


#17

Hi I was finally able to upload some videos but with some other I’m getting the following error.Does someone know why I’m getting this?

Error Domain=TWTRNetworkingErrorDomain Code=-1011 “Request failed: bad request (400)” UserInfo={NSLocalizedFailureReason=, TWTRNetworkingStatusCode=400, NSErrorFailingURLKey=https://upload.twitter.com/1.1/media/upload.json, NSLocalizedDescription=Request failed: bad request (400)})


#18

I was able to upload video to twitter successfully!
Below are steps referred from twitter docs:

  1. Request for twitter account

    accountStore.requestAccessToAccounts(with: twitterAccountType,options:nil){(granted, error) in
    
  2. POST media/upload (INIT)

    params["command"] = "INIT"
    params["total_bytes"]  = String(videoData.length)
    params["media_type"]  = "video/mov"
    
  3. POST media/upload (APPEND)

    params["command"] = "APPEND"
    params["media_id"]  = mediaId
    params["segment_index"]  = String(chunk)
    
  4. POST media/upload (FINALIZE)

    params["command"] = "FINALIZE"
    params["media_id"]  = mediaId
    
  5. POST media/upload

    params["status"] = twitterDescription
    params["media_ids"]  = mediaId
    

Please find the detailed solution for video upload to twitter using SLRequest here.