2015-08-14 17 views
8

In meiner iOS App möchte ich Benutzern ermöglichen, GIFs zu twittern.GIF an TWTRComposer anhängen?

Ich habe eine Arbeits TWTRComposer und versucht, eine GIF-Befestigung durch die SetImage Methode:

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

Das Bild erscheint dann in dem Komponisten Ansicht, aber wenn das Bild auf Twitter gepostet wird, ist es ein statisches Bild eher als ein GIF.

Ist es möglich, ein GIF an einen mit TWTRComposer erstellten Tweet anzuhängen?

bearbeiten

Ich habe versucht, diese Bibliothek zu integrieren eine animierte UIImage zu erstellen:

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

meinen Code aktualisiert, habe ich die folgenden:

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

Aber diese führt immer noch zu einem statischen Bild auf Twitter.

Edit # 2

Eine andere Beobachtung - wenn ich das GIF auf mein Handy zu speichern und versuchen Sie es auf Twitter von der Foto-Bibliothek direkt zu teilen (das öffnet, was ein TWTRComposer Fenster aussieht), es postet als ein Bild, kein GIF. Was dazu führt, dass Sie möglicherweise kein GIF an einen TWTRComposer anhängen können ...

Antwort

1

I hat diese Frage schon vor einiger Zeit gestellt, ist aber schließlich dazu gekommen, dieses Feature zu implementieren.

TWTRComposer unterstützt immer noch nichts anderes, als Bilder hinzuzufügen, daher habe ich die REST-API für Medien/Upload wie vorgeschlagen verwendet. Ich bin in der Lage, sowohl GIFs als auch Videos zu twittern. Bevor eine der Medien tweeten, erstelle ich einen benutzerdefinierten UIAlertView, dass jemand Komponist einen Tweet lässt:

enter image description here

dann, wenn sie den Tweet-Taste tippen, wird ein GIF getwittert wenn es klein genug; Andernfalls wird ein Video getwittert.

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

resultierende Video Tweet: https://twitter.com/spinturntable/status/730609829128081408

Hier ist, wie ich diese Funktion (viel Hilfe von diesem Posten https://stackoverflow.com/a/31259870/1720985) realisiert.

Erstellen Sie die anfänglichen UIAlertView für den Tweet-Nachricht:

-(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]; 
    } 

} 

die UIAlertView Tweet Dann erkennen (Ich füge ein 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); 
        } 

       }]; 
      } 
     } 
    } 

einige zusätzliche Dinge: Ich konzentriere mich die UITextView, wenn der Compose Tweet Alert erscheint:

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

Hier ist, wie ich überprüfen, ob der UITextView hat weniger als 140 Zeichen:

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

Hope this für andere nützlich ist, wie es mir eine lange Zeit in Anspruch nahm alles Stück zusammen.

3

Ich glaube nicht, dass der TWTRComposer derzeit animierte GIF- oder Videoanhänge unterstützt. Ich denke, Sie müssen den REST-API-Endpunkt media/upload direkt aufrufen, um den Anhang zu posten, und dann die Methode statuses/update verwenden, um sie an einen Tweet anzuhängen.

+0

danke für deine hilfe - hast du zufällig ein beispiel dafür? – scientiffic

+2

@scientiffic Hier ist ein Beispiel für das Posten eines Videos mit der REST-API. http://stackoverflow.com/questions/31259869/share-video-on-twitter-with-fabric-api-without-composer-ios/ – John81

+0

@ john81 danke für diesen link! Ich schätze, dass Sie ein benutzerdefiniertes Fenster erstellen müssen, damit Leute den Text ihres Tweets eingeben können. – scientiffic

3

Ich habe gerade eine App mit GIF-Funktionalität erstellt, die auf Twitter gepostet werden kann. Leider arbeitet ihr Komponist nicht mit GIFs (ich bin 99,9999% sicher und wenn Sie es irgendwie funktionieren, lassen Sie es mich wissen).

Meine Lösung war eigentlich, wenn der Benutzer wählen, auf Twitter zu teilen, die GIF zu einem 10 Sekunden Video konvertieren, die nur auf Wiederholung die GIF hatten (mein GIFs waren immer 2 Sekunden Dauer).

Ich schaffte es mit AVAssetWriterInput und AVAssetWriterInputPixelBufferAdaptor. Es gab mir auch eine narrensichere Möglichkeit, in anderen sozialen Medien zu posten, da viele von ihnen keine GIFs über den Komponisten (Messenger?) Unterstützen.

So können Sie ein Video/GIF/einen beliebigen anderen Medientyp auf einer gemeinsam nutzbaren Plattform freigeben.

Stellen Sie sicher, dass View-Controller an das UIActivityItemSource Protokoll antwortet:

@interface MyCustomViewController() <UIActivityItemSource> 

Dann werde ich annehmen, dass Sie eine Methode haben aufgerufen, wenn Sie teilen möchten:

- (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:^{ 

    }]; 
} 

Dann werden Sie müssen diese Methode haben, die zu dem Protokoll gehört, das wir früher übereinstimmten:

//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's 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's text, send a GIF 
    else if ([activityType isEqualToString:UIActivityTypeMessage]) 
     item = self.gifData; 
    //If it's 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; 
} 
+0

Danke für deine Antwort - in meiner App habe ich sowohl ein Video als auch ein GIF, das ich auf Twitter posten kann.Aber ich sehe keine Option, um TWTRComposer etwas anderes als ein Bild hinzuzufügen. Wie hast du ein Video hochgeladen? – scientiffic

+0

große Frage, ich werde meine Antwort bearbeiten. – AlexKoren

+0

wow, danke! Ich werde das zuerst ausprobieren und dann die Antwort markieren, wenn es funktioniert. – scientiffic