全部產品
Search
文件中心

Object Storage Service:iOS斷點續傳上傳

更新時間:Feb 28, 2024

在無線網路下,上傳比較大的檔案期間長,可能會遇到因為網路條件差、使用者切換網路等原因導致上傳中途失敗,整個檔案需要重新上傳。為此,iOS SDK提供了斷點續傳上傳功能。

背景資訊

對於移動端而言,如果不是大檔案(例如小於5 GB的檔案),不建議使用斷點續傳的方式上傳。斷點續傳上傳是通過分區上傳實現的,上傳單個檔案需要進行多次網路請求,效率不高。對於通過斷點續傳的方式上傳大於5 GB的檔案時:

  • 斷點續傳上傳前

    通過斷點續傳上傳的方式將檔案上傳到OSS前,您可以指定斷點記錄的儲存檔案夾。斷點續傳上傳僅在本次上傳生效。

    • 如果未指定斷點記錄的儲存檔案夾,假設某個分區因為網路原因等導致檔案上傳失敗時,將耗用大量的重試時間及流量來重新上傳整個大檔案。

    • 如果指定了斷點記錄的儲存檔案夾,在檔案上傳失敗時,將從斷點記錄處繼續上傳未上傳完成的部分。

  • 斷點續傳上傳時

    • 斷點續傳上傳僅支援上傳本地檔案。斷點續傳上傳支援上傳回調,使用方法與常見的上傳回調類似。具體操作,請參見Callback

    • 斷點續傳上傳依賴InitMultipartUploadUploadPartListPartsCompleteMultipartUploadAbortMultipartUpload等介面來實現。如果您需要通過STS鑒權模式來使用斷點續傳上傳,則需要保證您擁有訪問以上API介面的許可權。

    • 斷點續傳上傳預設已開啟每個分區上傳時的MD5校正,因此無需在請求中設定Content-Md5頭部。

    • 如果同一任務一直得不到續傳,可能會在OSS上積累無用片段。此時,您可以為Bucket設定lifeCycle規則的方式來定時清理片段,詳情請參見生命週期管理

      重要

      出於片段管理的原因,如果在斷點續傳時取消當前上傳任務,預設會同步清理已經上傳到伺服器的分區。取消上傳任務時如果仍希望保留斷點上傳記錄,則需要指定斷點記錄的儲存檔案夾並修改deleteUploadIdOnCancelling參數。如果服務端保留記錄時間過長,且Bucket已設定lifeCycle規則定時清理了服務端分區,會出現服務端和移動端記錄不一致的問題。

範例程式碼

  • 斷點記錄在本地持久儲存時,調用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];