Share video on Twitter through the iOS app

Can I share a video using SLRequest?

I can share images using the same

SLRequest *postRequest = [SLRequest requestForServiceType:SLServiceTypeTwitter requestMethod:SLRequestMethodPOST URL:requestURL parameters:message]; if (isImage) { NSData *data = UIImagePNGRepresentation(imgSelected); [postRequest addMultipartData:data withName:@"media" type:@"image/png" filename:@"TestImage.png"]; } postRequest.account = account; [postRequest performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) { if (!error) { NSLog(@"Upload Sucess !"); } }]; 
+6
source share
6 answers

I read the Twitter video upload API documentation and it is really quite simple. You basically need to make 3 POST requests to their API. Downloaded video is also limited to 15 MB.

Downloads using this endpoint require at least 3 calls, from one to initiate a request that returns media_id, one or more calls to add / download binary or base 64 encoded data, and one last call to complete the download and make media_id suitable for use with other resources .

So it works as follows:

  • Request 1: send an initialization request with the video size in bytes. This will return the media id number that we should use in queries 2 and 3.

  • Request 2: Use the returned media ID with request 1 to download the video data.

  • Request 3: Once the video download is complete, send the “FINALIZE” request back to the Twitter API. This allows the Twitter API to know that all pieces of the video file have completed uploading.

Note The Twitter API supports uploading videos in chunks. Therefore, if your video file is quite large, you can split it into several files, and you will have to repeat “Request 2” more than once (remember to increase the number of “segment_index” each time).

