All Products
Search
Document Center

ApsaraVideo VOD:Unggah file menggunakan iOS SDK

Last Updated:Jul 14, 2026

SDK unggah ApsaraVideo VOD untuk iOS memungkinkan aplikasi Anda mengunggah file video dan gambar langsung ke penyimpanan VOD. Aplikasi Anda memperoleh kredensial unggah dari layanan otorisasi backend, dan SDK menggunakan kredensial tersebut untuk mengunggah file ke OSS tanpa melewati server Anda.

Cara kerja

Proses unggah melibatkan tiga pihak: aplikasi iOS Anda, layanan backend Anda, dan ApsaraVideo VOD (yang menyimpan file di OSS). Alur kerjanya sebagai berikut:

  1. Aplikasi Anda memanggil SDK untuk memulai unggah. SDK memicu callback getAuth.

  2. Dalam callback tersebut, aplikasi Anda meminta kredensial unggah dari layanan backend Anda, yang memanggil operasi VOD OpenAPI (seperti CreateUploadVideo) dan mengembalikan responsnya.

  3. Aplikasi Anda meneruskan respons OpenAPI ke SDK. SDK mengekstrak UploadAuth dan UploadAddress dari respons tersebut dan mengunggah file langsung ke OSS.

  4. Jika kredensial kedaluwarsa selama unggah file besar, SDK memicu kembali callback getAuth dengan jenis refresh untuk memperoleh kredensial baru.

Prasyarat

ApsaraVideo VOD Quick Start

ItemPersyaratan
Versi iOS minimumiOS 12.0
Bahasa pengembanganObjective-C (proyek Swift menggunakan Bridging Header untuk bridging)
Akun Alibaba CloudApsaraVideo VOD telah diaktifkan
Layanan otorisasiLayanan backend yang dapat menerbitkan upload credential (UploadAuth) telah disiapkan

Integrasikan SDK

Metode integrasi

Tambahkan konten berikut ke Podfile Anda:

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

Jalankan perintah berikut:

pod repo update
pod install

SDK secara otomatis menarik dependensi AliyunOSSiOS yang mendasarinya.

Konfigurasi proyek

Podspec mendeklarasikan library sistem berikut, yang secara otomatis ditautkan saat Anda menggunakan CocoaPods untuk integrasi:

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

SDK menyertakan manifes privasi PrivacyInfo.xcprivacy yang secara otomatis disuntikkan ke VODUpload.bundle/PrivacyInfo.xcprivacy selama integrasi pod. Tidak diperlukan konfigurasi tambahan.

Impor file header yang diperlukan:

#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>

Alur unggah

Inisialisasi instans unggah

VODUploadConfig menggunakan properti untuk konfigurasi langsung. Panggil metode factory +uploaderWithConfig: untuk membuat instans:

VODUploadConfig *config = [[VODUploadConfig alloc] init];
config.getAuth = getAuth;                  // Wajib: callback otorisasi. Untuk informasi lebih lanjut, lihat "Tangani callback otorisasi".

VODUploadV2Client *uploader = [VODUploadV2Client uploaderWithConfig:config];

Instans uploader harus dipertahankan sebagai properti. Jika berupa variabel lokal, ARC akan melepaskannya, sehingga menyebabkan kehilangan callback. Anda dapat menggunakan kembali instans yang sama untuk mengunggah beberapa file secara bersamaan. Panggil [uploader dispose] untuk melepaskan sumber daya saat siklus hidup berakhir.

Unggah file

Panggil uploadFile:options:callback: untuk memulai unggah. Metode ini mengembalikan handle VODUploadTask yang dapat Anda gunakan untuk pembatalan:

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);
}];

// Batalkan selama unggah. Resumable upload diaktifkan secara default. Pemanggilan uploadFile berikutnya dengan file yang sama secara otomatis melanjutkan unggah.
[task cancel];
// task.uploadTaskId dapat digunakan untuk mengorelasikan log dan mengintegrasikan dengan pelacakan.

Unggah gambar: SDK secara otomatis menggunakan proses unggah gambar berdasarkan ekstensi file (jpg / jpeg / png / gif / bmp / webp / heic) atau jika options.imageMeta != nil diatur secara eksplisit. Dalam callback sukses, imageId dan imageUrl memiliki nilai:

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];
Catatan

Bidang deskripsi pada VODVideoMeta adalah desc (bukan description, untuk menghindari konflik dengan metode terbatas Objective-C).

Tangani callback otorisasi

Pada v2, blok VODGetAuthCallback meminta kredensial unggah dari aplikasi Anda. SDK memanggil getAuth pada titik-titik tertentu dan menggunakan VODAuthContext.kind untuk menunjukkan jenis kredensial yang diperlukan:

JenisPemicuOpenAPI yang dipanggil
VODAuthKindCreateVideoUnggah pertama kali file videoCreateUploadVideo
VODAuthKindRefreshVideoResumable upload / refresh kredensialRefreshUploadVideo
VODAuthKindCreateImageUnggah gambarCreateUploadImage

