在無線網絡下,上傳比較大的文件持續時間長,可能會遇到因為網絡條件差、用戶切換網絡等原因導致上傳中途失敗,整個文件需要重新上傳。為此,iOS SDK提供了斷點續傳上傳功能。
背景信息
對于移動端而言,如果不是大文件(例如小于5 GB的文件),不建議使用斷點續傳的方式上傳。斷點續傳上傳是通過分片上傳實現的,上傳單個文件需要進行多次網絡請求,效率不高。對于通過斷點續傳的方式上傳大于5 GB的文件時:
斷點續傳上傳前
通過斷點續傳上傳的方式將文件上傳到OSS前,您可以指定斷點記錄的保存文件夾。斷點續傳上傳僅在本次上傳生效。
如果未指定斷點記錄的保存文件夾,假設某個分片因為網絡原因等導致文件上傳失敗時,將耗用大量的重試時間及流量來重新上傳整個大文件。
如果指定了斷點記錄的保存文件夾,在文件上傳失敗時,將從斷點記錄處繼續上傳未上傳完成的部分。
斷點續傳上傳時
斷點續傳上傳僅支持上傳本地文件。斷點續傳上傳支持上傳回調,使用方法與常見的上傳回調類似。具體操作,請參見Callback。
斷點續傳上傳依賴InitMultipartUpload、UploadPart、ListParts、CompleteMultipartUpload、AbortMultipartUpload等接口來實現。如果您需要通過STS鑒權模式來使用斷點續傳上傳,則需要保證您擁有訪問以上API接口的權限。
斷點續傳上傳默認已開啟每個分片上傳時的MD5校驗,因此無需在請求中設置
Content-Md5
頭部。如果同一任務一直得不到續傳,可能會在OSS上積累無用碎片。此時,您可以為Bucket設置lifeCycle規則的方式來定時清理碎片,詳情請參見生命周期管理。
重要出于碎片管理的原因,如果在斷點續傳時取消當前上傳任務,默認會同步清理已經上傳到服務器的分片。取消上傳任務時如果仍希望保留斷點上傳記錄,則需要指定斷點記錄的保存文件夾并修改deleteUploadIdOnCancelling參數。如果服務端保留記錄時間過長,且Bucket已設置lifeCycle規則定時清理了服務端分片,會出現服務端和移動端記錄不一致的問題。
注意事項
使用本文示例前您需要先通過自定義域名、STS等方式新建OSSClient,具體請參見初始化。
說明所創建存儲空間的所屬地域取決于初始化配置的endpoint地域信息。
要上傳文件,您必須有
oss:PutObject
權限。具體操作,請參見為RAM用戶授權自定義的權限策略。
示例代碼
斷點記錄在本地持久保存時,調用
resumableUpload
方法實現斷點續傳上傳的過程如下:OSSResumableUploadRequest * resumableUpload = [OSSResumableUploadRequest new]; resumableUpload.bucketName = OSS_BUCKET_PRIVATE; //... NSString *cachesDir = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject]; resumableUpload.recordDirectoryPath = cachesDir;
說明使用斷點續傳上傳文件失敗時會生成斷點記錄文件,然后從斷點記錄處繼續上傳直到上傳完成。上傳成功后會自動刪除斷點記錄文件,默認情況下不會在本地持久保存斷點記錄。
斷點續傳上傳的完整示例代碼如下:
// 獲取UploadId上傳文件。 OSSResumableUploadRequest * resumableUpload = [OSSResumableUploadRequest new]; resumableUpload.bucketName = <bucketName>; // objectKey等同于objectName,表示斷點上傳文件到OSS時需要指定包含文件后綴在內的完整路徑,例如abc/efg/123.jpg resumableUpload.objectKey = <objectKey>; resumableUpload.partSize = 1024 * 1024; resumableUpload.uploadProgress = ^(int64_t bytesSent, int64_t totalByteSent, int64_t totalBytesExpectedToSend) { NSLog(@"%lld, %lld, %lld", bytesSent, totalByteSent, totalBytesExpectedToSend); }; NSString *cachesDir = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject]; // 設置斷點記錄保存路徑。 resumableUpload.recordDirectoryPath = cachesDir; // 將參數deleteUploadIdOnCancelling設置為NO,表示不刪除斷點記錄文件,上傳失敗后將從斷點記錄處繼續上傳直到文件上傳完成。如果不設置此參數,即保留默認值YES,表示刪除斷點記錄文件,下次再上傳同一文件時則重新上傳。 resumableUpload.deleteUploadIdOnCancelling = NO; resumableUpload.uploadingFileURL = [NSURL fileURLWithPath:<your file path>]; OSSTask * resumeTask = [client resumableUpload:resumableUpload]; [resumeTask continueWithBlock:^id(OSSTask *task) { if (task.error) { NSLog(@"error: %@", task.error); if ([task.error.domain isEqualToString:OSSClientErrorDomain] && task.error.code == OSSClientErrorCodeCannotResumeUpload) { // 此任務無法續傳,需獲取新的uploadId重新上傳。 } } else { NSLog(@"Upload file success"); } return nil; }]; // [resumeTask waitUntilFinished]; // [resumableUpload cancel];