LoginSignup
3
4

More than 5 years have passed since last update.

Swift で、Twitter に 30秒以上の動画を投稿

Posted at

Twitter への動画つき投稿

簡単な方法がありそうでなかったので、地道に api をコツコツ呼びました。
詳細は以下のサイトにまとまっているのですが、基本的な仕組みとswiftでの実装メモを書きました。
CORETWEETで30秒を超える動画をTWITTERにアップロードしてみる

Twitter api を2つ使います

// 動画アップロード用 : こちらに色々なコマンドを投げる
let UPLOAD_URL = NSURL(string: "https://upload.twitter.com/1.1/media/upload.json")

// ツイート用 : 最後に1回投げてツイート完了
let STATUS_URL = NSURL(string: "https://api.twitter.com/1.1/statuses/update.json")

最初に動画をアップロードして、media_id_string を取得

  • UPLOAD_URLにコマンドを投げます。

大きなファイルは分割してアップロード。以下4コマンドを順次呼び出します。
1. INIT (開始。media_id_stringを取得。以後の呼び出しは、全てこの値を使う)
2. APPEND (ファイルを適当な容量に分割して全部アップロードできるまで呼ぶ)
3. FINALIZE (終了)
4. STATUS

ポイントは、アップロード完了から、メディアが使用可能になるまで間があるとこです。
STATUS の戻り値で、state == "succeeded" になるまでポーリングが必要です。

if json["processing_info"]["state"] == "succeeded" {
    // 次の処理へ
}

media_id_string と text を一緒にツイート

  • STATUS_URL にコマンドを投げます。
let params = [
    "status": self.mTweet,
    "media_ids": self.mMediaIdString
]

swift での実装メモ

通信で使用するクラス・メソッド

SLRequest
.addMultipartData
.performRequestWithHandler 

バイナリファイル分割

// CHUNK_SIZE = 2 * 1024 * 1024 など、大きすぎないサイズ。
// mSegmentIndex は、0からの連番。append を呼ぶたびに +1。

var _range = NSRange()
_range.location = mSegmentIndex * CHUNK_SIZE
_range.length = min(CHUNK_SIZE, mFileSize)
let _mediaData = NSData(contentsOfFile: self.mFilePath)
let mediaData = _mediaData?.subdataWithRange(_range)

非同期コードの塊ですが、SwiftTask を使うとネストが深くならずに快適に実装できました。
SwiftTask(Promise拡張)を使う

メモ

FINALIZE -> STATUS 確認まで5秒程必要っぽいので、ツイート編集画面を表示した時点などでこっそりアップロードを開始したいところですが、キャンセル時など、数メガのアップロードが無駄になると思うと悩ましいところです。

以上です。

3
4
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
3
4