使用Fabric API在iOS中分享视频到Twitter,无需使用composer

13

在一月份,可以通过REST API将视频上传到Twitter,但不能使用Fabric框架:链接


如果您有多个段落,可以尝试此解决方案: https://stackoverflow.com/a/48563257/3894440 - bojanb89
2个回答

20

根据文档,为了上传媒体文件,需要使用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);
            }

        }];
    }
}

2
感谢@fechidal提供简明且最新的答案! - elliotrock
1
@fechidal:太棒了..运行得很好!可惜Twitter自己没有这个功能。 - Nishant
1
@John81 我也遇到了同样的问题。你找到解决方案了吗? - Rakesh Bhatt
1
@Rakesh Bhatt 我从未能够让这个工作起来。我在发布有关在推文中上传视频的问题时得到了一个答案,可能是一个解决方案,但我还没有时间去看看那个解决方案是否解决了问题。http://stackoverflow.com/questions/32789859/how-do-i-upload-video-in-a-tweet-in-an-ios-app-using-xcode/34448161#34448161 - John81
1
@John81 这里是API错误代码链接:https://dev.twitter.com/overview/api/response-codes,错误400 - 错误请求 - 请求无效或无法提供其他服务。附带的错误消息将进一步解释。在API v1.1中,未经身份验证的请求被视为无效,并将产生此响应。 - fechidal89
显示剩余6条评论

11

非常出色的回答,我乐在其中将其转换为Swift,花了我一些时间,这里放上来供其他遇到同样问题的人参考:

很好的答案,我愉快地将其转换为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")
        }
    })

}

1
@Swinny89,我已经实现了与你相同的代码,但是返回了“Command APPEND failed”错误信息,我不知道出了什么问题,请帮助我解决。 - Zalak Patel
1
println("Command APPEND failed") 之前添加 println(error),以便更清楚地了解请求失败的原因。 - Swinny89
1
@Swinny89 它会抛出这样的错误:“请求失败:未经授权(401)”UserInfo=0x7f9d00d61fc0 {NSErrorFailingURLKey=https://upload.twitter.com/1.1/media/upload.json, NSLocalizedDescription=请求失败:未经授权(401),NSLocalizedFailureReason=Twitter API 错误: 无法验证您的身份。(code 32)})" - Zalak Patel
这个解决方案已经不再适用了。你有最新的解决方案吗?我没有收到关于我的帖子http://stackoverflow.com/questions/36248965/ios-swift-how-to-post-a-video-to-twitter 的答案,也没有找到任何关于Swift 2的相关解决方案。 - Sam

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接