👻
iOSからTwitter APIで動画つきツイートする
概要
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;
}
// 動画つきツイート成功!
}];
}
この記事はQiitaの記事をエクスポートしたものです
Discussion