すべてのプロダクト
Search
ドキュメントセンター

ApsaraVideo VOD:iOS SDK を使用したファイルのアップロード

最終更新日:Sep 05, 2026

ApsaraVideo VOD iOS アップロード SDK を使用すると、アプリから動画ファイルと画像ファイルを VOD ストレージに直接アップロードできます。アプリはバックエンドの認証サービスからアップロード認証情報を取得し、SDK はその認証情報を使用して、サーバーを経由せずに OSS にファイルをアップロードします。

仕組み

アップロードプロセスには、iOS アプリ、バックエンドサービス、および ApsaraVideo VOD (OSS にファイルを保存) の 3 者が関わります。ワークフローは次のとおりです:

  1. アプリが SDK を呼び出してアップロードを開始すると、SDK は getAuth コールバックを呼び出します。

  2. コールバックでは、お使いのアプリがバックエンドサービスにアップロード認証情報を要求すると、バックエンドサービスは VOD OpenAPI 操作 (CreateUploadVideo など) を呼び出してレスポンスを返します。

  3. アプリが OpenAPI レスポンスを SDK に渡すと、SDK はそのレスポンスから UploadAuth と UploadAddress を抽出し、ファイルを直接 OSS にアップロードします。

  4. 大規模なアップロード中に認証情報の期限が切れると、SDK は refresh 種別で getAuth コールバックを再度呼び出し、新しい認証情報を取得します。

前提条件

ApsaraVideo VOD クイックスタート

項目

要件

最小 iOS バージョン

iOS 12.0

開発言語

Objective-C (Swift プロジェクトでは Bridging Header を使用してブリッジします)

Alibaba Cloud アカウント

ApsaraVideo VOD が有効化されていること

認証サービス

アップロード認証情報 (UploadAuth) を発行できるバックエンドサービスが用意されていること

SDK の統合

統合方法

方法 1:Pod 統合

お使いの Podfile に以下の内容を追加します:

platform :ios, '12.0'
target 'YourApp' do
  pod 'VODUpload', '~> 2.0'
end

次のコマンドを実行します:

pod repo update
pod install

SDK は、基盤となる AliyunOSSiOS 依存関係を自動的にプルします。

方法 2:Swift Package Manager (SPM) 統合

  1. Xcode のメニューで [File]→[Add Package Dependencies] を選択し、リポジトリアドレス https://github.com/aliyunvideo/VODUpload.git を入力します。

  2. バージョンルールには Up to Next Major Version を選択し、初期バージョンに 2.0.1 を入力します。

  3. プロダクト VODUpload を App ターゲットに追加します。

または、Package.swift で宣言します:

package(url: "https://github.com/aliyunvideo/VODUpload.git", from: "2.0.1")

内部の OSS 依存関係はメインパッケージとともに自動的に解決されます。手動で追加したり設定したりする必要はありません。統合完了後は、import VODUpload を記述するだけで利用できます。API の使用方法は CocoaPods で統合した場合と同じです。

プロジェクト設定

podspec では次のシステムライブラリが宣言されており、CocoaPods で統合すると自動的にリンクされます:

SystemConfiguration.framework
MobileCoreServices.framework
CoreMedia.framework
AVFoundation.framework
CoreTelephony.framework
libresolv.tbd

SDK には PrivacyInfo.xcprivacy プライバシーマニフェストが含まれており、Pod 統合時に自動的に VODUpload.bundle/PrivacyInfo.xcprivacy にインジェクトされます。追加の設定は不要です。

必要なヘッダーファイルをインポートします:

#import <VODUpload/VODUploadV2Client.h>
#import <VODUpload/VODUploadConfig.h>
#import <VODUpload/VODAuthContext.h>
#import <VODUpload/VODGetAuthCallback.h>
#import <VODUpload/VODUploadOptions.h>
#import <VODUpload/VODUploadResult.h>
#import <VODUpload/VODUploadError.h>
#import <VODUpload/VODVideoMeta.h>
#import <VODUpload/VODImageMeta.h>
#import <VODUpload/VODUploadTask.h>

アップロードのワークフロー

アップロードインスタンスの初期化

VODUploadConfig は、プロパティを使用して直接設定を行います。+uploaderWithConfig: ファクトリメソッドを呼び出してインスタンスを作成します。

VODUploadConfig *config = [[VODUploadConfig alloc] init];
config.getAuth = getAuth;                  // 必須:認証コールバック。詳細については、「認証コールバックの処理」をご参照ください。

VODUploadV2Client *uploader = [VODUploadV2Client uploaderWithConfig:config];

