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:
Aplikasi Anda memanggil SDK untuk memulai unggah. SDK memicu callback
getAuth.Dalam callback tersebut, aplikasi Anda meminta kredensial unggah dari layanan backend Anda, yang memanggil operasi VOD OpenAPI (seperti
CreateUploadVideo) dan mengembalikan responsnya.Aplikasi Anda meneruskan respons OpenAPI ke SDK. SDK mengekstrak
UploadAuthdanUploadAddressdari respons tersebut dan mengunggah file langsung ke OSS.Jika kredensial kedaluwarsa selama unggah file besar, SDK memicu kembali callback
getAuthdengan jenis refresh untuk memperoleh kredensial baru.
Prasyarat
| Item | Persyaratan |
| Versi iOS minimum | iOS 12.0 |
| Bahasa pengembangan | Objective-C (proyek Swift menggunakan Bridging Header untuk bridging) |
| Akun Alibaba Cloud | ApsaraVideo VOD telah diaktifkan |
| Layanan otorisasi | Layanan 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'
endJalankan perintah berikut:
pod repo update
pod installSDK 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.tbdSDK 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];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:
| Jenis | Pemicu | OpenAPI yang dipanggil |
| VODAuthKindCreateVideo | Unggah pertama kali file video | CreateUploadVideo |
| VODAuthKindRefreshVideo | Resumable upload / refresh kredensial | RefreshUploadVideo |
| VODAuthKindCreateImage | Unggah gambar | CreateUploadImage |
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):
| Jenis | Bidang wajib |
| VODAuthKindCreateVideo / VODAuthKindRefreshVideo | UploadAuth, UploadAddress, VideoId |
| VODAuthKindCreateImage | UploadAuth, 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: 2timeout mengontrol timeout koneksi dan baca/tulis (NSTimeInterval, dalam detik) untuk satu permintaan OSS. maxRetryCount mengontrol jumlah retry untuk permintaan OSS saat terjadi error jaringan.
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:
| Skenario | Perilaku SDK |
[task cancel] dipanggil selama unggah | Catatan resumable upload dipertahankan. Pemanggilan uploadFile: berikutnya dengan file yang sama secara otomatis melanjutkan unggah. |
| Aplikasi crash atau dihentikan di latar belakang | Catatan resumable upload dipertahankan. Pemanggilan uploadFile: berikutnya setelah cold start dengan file yang sama secara otomatis melanjutkan unggah. |
| Adanya perubahan pada sidik jari file | File dianggap sebagai file baru dan diunggah dari awal. |
| uploadId OSS kedaluwarsa | SDK 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-shanghaiUntuk 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: YESPenanganan error
VODUploadError mewarisi dari NSError. Kode error menggunakan format tiga segmen UPLOAD.{LAYER}.{TYPE}:
| LAYER | Kode error | Deskripsi |
| AUTH | UPLOAD.AUTH.GET_AUTH_FAILED | Callback getAuth gagal. |
| AUTH | UPLOAD.AUTH.DECODE_FAILED | Gagal mengurai UploadAuth. |
| AUTH | UPLOAD.AUTH.EXPIRED | Kredensial telah kedaluwarsa. |
| OSS | UPLOAD.OSS.ACCESS_DENIED | Akses OSS ditolak (masalah izin/signature). |
| OSS | UPLOAD.OSS.NO_SUCH_BUCKET | Bucket tidak ada. |
| OSS | UPLOAD.OSS.NO_SUCH_UPLOAD | uploadId telah kedaluwarsa. SDK secara otomatis fallback. |
| OSS | UPLOAD.OSS.UPLOAD_FAILED | Unggah OSS gagal. |
| OSS | UPLOAD.OSS.MERGE_FAILED | Penggabungan multipart OSS gagal. |
| NETWORK | UPLOAD.NETWORK.TIMEOUT | Timeout jaringan. |
| NETWORK | UPLOAD.NETWORK.UNREACHABLE | Jaringan tidak dapat dijangkau. |
| FILE | UPLOAD.FILE.NOT_FOUND | File tidak ada. |
| FILE | UPLOAD.FILE.EMPTY | File kosong. |
| CANCEL | UPLOAD.CANCEL.USER_CANCELLED | Pengguna membatalkan unggah. |
| INTERNAL | UPLOAD.INTERNAL.DISPOSED | Instans telah dihapus. |
| INTERNAL | UPLOAD.INTERNAL.INVALID_CONFIG | Konfigurasi tidak valid. |
Properti publik:
NSString *errorCode— Kode errorNSString *errorMessage— Pesan errorNSError *cause— Exception OSS yang mendasariNSString *uploadTaskId— ID task unggahNSString *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.checkpointdiatur keYES.Periksa apakah uploadId telah kedaluwarsa. Saat respons
NoSuchUploadditerima, 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.