I had such coding below. Try and experiment with it. I will also update my answer to improve it.

 -(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info { // Assign the mediatype to a string NSString *mediaType = [info objectForKey:UIImagePickerControllerMediaType]; // Check the media type string so we can determine if its a video if ([mediaType isEqualToString:@"public.movie"]) { NSURL *videoURL = [info objectForKey:UIImagePickerControllerMediaURL]; NSData *webData = [NSData dataWithContentsOfURL:videoURL]; // Get the size of the file in bytes. NSString *yourPath = [NSString stringWithFormat:@"%", videoURL]; NSFileManager *man = [NSFileManager defaultManager]; NSDictionary *attrs = [man attributesOfItemAtPath:yourPath error: NULL]; UInt32 result = [attrs fileSize]; //[self tweetVideoStage1:webData :result]; [self tweetVideo:webData :result :1 :@"n/a"]; } } -(void)tweetVideo:(NSData *)videoData :(int)videoSize :(int)mode :(NSString *)mediaID { NSURL *twitterVideo = [NSURL URLWithString:@"https://upload.twitter.com/1.1/media/upload.json"]; // Set the parameters for the first twitter video request. NSDictionary *postDict; if (mode == 1) { postDict = @{@"command": @"INIT", @"total_bytes" : videoSize, @"media_type" : @"video/mp4"}; } else if (mode == 2) { postDict = @{@"command": @"APPEND", @"media_id" : mediaID, @"segment_index" : @"0", @"media" : videoData }; } else if (mode == 3) { postDict = @{@"command": @"FINALIZE", @"media_id" : mediaID }; } SLRequest *postRequest = [SLRequest requestForServiceType:SLServiceTypeTwitter requestMethod:SLRequestMethodPOST URL:requestURL:twitterVideo parameters:postDict]; // Set the account and begin the request. postRequest.account = account; [postRequest performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) { if (!error) { if (mode == 1) { // Parse the returned data for the JSON string // which contains the media upload ID. NSMutableDictionary *returnedData = [NSJSONSerialization JSONObjectWithData:responseData options:NSJSONReadingMutableContainers error:&error] NSString *tweetID = [NSString stringWithFormat:@"%@", [returnedData valueForKey:@"media_id_string"]]; [self tweetVideo:videoData :result :2 :tweetID]; } else if (mode == 2) { [self tweetVideo:videoData :result :3 :mediaID]; } } else { NSLog(@"Error stage %d - %", mode, error); } }]; } 

Update - Twitter API Errors - https://dev.twitter.com/overview/api/response-codes

In response to your first comment, a 503 error means that the Twitter servers are overloaded and cannot process your request right now.

503 Service Unavailable Twitter servers up, but overloaded with requests. Please try again later.

+4
source

I know how to upload videos to twitter using the new API. And I tried, it works.

Please check this: https://github.com/liu044100/SocialVideoHelper

You just need to call this class method.

 +(void)uploadTwitterVideo:(NSData*)videoData account:(ACAccount*)account withCompletion:(dispatch_block_t)completion; 

Hope he can solve your problem.

Best wishes.

+4
source

Looking for a collaborative video on Twitter solution with the features below:

  • Package Download Support
  • Native support for obtaining user credentials

Since I could not find one meeting that I needed, so I decided to write it.

https://github.com/mtrung/TwitterVideoUpload

I have been testing for some time now and it works well for me.

Hope this helps,

Sincerely.

+2
source

Try this based on @Dan's answer. It has not been tested, but I think it can work.

Use Cocoa -pods : pod 'TwitterKit'

if you do not use pods try with fabric

 //for Extern call //Mode is 1 //MediaId is 0 - (void)uploadTwitterVideo:(NSData*)videoData videoTitle:(NSString *)title desc:(NSString *)desc withMode:(int)mode mediaID:(NSString *)mediaID withCompletion:(dispatch_block_t)completion { NSString *twitterPostURL = @"https://upload.twitter.com/1.1/media/upload.json"; NSDictionary *postParams; if (mode == 1) { postParams = @{@"command": @"INIT", @"total_bytes" : [NSNumber numberWithInteger: videoData.length].stringValue, @"media_type" : @"video/mp4"}; } else if (mode == 2) { postParams = @{@"command": @"APPEND", @"media_id" : mediaID, @"segment_index" : @"0"}; } else if (mode == 3) { postParams = @{@"command": @"FINALIZE", @"media_id" : mediaID }; } else if (mode == 4) { postParams = @{@"status": desc, @"media_ids" : @[mediaID]}; } TWTRAPIClient *twitterInstance = [[Twitter sharedInstance] APIClient]; NSError *error; NSURLRequest *requestTw = [twitterInstance URLRequestWithMethod:@"POST" URL:twitterPostURL parameters:postParams error:&error]; [twitterInstance sendTwitterRequest:requestTw completion:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) { NSLog(@"HTTP Response: %li, responseData: %@", (long)response, [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]); if (error) { NSLog(@"There was an error:%@", [error localizedDescription]); } else { if (mode == 1) { NSMutableDictionary *returnedData = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&connectionError]; NSString *mediaIDResponse = [NSString stringWithFormat:@"%@", [returnedData valueForKey:@"media_id_string"]]; NSLog(@"stage one success, mediaID -> %@", mediaID); [self uploadTwitterVideo:videoData videoTitle:title desc:desc withMode:2 mediaID:mediaIDResponse withCompletion:completion]; } else if (mode == 2) { [self uploadTwitterVideo:videoData videoTitle:title desc:desc withMode:3 mediaID:mediaID withCompletion:completion]; } else if (mode == 3) { [self uploadTwitterVideo:videoData videoTitle:title desc:desc withMode:4 mediaID:mediaID withCompletion:completion]; } else if (mode == 4) { DispatchMainThread(^(){completion();}); } } }]; } 

This API works as follows.

- Logging in when the application (twitter) is installed and not installed

- The first priority takes credentials when setting up

Check this case

+1
source

Swift

It is very simple. First you need to log in to your Twitter account. Go to Phone Settings and click on the Twitter application and log in. Now just call this videoUpload func anywhere

Video or Chunked uploads Method Link

Replace your type of video / extension with this code And carefully read all the twitter requirements .

 var twitterAccount = ACAccount() func videoUpload{ let path = Bundle.main.path(forResource: "file-Name", ofType:"mp4") let filePath = path var fileSize = UInt64() do { //return [FileAttributeKey : Any] let attr = try FileManager.default.attributesOfItem(atPath: filePath!) fileSize = attr[FileAttributeKey.size] as! UInt64 //if you convert to NSDictionary, you can get file size old way as well. let dict = attr as NSDictionary fileSize = dict.fileSize() } catch { print("Error: \(error)") } let accountStore = ACAccountStore() let twitterAccountType = accountStore.accountType(withAccountTypeIdentifier: ACAccountTypeIdentifierTwitter) accountStore.requestAccessToAccounts(with: twitterAccountType, options: nil) { (granted, error) in if granted { let accounts = accountStore.accounts(with: twitterAccountType) if (accounts?.count)! > 0 { self.twitterAccount = accounts?.last as! ACAccount }}} twitterAccount = Twitter.sharedInstance().sessionStore.session() as! ACAccount uploadVideoToTwitter(videoURL: URL(string : path!)! as NSURL, fileSize: UInt32(fileSize)) } func uploadVideoToTwitter(videoURL:NSURL,fileSize: UInt32) { if let videoData = NSData(contentsOfFile: videoURL.path!){ self.tweetVideoInit(videoData: videoData, videoSize: Int(fileSize)) } } func tweetVideoInit(videoData:NSData,videoSize:Int) { let uploadURL = NSURL(string:"https://upload.twitter.com/1.1/media/upload.json") var params = [String:String]() params["command"] = "INIT" params["total_bytes"] = String(videoData.length) params["media_type"] = "video/mp4" let postRequest = SLRequest(forServiceType: SLServiceTypeTwitter, requestMethod: SLRequestMethod.POST, url: uploadURL as URL!, parameters: params) postRequest?.account = self.twitterAccount; postRequest?.perform(handler: { ( responseData, urlREsponse,error) in if let err = error { print(error as Any) }else{ do { let object = try JSONSerialization.jsonObject(with: responseData! as Data, options: .allowFragments) if let dictionary = object as? [String: AnyObject] { if let tweetID = dictionary["media_id_string"] as? String{ self.tweetVideoApped(videoData: videoData, videoSize: videoSize, mediaId: tweetID, chunk: 0) } } } catch { print(error) } } }) } func tweetVideoApped(videoData:NSData,videoSize:Int ,mediaId:String,chunk:NSInteger) { let uploadURL = NSURL(string:"https://upload.twitter.com/1.1/media/upload.json") var params = [String:String]() params["command"] = "APPEND" params["media_id"] = mediaId params["segment_index"] = String(chunk) let postRequest = SLRequest(forServiceType: SLServiceTypeTwitter, requestMethod: SLRequestMethod.POST, url: uploadURL as URL!, parameters: params) postRequest?.account = self.twitterAccount postRequest?.addMultipartData(videoData as Data!, withName: "media", type: "video/mov", filename:"mediaFile") postRequest?.perform(handler: { ( responseData, urlREsponse,error) in if let err = error { print(err) }else{ self.tweetVideoFinalize(mediaId: mediaId) } }) } func tweetVideoFinalize(mediaId:String) { let uploadURL = NSURL(string:"https://upload.twitter.com/1.1/media/upload.json") var params = [String:String]() params["command"] = "FINALIZE" params["media_id"] = mediaId let postRequest = SLRequest(forServiceType: SLServiceTypeTwitter, requestMethod: SLRequestMethod.POST, url: uploadURL as URL!, parameters: params) postRequest?.account = self.twitterAccount; postRequest?.perform(handler: { ( responseData, urlREsponse,error) in if let err = error { print(err) }else{ do { let object = try JSONSerialization.jsonObject(with: responseData! as Data, options: .allowFragments) if let dictionary = object as? [String: AnyObject] { self.postStatus(mediaId: mediaId) } } catch { print(error) } } }) } func postStatus(mediaId:String) { let uploadURL = NSURL(string:"https://api.twitter.com/1.1/statuses/update.json") var params = [String:String]() params["status"] = "my first Video Upload" params["media_ids"] = mediaId let postRequest = SLRequest(forServiceType: SLServiceTypeTwitter, requestMethod: SLRequestMethod.POST, url: uploadURL as URL!, parameters: params) postRequest?.account = self.twitterAccount; postRequest?.perform(handler: { ( responseData, urlREsponse,error) in if let err = error { print(err) }else{ do { let object = try JSONSerialization.jsonObject(with: responseData! as Data, options: .allowFragments) if let dictionary = object as? [String: AnyObject] { print("video uploaded") } } catch { print(error) } } }) } 
0
source

I was able to successfully upload the video to twitter! The following are steps related to twitter documents:

  • Twitter account request

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

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

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

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

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

Here is the ditter doc link https://dev.twitter.com/rest/media/uploading-media.html

Please detail the detailed solution for uploading videos to twitter using SLRequest here.

http://swiftoverflow.blogspot.in/2017/04/upload-video-to-twitter-using-slrequest.html

-1
source

Source: https://habr.com/ru/post/988429/


All Articles