LoginSignup
12
9

More than 5 years have passed since last update.

iOSからTwitter APIで動画つきツイートする

Last updated at Posted at 2016-02-27

概要

iOSからTwitterへ動画のアップロードを行う。

画像の場合は media/upload のAPIの1コールでアップロードできるようだが、動画の場合はエラー(400 bad request)になってしまう。

そのため media/upload-chunked を使う必要がある。

動画の制約

アップロードできる動画の条件は以下のとおり。
- MPEG4
- 1ファイルのみ
- ファイルサイズは最大15MB
- 長さは0.5秒から30秒まで
- 大きさは 32x32 から 1280x1024 まで
- 縦横比は 1:3 から 3:1 まで
- フレームレートは 40fps 以下
- 音声はモノラルかステレオ

SDK

SDK(Fabric TwitterKit)を使う。準備については省略。

手順

ログイン

// Twitterにログインする
// アカウント選択のActionSheetはSDK側で表示される
// 選択およびログインが完了したらコールバックが呼ばれる
Twitter *twitter = [Twitter sharedInstance];
[twitter logInWithCompletion:^(TWTRSession *session, NSError *error) {
    if (error) {
        return;
    }
    // dataは動画のNSData*で事前に読み込んだもの
    [self twitterMediaUploadInitWithSession:session 
                                       data:data];
}];

INIT

- (void)twitterMediaUploadInitWithSession:(TWTRSession*)session 
                                     data:(NSData*)data {

// API Client
TWTRAPIClient *client = [[TWTRAPIClient alloc] initWithUserID:session.userID];

// Requestを用意
NSString *url = @"https://upload.twitter.com/1.1/media/upload.json";
NSDictionary *params = @{
    @"command": @"INIT",
    @"total_bytes": [NSString stringWithFormat:@"%d", data.length], // @(data.length) だと死ぬ
    @"media_type": @"video/mp4",
};
NSError* error = nil;
NSURLRequest *request = [client URLRequestWithMethod:@"POST" 
                                                 URL:url 
                                          parameters:params 
                                               error:&error];
if (error) {
    return;
}

// 送信
[client sendTwitterRequest:request completion:^(NSURLResponse *response, NSData *body, NSError *twError) {
    if (twError) {
        return;
    }
    NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:body 
                                                         options:0 
                                                           error:&twError];
    if (twError) {
        return;
    }

    // レスポンスのJSON内のmedia_id_stringで一連の処理を行う
    [self twitterMediaUploadAppendWithClient:client 
                                        data:data 
                                     mediaId:dict[@"media_id_string"]];
}];

}

APPEND

- (void)twitterMediaUploadAppendWithClient:(TWTRAPIClient*)client 
                                      data:(NSData*)data 
                                   mediaId:(NSString*)mediaId {

if (!mediaId || [mediaId length] <= 0) {
    return;
}

// Requestを用意
NSString *dataStr = [data base64EncodedStringWithOptions:0];
NSString *url = @"https://upload.twitter.com/1.1/media/upload.json";
NSDictionary *params = @{
    @"command": @"APPEND",
    @"media_id": mediaId,
    @"media_data": dataStr, // BASE64しないと死ぬ
    @"segment_index": @"0", // この例では1回のAPPENDで送信しきるので0
};
NSError* error = nil;
NSURLRequest *request = [client URLRequestWithMethod:@"POST" 
                                                 URL:url 
                                          parameters:params 
                                               error:&error];
if (error) {
    return;
}

// 送信
[client sendTwitterRequest:request completion:^(NSURLResponse *response, NSData *body, NSError *twError) {
    if (twError) {
        return;
    }
    [self twitterMediaUploadFinalizeWithClient:client 
                                       mediaId:mediaId];
}];

}

FINALIZE

- (void)twitterMediaUploadFinalizeWithClient:(TWTRAPIClient*)client 
                                     mediaId:(NSString*)mediaId {

// Requestを用意
NSString *url = @"https://upload.twitter.com/1.1/media/upload.json";
NSDictionary *params = @{
    @"command": @"FINALIZE",
    @"media_id": mediaId,
};
NSError* error = nil;
NSURLRequest *request = [client URLRequestWithMethod:@"POST" 
                                                 URL:url 
                                          parameters:params 
                                               error:&error];
if (error) {
    return;
}

// 送信
[client sendTwitterRequest:request completion:^(NSURLResponse *response, NSData *body, NSError *twError) {
    if (twError) {
        return;
    }
    [self twitterStatusUpdateWithClient:client 
                                mediaId:mediaId];
}];

}

Tweet

- (void)twitterStatusUpdateWithClient:(TWTRAPIClient*)client 
                              mediaId:(NSString*)mediaId {

// Requestを用意
NSString *url = @"https://api.twitter.com/1.1/statuses/update.json"
NSDictionary *params = @{
    @"status": @"ツイート文はここに入れる",
    @"media_ids": mediaId,
};
NSError* error = nil;
NSURLRequest *request = [client URLRequestWithMethod:@"POST" 
                                                 URL:url 
                                          parameters:params 
                                               error:&error];
if (error) {
    return;
}

// 送信
[client sendTwitterRequest:request completion:^(NSURLResponse *response, NSData *body, NSError *twError) {
    if (twError) {
        return;
    }
    // 動画つきツイート成功!
}];

}
12
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
9