Join GIF to TWTRComposer?

In my iOS app, I would like to enable users to tweet GIFs.

I have a working TWTRComposer and I'm trying to set a GIF using the SetImage method:

[composer setImage:[UIImage imageWithData:[NSData dataWithContentsOfURL:self.localGifURL]]]; 

The image then appears in the composer's view, but when the image is sent to Twitter, it is a static image, not a GIF.

Can I connect a GIF to a tweet created using TWTRComposer?

Edit

I tried integrating this library to create an animated UIImage:

https://github.com/mayoff/uiimage-from-animated-gif

Updating my code, I have the following:

 [composer setImage:[UIImage animatedImageWithAnimatedGIFURL:self.localGifURL]]; 

But this still leads to a static image on Twitter.

Edit # 2

Another note: if I save the GIF on my phone and try to share it on Twitter directly from the photo library (which opens a window that looks like a TWTRComposer window), it is placed as an image, not a GIF. This leads me to the fact that you cannot connect GIFs to TWTRComposer ...

+8
ios objective-c twitter fabric-twitter
source share
3 answers

I posted this question a while ago, but finally found a way to implement this feature.

TWTRComposer still does not support adding anything other than images, so I used the media / loading of the REST API as suggested. I can tweet both GIF and video. Before tweeting on any medium, I create a custom UIAlertView that allows someone to compose a tweet:

enter image description here

Then, when they press the twitter button, the GIF gets twitter if it is small enough; otherwise the video will be on Twitter.

GIF Tweet Result: https://twitter.com/spinturntable/status/730609962817294336

Final video: https://twitter.com/spinturntable/status/730609829128081408