uploader インスタンスはプロパティとして保持する必要があります。ローカル変数にすると、ARC によって解放されてしまい、コールバックが失われる原因となります。同じインスタンスを再利用して、複数のファイルを並行してアップロードできます。ライフサイクルの終了時に [uploader dispose] を呼び出して、リソースを解放してください。

ファイルのアップロード

uploadFile:options:callback: を呼び出してアップロードを開始します。このメソッドは、キャンセルに使用できる VODUploadTask ハンドルを返します:

VODVideoMeta *meta = [[VODVideoMeta alloc] init];
meta.title = @"My Video";
meta.tags = @"demo";
meta.cateId = @(1000);

VODUploadOptions *options = [[VODUploadOptions alloc] init];
options.videoMeta = meta;
options.onProgress = ^(float percent, int64_t uploaded, int64_t total) {
    NSLog(@"%.1f%%", percent * 100);
};

VODUploadTask *task = [uploader uploadFile:filePath
                                   options:options
                                  callback:^(VODUploadResult *r, VODUploadError *e) {
    if (e) {
        NSLog(@"%@: %@", e.errorCode, e.errorMessage);
        return;
    }
    NSLog(@"videoId=%@ uploadTaskId=%@ etag=%@ requestId=%@ durationMs=%lld",
          r.videoId, r.uploadTaskId, r.etag, r.requestId, r.durationMs);
}];

// アップロードをキャンセルします。レジュームアップロードはデフォルトで有効なため、同じファイルで次回 uploadFile を呼び出すと、アップロードが自動的に再開されます。
[task cancel];
// task.uploadTaskId はログの関連付けやトラッキング連携に使用できます。

画像のアップロード: SDK は、ファイル拡張子 (jpg / jpeg / png / gif / bmp / webp / heic) に基づく場合、または options.imageMeta != nil が明示的に設定されている場合に、自動的に画像のアップロードとして処理します。成功コールバックでは、imageId と imageUrl に値が設定されます。

VODImageMeta *imgMeta = [[VODImageMeta alloc] init];
imgMeta.imageType = @"cover";
imgMeta.title = @"Cover";

VODUploadOptions *opts = [[VODUploadOptions alloc] init];
opts.imageMeta = imgMeta;

[uploader uploadFile:imagePath options:opts callback:cb];
説明

VODVideoMeta の説明フィールドは、Objective-C の予約済みメソッドとの競合を避けるため、description ではなく desc です。

認証コールバックの処理

v2 では、VODGetAuthCallback ブロックはアプリケーションからアップロード認証情報を要求します。SDK は特定のタイミングで getAuth を呼び出し、VODAuthContext.kind を使用して必要な認証情報タイプを示します。

Kind

トリガー

呼び出す OpenAPI

VODAuthKindCreateVideo

動画ファイルの初回アップロード

CreateUploadVideo

VODAuthKindRefreshVideo

レジュームアップロード / 認証情報の更新

RefreshUploadVideo

VODAuthKindCreateImage

画像のアップロード

CreateUploadImage

アプリケーションは、バックエンドの OpenAPI 呼び出しからの raw JSON レスポンスを completion に直接渡します。SDK は、OpenAPI レスポンスからフィールド名で次のキーを読み取ります (大文字と小文字が区別されます):

Kind

必須フィールド

VODAuthKindCreateVideo / VODAuthKindRefreshVideo

UploadAuth, UploadAddress, VideoId

VODAuthKindCreateImage

UploadAuth, UploadAddress, ImageId, ImageURL

フィールド名では大文字と小文字が区別されます。OpenAPI レスポンスはそのまま渡してください。フィールドを手動で videoId、imageUrl、または image_url に名前変更すると、SDK はそれらを nil として解析します。

VODGetAuthCallback getAuth = ^(VODAuthContext *ctx,
                               void (^completion)(NSDictionary *result, NSError *error)) {
    switch (ctx.kind) {
        case VODAuthKindCreateVideo:
            [YourBackend createUploadVideo:ctx.fileName
                                  fileSize:ctx.fileSize
                                completion:^(NSDictionary *json, NSError *err) {
                completion(json, err);
            }];
            break;
        case VODAuthKindRefreshVideo:
            [YourBackend refreshUploadVideo:ctx.videoId
                                 completion:^(NSDictionary *json, NSError *err) {
                completion(json, err);
            }];
            break;
        case VODAuthKindCreateImage:
            [YourBackend createUploadImage:ctx.fileName
                                completion:^(NSDictionary *json, NSError *err) {
                completion(json, err);
            }];
            break;
    }
};

