本文介紹如何使用iOS SDK將媒體檔案從本地上傳至點播儲存。
前提條件
專案 | 要求 |
最低 iOS 版本 | iOS 12.0 |
開發語言 | Objective-C(Swift 工程通過 Bridging Header 橋接) |
阿里雲帳號 | |
鑒權服務 | 已準備好可簽發上傳憑證(UploadAuth)的後端服務 |
整合SDK
整合方式
在 Podfile 中加入:
platform :ios, '12.0'
target 'YourApp' do
pod 'VODUpload', '~> 2.0'
end執行:
pod repo update
pod installSDK 會自動拉取底層 AliyunOSSiOS 依賴。
專案配置
podspec 已聲明以下系統庫,使用 CocoaPods 整合時自動連結:
SystemConfiguration.framework
MobileCoreServices.framework
CoreMedia.framework
AVFoundation.framework
CoreTelephony.framework
libresolv.tbdSDK 內建 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 使用 property 直接設定,調用 +uploaderWithConfig: Factory 方法建立執行個體:
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 = @"我的視訊";
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 = @"封面";
VODUploadOptions *opts = [[VODUploadOptions alloc] init];
opts.imageMeta = imgMeta;
[uploader uploadFile:imagePath options:opts callback:cb];VODVideoMeta 的描述欄位為 desc(非 description,避免與 Objective-C 保留方法衝突)。
回調處理
v2 通過統一的 VODGetAuthCallback block 向業務方索取上傳憑證。SDK 在以下時機調用 getAuth,並通過 VODAuthContext.kind告知所需憑證類型:
Kind | 觸發時機 | 業務方應調用的 OpenAPI |
| 首次上傳一個視頻檔案 | |
| 續傳 / 憑證重新整理 | |
| 上傳圖片 |
業務方只需把後端 OpenAPI 返回的原始 JSON 原樣傳入 completion。SDK 按 OpenAPI 原始欄位名(大小寫敏感)讀取以下鍵:
Kind | 必須包含的欄位 |
|
|
|
|
欄位名大小寫敏感,請直接轉寄 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,VOD 服務端在簽發 UploadAddress 時會自動返回 OSS 全球傳輸加速節點(oss-accelerate.aliyuncs.com),SDK 直傳到加速節點完成上傳:
VODVideoMeta *meta = [[VODVideoMeta alloc] init];
meta.title = @"我的視訊";
meta.userData = @"{\"Type\":\"oss\",\"Domain\":\"oss-accelerate.aliyuncs.com\"}";上傳加速能力依賴 OSS 全球傳輸加速,需在 OSS 控制台對 Bucket 開啟傳輸加速。詳情請參見通過傳輸加速訪問OSS 。
上傳轉碼
通過 VODVideoMeta 指定轉碼模板組或工作流程:
VODVideoMeta *meta = [[VODVideoMeta alloc] init];
meta.title = @"我的視訊";
meta.desc = @"視頻描述"; // 注意:是 desc,不是 description
meta.coverUrl = @"https://example.com/cover.jpg";
meta.cateId = @(1000);
meta.tags = @"tag1,tag2";
meta.storageLocation = @"<可選:自訂儲存地區>";
meta.templateGroupId = @"<你的模板組 ID>"; // 轉碼模板組
meta.workflowId = @"<你的工作流程 ID>"; // 工作流程(可選)
meta.appId = @"<可選:應用 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 請求在網路異常時的重試次數。
Android timeout 單位是毫秒,iOS 單位是秒,跨端整合時注意區分。
簽名版本
1config.signature = @"v4"; // 預設 @"v4",可選 @"v1"OSS V4 簽名是當前推薦版本,自 2025-09-01 起建立 Bucket 強制使用 V4 簽名,存量客戶也建議儘快遷移。僅當業務方依賴的 Bucket 仍只支援 V1 簽名時才需顯式設定 @"v1"。
斷點續傳
預設開啟。SDK 使用 (lastModified, fileName, fileSize) 三元組作為續傳 key,自動持久化到本地 Caches 目錄:
情境 | SDK 行為 |
上傳途中調用 | 保留續傳記錄,下次同檔案 |
App 崩潰 / 後台被殺 | 保留續傳記錄,下次冷啟同檔案 |
檔案指紋任一變化 | 視為新檔案,全新上傳 |
OSS uploadId 到期 | SDK 自動清除舊記錄,重新走 |
如需關閉:
config.checkpoint = NO;分區上傳
通過 partSize 控制分區大小、parallel 控制並發分區數:
// 全域配置
config.partSize = 1024 * 1024; // 預設 1MB
config.parallel = 4; // 預設 4
// 單次任務覆蓋
VODUploadOptions *options = [[VODUploadOptions alloc] init];
options.videoMeta = meta;
options.partSize = 2 * 1024 * 1024;
options.parallel = 6;設定點播服務地區
1config.region = @"cn-shanghai"; // 預設 cn-shanghai支援的 region 列表見 點播地區標識。
資料上報
SDK 預設開啟上傳鏈路埋點用於產品品質監控,僅採集上傳過程的運行指標,不包含檔案內容。如需關閉:
config.reportEnabled = NO; // 預設 YES錯誤處理
VODUploadError 繼承自 NSError,錯誤碼採用 UPLOAD.{LAYER}.{TYPE} 三段式:
LAYER | 錯誤碼 | 含義 |
AUTH |
| getAuth 回調失敗 |
AUTH |
| UploadAuth 解碼失敗 |
AUTH |
| 憑證到期 |
OSS |
| OSS 拒絕訪問(許可權/簽名) |
OSS |
| Bucket 不存在 |
OSS |
| uploadId 到期(SDK 自動 fallback) |
OSS |
| OSS 上傳失敗 |
OSS |
| OSS 分區合并失敗 |
NETWORK |
| 網路逾時 |
NETWORK |
| 網路不可達 |
FILE |
| 檔案不存在 |
FILE |
| 檔案為空白 |
CANCEL |
| 使用者取消 |
INTERNAL |
| 執行個體已 dispose |
INTERNAL |
| 配置非法 |
公開屬性:
NSString *errorCode— 錯誤碼NSString *errorMessage— 錯誤資訊NSError *cause— 底層 OSS 異常NSString *uploadTaskId— 上傳任務 IDNSString *suggestion— SDK 內建的修複建議
if ([error.errorCode hasPrefix:@"UPLOAD.AUTH."]) {
// 提醒使用者檢查後端鑒權
} else if ([error.errorCode isEqualToString:VODErrorCodeOssUploadFailed]) {
// 重試或提示使用者檢查網路
}
NSLog(@"%@ : %@ (cause=%@, suggestion=%@)",
error.errorCode, error.errorMessage, error.cause, error.suggestion);常見問題
能否同時發起多個 uploadFile
可以,每個 task 獨立。建議根據網路情況控制並發數,避免與 parallel 疊加放大上行頻寬壓力。
取消後再次 uploadFile 沒有續傳
請按以下步驟排查:
確認是否同一檔案路徑;
確認檔案 lastModified / size 是否變化;
確認
config.checkpoint是否為YES;確認uploadId 是否到期(響應
NoSuchUpload時 SDK 自動 fallback 全新上傳,屬預期行為)。
App Store Connect 審核被拒,提示 Missing Privacy Manifest
SDK 已內建 PrivacyInfo.xcprivacy 並隨 Pod 自動注入。同時 App 自身也需聲明所使用的 Required Reason API。
uploader 建立後回調不觸發
確認 uploader 不是局部變數。VODUploadV2Client 執行個體需要作為 self 的屬性持有,否則會被 ARC 提前釋放。