Here is how I implemented this function (a lot of help from this post https://stackoverflow.com/a/166605/ ).

Create the source UIAlertView file to compose a tweet message:

 -(IBAction)tweet:(id)sender{ // check if the person has twitter if([[Twitter sharedInstance] session]){ // first, show a pop up window for someone to customize their tweet message, limited to 140 characters UIAlertView *tweetAlert = [[UIAlertView alloc] initWithTitle:@"Compose Tweet" message:nil delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:nil]; tweetAlert.tag = TAG_TWEET; tweetTextView = [UITextView new]; [tweetTextView setBackgroundColor:[UIColor clearColor]]; CGRect frame = tweetTextView.frame; frame.size.height = 500; tweetTextView.frame = frame; [tweetTextView setFont:[UIFont systemFontOfSize:15]]; tweetTextView.textContainerInset = UIEdgeInsetsMake(0, 10, 10, 10); [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(limitTextView:) name:@"UITextViewTextDidChangeNotification" object:tweetTextView]; [tweetTextView setText:[NSString stringWithFormat:@"%@ %@", [[NSUserDefaults standardUserDefaults] valueForKey:@"tweetText"], self.setShareURL]]; [tweetAlert setValue:tweetTextView forKey:@"accessoryView"]; [tweetAlert addButtonWithTitle:@"Tweet"]; [tweetAlert show]; }else{ UIAlertView *alert = [[UIAlertView alloc] initWithTitle:nil message:@"Please log in with your Twitter account to tweet!" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil]; [alert show]; } } 

Then define the UIAlertView Tweet (I add the UIAlertViewDelegate):

 - (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex { if(alertView.tag == TAG_TWEET){ if (buttonIndex == 1) { UIAlertView *tweetStartAlert = [[UIAlertView alloc] initWithTitle:nil message:@"Tweeting..." delegate:self cancelButtonTitle:nil otherButtonTitles:nil]; [tweetStartAlert show]; // get client __block TWTRAPIClient *client = [[Twitter sharedInstance] APIClient]; __block NSString *mediaID; NSString *text = [tweetTextView text]; // get tweet text NSLog(@"text: %@", text); NSData *mediaData; NSString *mediaLength; NSString *mediaType; NSString* url = @"https://upload.twitter.com/1.1/media/upload.json"; // if this is a single spin set, tweet the gif if([self.setSpins count] ==1){ NSLog(@"tweeting GIF with url %@", self.gifURL); mediaData = [NSData dataWithContentsOfURL:[NSURL URLWithString:self.gifURL]]; mediaLength = [NSString stringWithFormat:@"%lu", mediaData.length]; mediaType = @"image/gif"; }else if([self.setSpins count] > 1){ // multi-spin set - tweet the video NSLog(@"tweeting video with url %@", self.videoURL); mediaData = [NSData dataWithContentsOfURL:[NSURL URLWithString:self.videoURL]]; mediaLength = [NSString stringWithFormat:@"%lu", mediaData.length]; mediaType = @"video/mp4"; } NSError *error; // First call with command INIT __block NSDictionary *message = @{ @"status":text, @"command":@"INIT", @"media_type":mediaType, @"total_bytes":mediaLength}; NSURLRequest *preparedRequest = [client URLRequestWithMethod:@"POST" URL:url parameters:message error:&error]; [client sendTwitterRequest:preparedRequest completion:^(NSURLResponse *urlResponse, NSData *responseData, NSError *error){ if(!error){ NSError *jsonError; NSDictionary *json = [NSJSONSerialization JSONObjectWithData:responseData options:0 error:&jsonError]; mediaID = [json objectForKey:@"media_id_string"]; NSError *error; NSString *mediaString = [mediaData base64EncodedStringWithOptions:0]; // Second call with command APPEND message = @{@"command" : @"APPEND", @"media_id" : mediaID, @"segment_index" : @"0", @"media" : mediaString}; NSURLRequest *preparedRequest = [client URLRequestWithMethod:@"POST" URL:url parameters:message error:&error]; [client sendTwitterRequest:preparedRequest completion:^(NSURLResponse *urlResponse, NSData *responseData, NSError *error){ if(!error){ client = [[Twitter sharedInstance] APIClient]; NSError *error; // Third call with command FINALIZE message = @{@"command" : @"FINALIZE", @"media_id" : mediaID}; NSURLRequest *preparedRequest = [client URLRequestWithMethod:@"POST" URL:url parameters:message error:&error]; [client sendTwitterRequest:preparedRequest completion:^(NSURLResponse *urlResponse, NSData *responseData, NSError *error){ if(!error){ client = [[Twitter sharedInstance] APIClient]; NSError *error; // publish video with status NSLog(@"publish video!"); NSString *url = @"https://api.twitter.com/1.1/statuses/update.json"; NSMutableDictionary *message = [[NSMutableDictionary alloc] initWithObjectsAndKeys:text,@"status",@"true",@"wrap_links",mediaID, @"media_ids", nil]; NSURLRequest *preparedRequest = [client URLRequestWithMethod:@"POST" URL:url parameters:message error:&error]; [client sendTwitterRequest:preparedRequest completion:^(NSURLResponse *urlResponse, NSData *responseData, NSError *error){ if(!error){ NSError *jsonError; NSDictionary *json = [NSJSONSerialization JSONObjectWithData:responseData options:0 error:&jsonError]; NSLog(@"%@", json); [tweetStartAlert dismissWithClickedButtonIndex:0 animated:YES]; UIAlertView *tweetFinishedAlert = [[UIAlertView alloc] initWithTitle:nil message:@"Tweeted!" delegate:self cancelButtonTitle:nil otherButtonTitles:nil]; [tweetFinishedAlert show]; double delayInSeconds = 1.5; dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC)); dispatch_after(popTime, dispatch_get_main_queue(), ^(void){ [tweetFinishedAlert dismissWithClickedButtonIndex:0 animated:YES]; }); [self logShare:@"twitter"]; }else{ NSLog(@"Error: %@", error); } }]; }else{ NSLog(@"Error command FINALIZE: %@", error); } }]; }else{ NSLog(@"Error command APPEND: %@", error); } }]; }else{ NSLog(@"Error command INIT: %@", error); } }]; } } } 

Some additional things: I focus on a UITextView when a message about creating a Tweet message appears:

 - (void)didPresentAlertView:(UIAlertView *)alertView { if(alertView.tag == TAG_TWEET){ NSLog(@"tweetAlertView appeared"); [tweetTextView becomeFirstResponder]; } } 

Here, as I check if the UITextView has less than 140 characters:

 - (void)limitTextView:(NSNotification *)note { int limit = 140; if ([[tweetTextView text] length] > limit) { [tweetTextView setText:[[tweetTextView text] substringToIndex:limit]]; } } 

Hope this is helpful to others as it took me a long time to put everything together.

+1
source share

I donโ€™t think TWTRComposer currently supports animated GIFs or video attachments. I think you would need to call the media/upload REST API API endpoint directly to post the attachment, and then use the statuses/update method to attach them to Tweet.

+3
source share

I just created an application that has GIF functionality and the ability to post to Twitter. Unfortunately, their composer does not work with GIF (I'm sure 99.9999%, and if you somehow earn it, let me know).

My solution was that if the user decided to share on Twitter, convert the GIF to a 10 second video that just repeated the GIF (my GIF files always lasted 2 seconds).

I succeeded using AVAssetWriterInput and AVAssetWriterInputPixelBufferAdaptor. It also gave me an impeccable way to post to other social networks, as many of them do not support GIF through composer (Messenger?).

Here you can share video / GIF / any other type of media on any available platform.

Make sure your view controller responds to the UIActivityItemSource protocol:

 @interface MyCustomViewController () <UIActivityItemSource> 

Then, I will assume that you have a method that you want to use:

 - (void)methodCalledToShare { //Create an activity view controller UIActivityViewController *activityController = [[UIActivityViewController alloc] initWithActivityItems:@[self] applicationActivities:nil]; //decide what happens after it closes (optional) [activityController setCompletionWithItemsHandler:^(NSString *activityType, BOOL completed, NSArray *returnedItems, NSError *activityError) { }]; //present the activity view controller [self presentViewController:activityController animated:YES completion:^{ }]; } 

Then you will need this method related to the protocol that we previously agreed:

 //This is an example for if you want to have different data sent based on which app they choose. //I have an NSURL pointing to a local video in "videoUrl" //And I have NSData of a GIF in "gifData" - (id)activityViewController:(UIActivityViewController *)activityViewController itemForActivityType:(NSString *)activityType { id item; //If it Facebook, send a video if ([activityType isEqualToString:UIActivityTypePostToFacebook]) item = self.videoUrl; //if its Twitter, send a GIF else if ([activityType isEqualToString:UIActivityTypePostToTwitter]) item = self.gifData; //if its mail, send a GIF else if ([activityType isEqualToString:UIActivityTypeMail]) item = self.gifData; //If it text, send a GIF else if ([activityType isEqualToString:UIActivityTypeMessage]) item = self.gifData; //If it Facebook Messenger, send a video else if ([activityType isEqualToString:@"com.facebook.Messenger.ShareExtension"]) item = self.videoUrl; //Just default to a video else item = self.videoUrl; return item; } 
+3
source share

All Articles