【问题标题】:Share video on Twitter with Fabric API without composer iOS使用 Fabric API 在 Twitter 上分享视频,无需 composer iOS
【发布时间】:2015-09-24 10:15:40
【问题描述】:

通过 REST API for Twitter 的视频上传功能在 1 月可用,但在 Fabric 框架中不可用: link!

【问题讨论】:

标签: ios objective-c video twitter twitter-fabric


【解决方案1】:

根据documentation 需要使用以下命令进行 3 次调用:INIT、APPEND 和 FINALIZE。

-(void) shareOnTwitterWithVideo:(NSDictionary*) params{   
    NSString *text = params[@"text"];
    NSData* dataVideo = params[@"video"];
    NSString *lengthVideo = [NSString stringWithFormat:@"%d", [params[@"length"] intValue]];
    NSString* url = @"https://upload.twitter.com/1.1/media/upload.json";

    __block NSString *mediaID;

    if([[Twitter sharedInstance] session]){

        TWTRAPIClient *client = [[Twitter sharedInstance] APIClient];
        NSError *error;
        // First call with command INIT
        NSDictionary *message =  @{ @"status":text,
                                   @"command":@"INIT",
                                @"media_type":@"video/mp4",
                               @"total_bytes":lengthVideo};
        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"];
                client = [[Twitter sharedInstance] APIClient];
                NSError *error;
                NSString *videoString = [dataVideo base64EncodedStringWithOptions:0];
                // Second call with command APPEND
                message = @{@"command" : @"APPEND",
                           @"media_id" : mediaID,
                      @"segment_index" : @"0",
                              @"media" : videoString};

                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
                                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);
                                    }else{
                                        NSLog(@"Error: %@", error);
                                    }
                                }];
                            }else{
                                NSLog(@"Error command FINALIZE: %@", error);
                            }
                        }];

                    }else{
                        NSLog(@"Error command APPEND: %@", error);
                    }
                }];

            }else{
                NSLog(@"Error command INIT: %@", error);
            }

        }];
    }
}

【讨论】:

  • 感谢@fechidal 提供简洁和最新的答案!
  • @fechidal:太棒了.. 效果很好!可惜推特自己没有这个。
  • 我在 APPEND 上遇到错误 ---> 错误域=TWTRNetworkingErrorDomain 代码=-1011 “请求失败:错误请求 (400)”。有什么想法可以解决这个问题吗?
  • @John81 你确定收到一个 mediaID 吗? videoString 是您的 NSData 视频转换为基于 64 的字符串,您确定吗?
  • @fechidal 是的,我确实从 INIT 响应中获得了 mediaID -> 响应:{ "expires_after_secs" = 86399; “media_id”=660168523088433152; "media_id_string" = 660168523088433152; },视频数据看起来也被正确转换为字符串。我希望我收到更具描述性的错误消息。
【解决方案2】:

很好的答案,把它转换成 swift 很有趣,花了我一段时间,所以这里是为其他有同样问题的人准备的:

var video: NSData!
let strUploadUrl = "https://upload.twitter.com/1.1/media/upload.json"
let strStatusUrl = "https://api.twitter.com/1.1/statuses/update.json"

func postVideo() {
    var client = Twitter.sharedInstance().APIClient
    var text: String = "Testing Video"
    var videoLength: String = "\(self.video.length)" 
    var mediaID: String = ""

    var initError: NSError? 
    var message = ["status": text, "command" : "INIT", "media_type" : "video/m4v", "total_bytes" : videoLength]
    var preparedRequest: NSURLRequest = client.URLRequestWithMethod("POST", URL: self.strUploadUrl, parameters: message, error: &initError)
    client.sendTwitterRequest(preparedRequest, completion: { (urlResponse: NSURLResponse?, responseData: NSData?, error: NSError?) -> Void in
        if error == nil {
            var jsonError: NSError?
            var json: NSDictionary = (NSJSONSerialization.JSONObjectWithData(responseData!, options: nil, error: &jsonError) as? NSDictionary)!
            println(json)
            var mediaID = json.objectForKey("media_id_string") as! String

            client = Twitter.sharedInstance().APIClient
            var uploadError: NSError?
            var videoString = self.video.base64EncodedStringWithOptions(nil)
            message = ["command" : "APPEND", "media_id" : mediaID, "segment_index" : "0", "media" : videoString]
            var preparedRequest = client.URLRequestWithMethod("POST", URL: self.strUploadUrl, parameters: message, error: &uploadError)
            client.sendTwitterRequest(preparedRequest, completion: { (urlResponse: NSURLResponse?, responseData: NSData?, error: NSError?) -> Void in
                if error == nil {
                    client = Twitter.sharedInstance().APIClient
                    var finalizeError: NSError?
                    message = ["command":"FINALIZE", "media_id": mediaID]
                    var preparedRequest = client.URLRequestWithMethod("POST", URL: self.strUploadUrl, parameters: message, error: &finalizeError)
                    client.sendTwitterRequest(preparedRequest, completion: { (urlResponse: NSURLResponse?, responseData: NSData?, error: NSError?) -> Void in
                        if error == nil {
                            client = Twitter.sharedInstance().APIClient
                            var sendError: NSError?
                            var message = ["status": text, "wrap_links": "true", "media_ids": mediaID]
                            var updateMessage = NSMutableDictionary(dictionary: message)
                            var preparedRequest = client.URLRequestWithMethod("POST", URL: self.strStatusUrl, parameters: message , error: &sendError)
                            client.sendTwitterRequest(preparedRequest, completion: { (urlResponse: NSURLResponse?, responseData: NSData?, error: NSError?) -> Void in

                            })
                        } else {
                            println("Command FINALIZE failed \n \(error!)")
                        }
                    })
                } else {
                    println("Command APPEND failed")
                }
            })
        } else {
            println("Command INIT failed")
        }
    })

}

【讨论】:

  • @Swinny89 我已经实现了和你的一样但是返回“命令追加失败”我不知道我做错了什么?请帮我解决。
  • println("Command APPEND failed") 之前添加println(error) 让您更清楚地了解请求失败的原因
  • @Swinny89 抛出这样的错误“请求失败:未经授权(401)” UserInfo=0x7f9d00d61fc0 {NSErrorFailingURLKey=upload.twitter.com/1.1/media/upload.json,NSLocalizedDescription=请求失败:未经授权(401),NSLocalizedFailureReason=Twitter API 错误: 无法验证您的身份。 (代码 32)})"
  • 此解决方案不再起作用。您有最新的解决方案吗?我没有收到我的帖子的答案:stackoverflow.com/questions/36248965/… 也没有找到 swift 2 的任何相关解决方案
猜你喜欢
  • 2015-08-17
  • 1970-01-01
  • 2013-02-05
  • 2013-08-30
  • 2015-12-30
  • 2015-10-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多