Resumable upload lets you recover a failed large-file upload from where it stopped, so you don't have to restart from the beginning after a network interruption.
Prerequisites
Before you begin, ensure that you have:
An initialized
OSSClient. For instructions, see Initialization (iOS SDK).The
oss:PutObjectpermission. For details, see Grant custom access policies to a RAM user.
The bucket region is determined by the endpoint you specified during initialization.
Usage notes
Resumable upload supports local files only.
For objects smaller than 5 GB uploaded from a mobile device, use simple upload instead. Resumable upload is built on multipart upload and requires multiple network requests, making it inefficient for smaller objects.
Each part's integrity is verified using MD5 by default. You don't need to set the
Content-MD5header.Resumable upload supports the upload callback feature, used the same way as in simple upload. For details, see Callback.
If you use Security Token Service (STS) for authentication, make sure you are authorized to call all five API operations listed below.
Incomplete multipart uploads accumulate in OSS if upload tasks are abandoned. Set lifecycle rules on the bucket to periodically clean them up. For details, see Lifecycle management.
How it works
Resumable upload is built on OSS multipart upload. The iOS SDK calls the following API operations internally:
| API operation | Description |
|---|---|
InitMultipartUpload | Initializes the multipart upload and returns an upload ID |
UploadPart | Uploads individual parts |
ListParts | Lists uploaded parts |
CompleteMultipartUpload | Combines all parts into the final object |
AbortMultipartUpload | Cancels the upload and removes uploaded parts |
When you specify a directory for the checkpoint file, the SDK saves upload progress locally. If the upload fails, the next call to resumableUpload reads the checkpoint file and resumes from the last successful part rather than restarting.
Upload an object with resumable upload
The following example uploads a local file using OSSResumableUploadRequest. It saves the checkpoint file to the system caches directory so the upload can resume after a failure.
// Initialize the request
OSSResumableUploadRequest *resumableUpload = [OSSResumableUploadRequest new];
resumableUpload.bucketName = <bucketName>;
// objectKey is the full path of the object in OSS, including the file extension.
// Example: images/photos/2024/photo.jpg
resumableUpload.objectKey = <objectKey>;
// Set the part size (1 MB by default)
resumableUpload.partSize = 1024 * 1024;
// Save checkpoint files to the system caches directory.
// If the upload fails, the next call resumes from the last checkpoint.
NSString *cachesDir = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject];
resumableUpload.recordDirectoryPath = cachesDir;
// Set deleteUploadIdOnCancelling to NO so the checkpoint file is kept when
// the upload is cancelled. This allows the upload to resume later.
// The default is YES, which deletes the checkpoint file on cancellation.
resumableUpload.deleteUploadIdOnCancelling = NO;
// Track upload progress
resumableUpload.uploadProgress = ^(int64_t bytesSent, int64_t totalByteSent, int64_t totalBytesExpectedToSend) {
NSLog(@"Sent: %lld Total sent: %lld Expected: %lld", bytesSent, totalByteSent, totalBytesExpectedToSend);
};
resumableUpload.uploadingFileURL = [NSURL fileURLWithPath:<your-file-path>];
OSSTask *resumeTask = [client resumableUpload:resumableUpload];
[resumeTask continueWithBlock:^id(OSSTask *task) {
if (task.error) {
NSLog(@"Upload failed: %@", task.error);
if ([task.error.domain isEqualToString:OSSClientErrorDomain] &&
task.error.code == OSSClientErrorCodeCannotResumeUpload) {
// The upload cannot be resumed. Start a new upload with a fresh request.
}
} else {
NSLog(@"Upload succeeded.");
}
return nil;
}];
// Uncomment to wait synchronously:
// [resumeTask waitUntilFinished];Replace the following placeholders:
| Placeholder | Description |
|---|---|
<bucketName> | The name of your OSS bucket |
<objectKey> | The full path of the object in OSS, for example, videos/upload/sample.mp4 |
<your-file-path> | The absolute path of the local file, for example, /var/mobile/Documents/sample.mp4 |
After a successful upload, the checkpoint file is deleted automatically. If you don't set recordDirectoryPath, checkpoint records are not saved and the entire upload restarts on failure.Cancel and resume an upload
Cancel an upload
Call cancel on the upload task to stop it.
[resumableUpload cancel];By default (deleteUploadIdOnCancelling = YES), the checkpoint file is deleted when an upload is cancelled. The next upload of the same object starts from the beginning.
To keep the checkpoint file so the upload can resume later, set deleteUploadIdOnCancelling = NO before starting the upload (shown in the example above).
When you cancel an upload with deleteUploadIdOnCancelling = YES, the parts already uploaded to OSS are deleted. To keep those parts and resume the upload later, set deleteUploadIdOnCancelling = NO and specify recordDirectoryPath. If a lifecycle rule deletes the parts from OSS before you resume, the checkpoint file on the device becomes invalid.
Resume a cancelled upload
To resume an upload that was cancelled with deleteUploadIdOnCancelling = NO, create a new OSSResumableUploadRequest with the same bucketName, objectKey, and recordDirectoryPath. The SDK reads the existing checkpoint file and resumes from the last successful part.
OSSResumableUploadRequest *resumableUpload = [OSSResumableUploadRequest new];
resumableUpload.bucketName = <bucketName>;
resumableUpload.objectKey = <objectKey>;
resumableUpload.partSize = 1024 * 1024;
NSString *cachesDir = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) firstObject];
resumableUpload.recordDirectoryPath = cachesDir; // Must match the original path
resumableUpload.deleteUploadIdOnCancelling = NO;
resumableUpload.uploadingFileURL = [NSURL fileURLWithPath:<your-file-path>];
OSSTask *resumeTask = [client resumableUpload:resumableUpload];
[resumeTask continueWithBlock:^id(OSSTask *task) {
if (task.error) {
NSLog(@"Resume failed: %@", task.error);
} else {
NSLog(@"Upload succeeded.");
}
return nil;
}];What's next
Callback — Use upload callback to receive notifications after an upload completes.
Lifecycle management — Set lifecycle rules to automatically clean up incomplete multipart uploads.