高度な設定

アップロードアクセラレーション

VODVideoMeta.userData を次の JSON に設定すると、UploadAddress の発行時に VOD サーバーが OSS グローバル転送アクセラレーションエンドポイント (oss-accelerate.aliyuncs.com) を自動的に返します。SDK はそのアクセラレーションエンドポイントに直接アップロードします。

VODVideoMeta *meta = [[VODVideoMeta alloc] init];
meta.title = @"My Video";
meta.userData = @"{\"Type\":\"oss\",\"Domain\":\"oss-accelerate.aliyuncs.com\"}";

アップロードアクセラレーションは OSS グローバル転送アクセラレーションに依存します。OSS コンソールでバケットの転送アクセラレーションを有効にする必要があります。詳細については、「転送アクセラレーションを使用した OSS へのアクセス」をご参照ください。

アップロードとトランスコード

VODVideoMeta を使用して、トランスコーディングテンプレートグループまたはワークフローを指定します:

VODVideoMeta *meta = [[VODVideoMeta alloc] init];
meta.title = @"My Video";
meta.desc = @"Video description";                     // 注:description ではなく desc を使用します
meta.coverUrl = @"https://example.com/cover.jpg";
meta.cateId = @(1000);
meta.tags = @"tag1,tag2";
meta.storageLocation = @"<Optional: custom storage region>";
meta.templateGroupId = @"<Your template group ID>";    // トランスコードテンプレートグループ
meta.workflowId = @"<Your workflow ID>";          // ワークフロー (オプション)
meta.appId = @"<Optional: application ID>";

VODVideoMeta でサポートされているフィールドは、title、desc、coverUrl、cateId、tags、userData、storageLocation、templateGroupId、workflowId、および appId です。すべてのフィールドは任意であり、CreateUploadVideo に渡されます。

アップロードが完了すると、VOD サーバーはテンプレートグループに基づいてソースビデオをトランスコードします。トランスコードを開始したくない場合は、バックエンドから CreateUploadVideo を呼び出す際に、「トランスコードなし」テンプレートグループを渡します。

タイムアウトとリトライ

VODUploadConfig *config = [[VODUploadConfig alloc] init];
config.getAuth = getAuth;
config.timeout = 60;            // 単位:秒。デフォルト値:60
config.maxRetryCount = 2;       // デフォルト値:2

timeout は、単一の OSS リクエストに対する接続および読み書きのタイムアウト (NSTimeInterval、秒単位) を制御します。maxRetryCount は、ネットワークエラー発生時の OSS リクエストの再試行回数を制御します。

重要

timeout の単位は、Android ではミリ秒、iOS では秒です。クロスプラットフォームで実装する際は、この違いにご注意ください。

署名バージョン

config.signature = @"v4";        // デフォルト値:@"v4"。有効な値:@"v1"

OSS V4 署名は推奨バージョンです。2025 年 9 月 1 日以降、新規作成バケットには V4 署名が必須となります。既存のお客様も、お早めの移行を推奨します。アプリケーションで使用されるバケットがまだ V1 署名のみをサポートしている場合にのみ、@"v1" を明示的に設定してください。

レジュームアップロード

レジュームアップロードはデフォルトで有効になっています。SDK は (lastModified, fileName, fileSize) の 3つ組をレジュームアップロードキーとして使用し、それをローカルの Caches ディレクトリに自動的に永続化します。

シナリオ

SDK の動作

[task cancel] はアップロード中に呼び出されます

レジュームアップロードの記録は保持されます。次に同じファイルで uploadFile: を呼び出すと、アップロードが自動的に再開されます。

アプリがクラッシュする、またはバックグラウンドで終了する

レジュームアップロードの記録は保持されます。 次のコールドスタート時に同じファイルで uploadFile: を呼び出すと、アップロードが自動的に再開されます。

ファイルフィンガープリントの変更

ファイルは新規ファイルとして扱われ、最初からアップロードされます。

OSS uploadId の有効期限切れ

SDK は古い記録を自動的にクリアし、VODAuthKindCreateVideo 経由で新規アップロードを開始します。

レジュームアップロードを無効にするには:

config.checkpoint = NO;

マルチパートアップロード

partSize でパートサイズを制御し、parallel で並列数を制御します。

// グローバル設定
config.partSize = 1024 * 1024;     // デフォルト値:1 MB
config.parallel = 4;               // デフォルト値:4