Aplikasi Anda meneruskan respons JSON mentah dari panggilan OpenAPI backend langsung ke completion. SDK membaca kunci berikut dari respons OpenAPI berdasarkan nama bidang (sensitif terhadap huruf besar/kecil):

JenisBidang wajib
VODAuthKindCreateVideo / VODAuthKindRefreshVideoUploadAuth, UploadAddress, VideoId
VODAuthKindCreateImageUploadAuth, UploadAddress, ImageId, ImageURL (diteruskan ke result.imageUrl)

Nama bidang sensitif terhadap huruf besar/kecil. Teruskan respons OpenAPI secara langsung. Mengganti nama bidang secara manual menjadi videoId, imageUrl, atau image_url menyebabkan SDK menguraikannya sebagai 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;
    }
};

Pengaturan lanjutan

Akselerasi unggah

Atur VODVideoMeta.userData ke JSON berikut. Server VOD secara otomatis mengembalikan titik akhir akselerasi transfer global OSS (oss-accelerate.aliyuncs.com) saat menerbitkan UploadAddress. SDK kemudian langsung mengunggah ke titik akhir percepatan tersebut:

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

Akselerasi unggah bergantung pada akselerasi transfer global OSS. Anda harus mengaktifkan akselerasi transfer untuk bucket di Konsol OSS. Untuk informasi lebih lanjut, lihat Akses OSS menggunakan akselerasi transfer.

Unggah dan transkoding

Tentukan kelompok template transkoding atau alur kerja menggunakan VODVideoMeta:

VODVideoMeta *meta = [[VODVideoMeta alloc] init];
meta.title = @"My Video";
meta.desc = @"Video description";                     // Catatan: gunakan desc, bukan description
meta.coverUrl = @"https://example.com/cover.jpg";
meta.cateId = @(1000);
meta.tags = @"tag1,tag2";
meta.storageLocation = @"<Opsional: wilayah penyimpanan kustom>";
meta.templateGroupId = @"<ID kelompok template Anda>";    // Kelompok template transkoding
meta.workflowId = @"<ID alur kerja Anda>";          // Alur kerja (opsional)
meta.appId = @"<Opsional: ID aplikasi>";

Bidang yang didukung oleh VODVideoMeta: title, desc, coverUrl, cateId, tags, userData, storageLocation, templateGroupId, workflowId, dan appId. Semua bidang bersifat opsional dan diteruskan ke CreateUploadVideo.

Setelah unggah selesai, server VOD melakukan transkoding video sumber berdasarkan kelompok template. Jika Anda tidak ingin memicu transkoding, teruskan kelompok template "tanpa transkoding" saat memanggil CreateUploadVideo dari backend Anda.

Timeout dan retry

VODUploadConfig *config = [[VODUploadConfig alloc] init];
config.getAuth = getAuth;
config.timeout = 60;            // Satuan: detik. Nilai default: 60
config.maxRetryCount = 2;       // Nilai default: 2

timeout mengontrol timeout koneksi dan baca/tulis (NSTimeInterval, dalam detik) untuk satu permintaan OSS. maxRetryCount mengontrol jumlah retry untuk permintaan OSS saat terjadi error jaringan.

Penting

Satuan timeout adalah milidetik di Android dan detik di iOS. Perhatikan perbedaan ini saat mengintegrasikan lintas platform.

Versi signature

config.signature = @"v4";        // Nilai default: @"v4". Nilai valid: @"v1"

Signature OSS V4 adalah versi yang direkomendasikan. Mulai 1 September 2025, signature V4 wajib digunakan untuk bucket yang baru dibuat. Pelanggan yang sudah ada juga disarankan untuk segera migrasi. Atur @"v1" secara eksplisit hanya jika bucket yang digunakan aplikasi Anda masih hanya mendukung signature V1.

Resumable upload

Resumable upload diaktifkan secara default. SDK menggunakan triplet (lastModified, fileName, fileSize) sebagai kunci resumable upload dan secara otomatis menyimpannya ke direktori Caches lokal:

SkenarioPerilaku SDK
[task cancel] dipanggil selama unggahCatatan resumable upload dipertahankan. Pemanggilan uploadFile: berikutnya dengan file yang sama secara otomatis melanjutkan unggah.
Aplikasi crash atau dihentikan di latar belakangCatatan resumable upload dipertahankan. Pemanggilan uploadFile: berikutnya setelah cold start dengan file yang sama secara otomatis melanjutkan unggah.
Adanya perubahan pada sidik jari fileFile dianggap sebagai file baru dan diunggah dari awal.
uploadId OSS kedaluwarsaSDK secara otomatis menghapus catatan lama dan memulai unggah baru melalui VODAuthKindCreateVideo.

Untuk menonaktifkan unggah yang dapat dilanjutkan:

config.checkpoint = NO;

Multipart upload

Gunakan partSize untuk mengontrol ukuran bagian dan parallel untuk mengontrol jumlah bagian konkuren:

// Konfigurasi global
config.partSize = 1024 * 1024;     // Nilai default: 1 MB
config.parallel = 4;               // Nilai default: 4

// Penggantian per-task
VODUploadOptions *options = [[VODUploadOptions alloc] init];
options.videoMeta = meta;
options.partSize = 2 * 1024 * 1024;
options.parallel = 6;

Atur wilayah layanan VOD

config.region = @"cn-shanghai";    // Nilai default: cn-shanghai

Untuk daftar wilayah yang didukung, lihat ID wilayah ApsaraVideo VOD.

Pelaporan data

SDK mengaktifkan pelacakan tautan unggah secara default untuk pemantauan kualitas produk. Hanya metrik waktu proses dari proses unggah yang dikumpulkan, dan konten file tidak termasuk. Untuk menonaktifkan pelaporan data:

config.reportEnabled = NO;       // Nilai default: YES

Penanganan error

VODUploadError mewarisi dari NSError. Kode error menggunakan format tiga segmen UPLOAD.{LAYER}.{TYPE}:

LAYERKode errorDeskripsi
AUTHUPLOAD.AUTH.GET_AUTH_FAILEDCallback getAuth gagal.
AUTHUPLOAD.AUTH.DECODE_FAILEDGagal mengurai UploadAuth.
AUTHUPLOAD.AUTH.EXPIREDKredensial telah kedaluwarsa.
OSSUPLOAD.OSS.ACCESS_DENIEDAkses OSS ditolak (masalah izin/signature).
OSSUPLOAD.OSS.NO_SUCH_BUCKETBucket tidak ada.
OSSUPLOAD.OSS.NO_SUCH_UPLOADuploadId telah kedaluwarsa. SDK secara otomatis fallback.
OSSUPLOAD.OSS.UPLOAD_FAILEDUnggah OSS gagal.
OSSUPLOAD.OSS.MERGE_FAILEDPenggabungan multipart OSS gagal.
NETWORKUPLOAD.NETWORK.TIMEOUTTimeout jaringan.
NETWORKUPLOAD.NETWORK.UNREACHABLEJaringan tidak dapat dijangkau.
FILEUPLOAD.FILE.NOT_FOUNDFile tidak ada.
FILEUPLOAD.FILE.EMPTYFile kosong.
CANCELUPLOAD.CANCEL.USER_CANCELLEDPengguna membatalkan unggah.
INTERNALUPLOAD.INTERNAL.DISPOSEDInstans telah dihapus.
INTERNALUPLOAD.INTERNAL.INVALID_CONFIGKonfigurasi tidak valid.

Properti publik:

  • NSString *errorCode — Kode error

  • NSString *errorMessage — Pesan error

  • NSError *cause — Exception OSS yang mendasari

  • NSString *uploadTaskId — ID task unggah

  • NSString *suggestion — Saran perbaikan bawaan dari SDK

if ([error.errorCode hasPrefix:@"UPLOAD.AUTH."]) {
    // Beri prompt kepada pengguna untuk memeriksa otorisasi backend
} else if ([error.errorCode isEqualToString:VODErrorCodeOssUploadFailed]) {
    // Ulangi atau beri prompt kepada pengguna untuk memeriksa jaringan
}
NSLog(@"%@ : %@ (cause=%@, suggestion=%@)",
      error.errorCode, error.errorMessage, error.cause, error.suggestion);

FAQ

Apakah saya dapat memulai beberapa pemanggilan uploadFile secara bersamaan?

Ya. Setiap task bersifat independen. Kendalikan jumlah unggah konkuren berdasarkan kondisi jaringan untuk menghindari tekanan bandwidth upstream berlebihan akibat kombinasi dengan parallel.

Resumable upload tidak berfungsi setelah pembatalan dan unggah ulang

Selesaikan masalah dengan langkah-langkah berikut:

  • Periksa apakah path file sama.

  • Periksa apakah lastModified atau ukuran file telah berubah.

  • Periksa apakah config.checkpoint diatur ke YES.

  • Periksa apakah uploadId telah kedaluwarsa. Saat respons NoSuchUpload diterima, SDK secara otomatis fallback ke unggah baru. Ini adalah perilaku yang diharapkan.

Tinjauan App Store Connect ditolak dengan "missing privacy manifest"

SDK menyertakan file PrivacyInfo.xcprivacy yang secara otomatis disuntikkan selama integrasi pod. Pastikan aplikasi Anda juga mendeklarasikan Required Reason API yang digunakan aplikasi Anda.

Callback tidak dipicu setelah membuat uploader

Pastikan bahwa uploader bukan variabel lokal. Instans VODUploadV2Client harus dipertahankan sebagai properti dari self. Jika tidak, ARC akan melepaskannya secara prematur.