将GIF附加到TWTRComposer?

时间:2015-08-14 20:12:23

标签: ios objective-c twitter twitter-fabric

在我的iOS应用中,我想让用户发推文GIF。

我有一个正在运行的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保存到手机并尝试直接从照片库(打开看起来像是TWTRComposer窗口)在Twitter上分享它,它会以图像而不是GIF的形式发布。这导致我可能无法将GIF附加到TWTRComposer ......

2 个答案:

答案 0 :(得分:3)

我刚刚构建了一个具有GIF功能并且需要能够发布到Twitter的应用程序。不幸的是,他们的作曲家不适用于GIF(我99.9999%肯定,如果你以某种方式让它工作,请告诉我。)

我的解决方案实际上是,如果用户选择在Twitter上分享,将GIF转换为10秒重复播放GIF的视频(我的GIF持续时间为2秒)。

我设法使用AVAssetWriterInput和AVAssetWriterInputPixelBufferAdaptor来完成它。它还给了我一个简单的方式发布到其他社交媒体渠道,因为他们中的许多人不通过作曲家支持GIF(Messenger?)。

以下是在任何可共享平台上分享视频/ GIF /任何其他媒体类型的方法。

确保您的视图控制器响应UIActivityItemSource协议:

source 'https://rubygems.org'

gem 'rails', '3.2.12'

# Bundle edge Rails instead:
# gem 'rails', :git => 'git://github.com/rails/rails.git'


# Gems used only for assets and not required
# in production environments by default.
group :assets do
  gem 'sass-rails',   '~> 3.2.3'
  gem 'coffee-rails', '~> 3.2.1'
  gem 'zurb-foundation'

# See https://github.com/sstephenson/execjs#readme for more supported runtimes
# gem 'therubyracer', :platforms => :ruby

gem 'uglifier', '>= 1.0.3'
end

gem 'jquery-rails', '~> 2.3.0'

group :development do
  gem "better_errors"
  gem 'annotate'
  gem 'pry'
  gem 'sqlite3'
end

group :production do
  gem 'pg'
end

gem 'ember-rails'
gem 'ember-source', '~> 1.10'
gem 'handlebars-source', '~> 2.0.0'
gem 'active_model_serializers', '~>0.8.0'
gem 'filepicker-rails'

gem 'thin'
gem 'unicorn'
gem 'capistrano'
gem 'simple_form'

# To use ActiveModel has_secure_password
# gem 'bcrypt-ruby', '~> 3.0.0'

# To use Jbuilder templates for JSON
# gem 'jbuilder'

# Use unicorn as the app server
# gem 'unicorn'

# Deploy with Capistrano
# gem 'capistrano'

# To use debugger
# gem 'debugger'

# File upload extension
gem "paperclip", "~> 4.3"

# Admin
gem 'activeadmin'

然后,我假设您在分享时调用了一些方法:

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

    }];
}

答案 1 :(得分:1)

我刚刚发布了这个问题,但最终还是实现了这个功能。

TWTRComposer仍然不支持添加除图像之外的任何内容,因此我按照建议使用了媒体/上传REST API。我能够推特GIF和视频。在推特任一媒体之前,我创建了一个自定义UIAlertView,让某人编写推文:

enter image description here

然后,当他们点击推文按钮时,如果GIF足够小,就会收到推文。否则,视频会在Twitter上发布。

结果GIF推文:https://twitter.com/spinturntable/status/730609962817294336

结果视频推文:https://twitter.com/spinturntable/status/730609829128081408

以下是我实施此功能的方法(此帖https://stackoverflow.com/a/31259870/1720985提供了大量帮助)。

创建用于撰写推文消息的初始UIAlertView:

-(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推文(我添加了一个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);
                    }

                }];
            }
        }
    }

一些额外的事情:当Compose Tweet Alert出现时,我会关注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]];
    }
}

希望这对其他人有用,因为我花了很长时间将所有东西拼凑在一起。