// タスク単位で上書き
VODUploadOptions *options = [[VODUploadOptions alloc] init];
options.videoMeta = meta;
options.partSize = 2 * 1024 * 1024;
options.parallel = 6;

VOD サービスリージョンの設定

config.region = @"cn-shanghai";    // デフォルト値:cn-shanghai

サポートされているリージョンの一覧については、「ApsaraVideo VOD のリージョン ID」をご参照ください。

データレポート

SDK は、製品品質の監視のためにアップロードリンクトラッキングをデフォルトで有効にしています。収集されるのはアップロードプロセスの実行時メトリクスのみで、ファイル内容は含まれません。データレポートを無効にするには:

config.reportEnabled = NO;       // デフォルト値:YES

エラー処理

VODUploadError は NSError を継承します。エラーコードは UPLOAD.{LAYER}.{TYPE} の 3 セグメント形式です:

LAYER

エラーコード

説明

AUTH

UPLOAD.AUTH.GET_AUTH_FAILED

getAuth コールバックに失敗しました。

AUTH

UPLOAD.AUTH.DECODE_FAILED

UploadAuth のデコードに失敗しました。

AUTH

UPLOAD.AUTH.EXPIRED

認証情報の有効期限が切れています。

OSS

UPLOAD.OSS.ACCESS_DENIED

OSS へのアクセスが拒否されました (権限/署名の問題)。

OSS

UPLOAD.OSS.NO_SUCH_BUCKET

バケットが存在しません。

OSS

UPLOAD.OSS.NO_SUCH_UPLOAD

uploadId の有効期限が切れています。SDK は自動的にフォールバックします。

OSS

UPLOAD.OSS.UPLOAD_FAILED

OSS のアップロードに失敗しました。

OSS

UPLOAD.OSS.MERGE_FAILED

OSS マルチパートのマージに失敗しました。

NETWORK

UPLOAD.NETWORK.TIMEOUT

ネットワークタイムアウト。

NETWORK

UPLOAD.NETWORK.UNREACHABLE

ネットワークに到達できません。

FILE

UPLOAD.FILE.NOT_FOUND

ファイルが存在しません。

FILE

UPLOAD.FILE.EMPTY

ファイルが空です。

CANCEL

UPLOAD.CANCEL.USER_CANCELLED

ユーザーがアップロードをキャンセルしました。

INTERNAL

UPLOAD.INTERNAL.DISPOSED

インスタンスは破棄されています。

INTERNAL

UPLOAD.INTERNAL.INVALID_CONFIG

設定が無効です。

パブリックプロパティ:

  • NSString *errorCode — エラーコード

  • NSString *errorMessage — エラーメッセージ

  • NSError *cause — 基になる OSS の例外

  • NSString *uploadTaskId — アップロードタスク ID

  • NSString *suggestion — SDK 組み込みの修正案

if ([error.errorCode hasPrefix:@"UPLOAD.AUTH."]) {
    // ユーザーにバックエンドの認証を確認するよう促します
} else if ([error.errorCode isEqualToString:@"UPLOAD.OSS.UPLOAD_FAILED"]) {
    // リトライするか、ユーザーにネットワークを確認するよう促します
}
NSLog(@"%@ : %@ (cause=%@, suggestion=%@)",
      error.errorCode, error.errorMessage, error.cause, error.suggestion);

よくある質問

複数の uploadFile 呼び出しを同時に開始できますか?

はい。各 task は独立しています。parallel との組み合わせによる過度なアップストリーム帯域幅への圧迫を避けるため、ネットワーク状況に応じて同時アップロード数を制御してください。

キャンセル後に再アップロードするとレジュームアップロードが機能しない

次の手順で問題を切り分けてください:

  • ファイルパスが同一かどうかを確認してください。

  • ファイルの lastModified またはサイズが変更されていないかを確認してください。

  • config.checkpoint が YES に設定されているかどうかを確認してください。

  • uploadId が期限切れかどうかを確認します。NoSuchUpload レスポンスを受信すると、SDK は自動的に新規アップロードにフォールバックします。これは想定される動作です。

App Store Connect の審査で "missing privacy manifest" を理由にリジェクトされる

SDK には、Pod の統合時に自動的に組み込まれる PrivacyInfo.xcprivacy ファイルが含まれています。お使いのアプリで使用する Required Reason API も宣言されていることを確認してください。

uploader を作成した後にコールバックがトリガーされない

uploader がローカル変数ではないことを確認してください。 VODUploadV2Client インスタンスは self のプロパティとして保持する必要があります。 そうしないと、ARC によって早期に解放されてしまいます。