2015-08-14 42 views
8

在我的iOS應用程序中,我想讓用戶鳴叫GIF。將GIF附加到TWTRComposer?

我有一個工作TWTRComposer,並試圖用setImage方法來連接一個GIF:

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

然後圖像出現在作曲家觀點,但是當圖像被張貼到Twitter,這是一個靜態圖像,而比GIF。

是否可以將GIF附加到使用TWTRComposer創建的推文上?

編輯

我試圖整合這個庫創建動畫的UIImage:

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

更新我的代碼,我有以下幾點:

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

但這仍然會在Twitter上產生靜態圖片。

編輯#2

另外一個觀察 - 如果我的GIF保存到我的手機,並嘗試在Twitter上直接從照片庫共享(這帶來了什麼看起來是一個TWTRComposer窗口),它發佈爲圖片,而不是GIF。這使我對你可能無法爲GIF附加到TWTRComposer ...

回答

1

I前不久發佈了這個問題,但終於實現了這個功能。

TWTRComposer仍然不支持添加除圖像以外的任何內容,因此我使用了建議的媒體/上傳REST API。我可以發佈GIF和視頻。啁啾或者媒體之前,我創建一個自定義UIAlertView中,讓別人作曲鳴叫:

enter image description here

然後,當他們挖掘鳴叫按鈕,GIF被啾啾,如果它足夠小;否則,視頻將被推送。

得到的GIF鳴叫:https://twitter.com/spinturntable/status/730609962817294336

生成的視頻鳴叫:https://twitter.com/spinturntable/status/730609829128081408

這裏是我是如何實現這個功能(很多的幫助,從這個帖子https://stackoverflow.com/a/31259870/1720985)。

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

} 

然後檢測UIAlertView中分享Tweet(我加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); 
        } 

       }]; 
      } 
     } 
    } 

一些額外的東西:

用於組成的tweet消息創建初始UIAlertView中我重點UITextView在撰寫鳴叫提醒時出現:

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

下面是如何檢查的UITextView是否有小於140個字符:

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

希望爲我花了很長時間才拼湊起來的一切,這是對別人有用。

3

我不相信TWTRComposer目前支持GIF動畫或視頻附件。我想你可以直接調用media/upload REST API端點發布的附件,然後用statuses/update方法將其連接到鳴叫。

+0

感謝您的幫助 - 你碰巧有一個如何做到這一點的例子? – scientiffic

+2

@scientiffic以下是使用REST API發佈視頻的示例。 http://stackoverflow.com/questions/31259869/share-video-on-twitter-with-fabric-api-without-composer-ios/ – John81

+0

@ john81感謝您的鏈接!我猜你需要爲人們創建一個自定義窗口來輸入他們的推文文本? – scientiffic

3

我剛剛構建了一個具有GIF功能並且需要能夠發佈到Twitter的應用程序。不幸的是,他們的作曲家不能使用GIF(我99.9999%確定,如果你以某種方式工作,請告訴我)。

我的解決方案實際上是,如果用戶選擇在Twitter上分享,則將GIF轉換爲僅重複GIF(我的GIF始終持續2秒)的10秒視頻。

我設法使用AVAssetWriterInput和AVAssetWriterInputPixelBufferAdaptor。它也給了我一個傻瓜證明的方式張貼到其他社交媒體,因爲他們中許多人不支持通過作曲家(信使?)的GIF。

這裏是你如何可以共享視頻/ GIF /任何其他介質上的任何共享的平臺類型。

確保您的視圖控制器響應UIActivityItemSource協議:

@interface MyCustomViewController() <UIActivityItemSource> 

然後,我假設你有一些所謂的方法,當你想要分享:

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

    }]; 
} 

然後你就需要使用與我們之前遵循的協議有關的此方法:

//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

感謝您的回覆 - 在我的應用程序中,我實際上同時擁有一個視頻和GIF圖片,可以發佈到twitter。但我沒有看到向TWTRComposer添加任何圖像的選項。你是如何上傳視頻的? – scientiffic

+0

很好的問題,我會編輯我的回覆。 – AlexKoren

+0

哇,謝謝!我會先嚐試一下,然後標記答案,如果它有效。 – scientiffic