All Products
Search
Document Center

Object Storage Service:Resumable upload (iOS SDK)

Last Updated:Nov 29, 2025

Uploading large files over a wireless network can take a long time. Poor network conditions or network changes can cause the upload to fail. If an upload fails, the entire file must be re-uploaded. To address this, the iOS software development kit (SDK) provides a resumable upload feature.

Background information

We recommend that you do not use resumable upload when you upload objects that are smaller than 5 GB in size from a mobile device. Resumable upload is implemented by using the multipart upload feature. Resumable upload of a single object requires multiple network requests, which is inefficient. When you upload an object that is larger than 5 GB in size by performing resumable upload, take note of the following items:

  • Before resumable upload

    Before you upload an object to OSS by performing resumable upload, you can specify a directory for the checkpoint file that stores the resumable upload progress. The checkpoint file applies only to the current resumable upload task.

    • If you do not specify the directory for the checkpoint file and a part of a large object fails to be uploaded due to network issues, a long period of time is required and a large amount of traffic is consumed to re-upload the entire object.

    • If you specify the directory for the checkpoint file, a failed resumable upload task can be resumed from the position recorded in the checkpoint file.

  • During a resumable upload

    • Resumable upload allows you to upload only local files. Resumable upload supports the upload callback feature, which is used in the same manner as in common upload tasks. For more information, see Callback.

    • You can perform resumable upload by calling the following API operations: InitMultipartUpload, UploadPart, ListParts, CompleteMultipartUpload, and AbortMultipartUpload. If you want to perform resumable upload by using Security Token Service (STS), make sure that you are authorized to call the preceding API operations.

    • By default, the MD5 hash of each part is verified in a resumable upload task. Therefore, you do not need to specify the Content-Md5 header in the request.

    • If a task cannot be resumed for a long time, incomplete multipart uploads may accumulate in OSS. You can set lifecycle rules for the bucket to periodically delete these parts. For more information, see Lifecycle management.

      Important

      If you cancel a resumable upload task, the parts that are already uploaded to the server are deleted by default. To keep the breakpoint records when you cancel a task, you must specify a folder for the records and modify the deleteUploadIdOnCancelling parameter. If the server retains the records for an extended period and a lifecycle rule deletes the parts from the server, the records on the server and the mobile client may become inconsistent.

Usage notes

  • Before you use the examples in this topic, you must create an OSSClient using a custom domain name or Security Token Service (STS). For more information, see Initialization (iOS SDK).

    Note

    The region of the bucket is determined by the endpoint specified in the initialization configuration.

  • To upload a file, you must have the oss:PutObject permission. For more information, see Grant custom access policies to a RAM user.

Sample code

  • To save breakpoint records locally, you can call the resumableUpload method to perform a resumable upload as follows:

    OSSResumableUploadRequest * resumableUpload = [OSSResumableUploadRequest new];
    resumableUpload.bucketName = OSS_BUCKET_PRIVATE;
    //...
    NSString *cachesDir = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject];
    resumableUpload.recordDirectoryPath = cachesDir;
                        
    Note

    If a resumable upload fails, a breakpoint record file is created. The upload then resumes from the breakpoint until it is complete. After the upload is successful, the breakpoint record file is automatically deleted. By default, breakpoint records are not saved locally.

  • The following code provides a complete example of a resumable upload:

    // Obtain the UploadId to upload the file.
    OSSResumableUploadRequest * resumableUpload = [OSSResumableUploadRequest new];
    resumableUpload.bucketName = <bucketName>;
    // objectKey is the same as objectName. It specifies the full path of the object that you want to upload to OSS, including the file extension. For example, 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];
    // Set the path to save the breakpoint record.
    resumableUpload.recordDirectoryPath = cachesDir;
    // Set the deleteUploadIdOnCancelling parameter to NO. This indicates that the breakpoint record file is not deleted. If the upload fails, the upload resumes from the breakpoint until the file is completely uploaded. If you do not set this parameter, the default value YES is used. This indicates that the breakpoint record file is deleted. The next time you upload the same file, the upload starts from the beginning.
    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) {
                // This task cannot be resumed. You must obtain a new uploadId to re-upload the file.
            }
        } else {
            NSLog(@"Upload file success");
        }
        return nil;
    }];
    
    // [resumeTask waitUntilFinished];
    
    // [resumableUpload cancel];