Resumable upload is for large file transfers or unstable network conditions. TOS iOS SDK splits objects into multiple parts and saves them to the checkpoint. After a task is paused or interrupted, restarting the same request continues from completed parts without re-uploading the entire file.
- Have available Endpoint, Region, and Bucket.
- Ensure the upload source path, download destination folder, and checkpoint folder are all accessible.
- Example code uses Objective-C and can be placed in the project’s .m files.
Each transfer task must use a separate checkpoint path. The following example saves the checkpoint in the app's Application Support directory:
static NSString *TOSCheckpointPath(NSString *fileName) {
NSFileManager *fileManager = [NSFileManager defaultManager];
NSURL *baseURL = [[fileManager URLsForDirectory:NSApplicationSupportDirectory
inDomains:NSUserDomainMask] firstObject];
NSURL *directoryURL = [baseURL URLByAppendingPathComponent:@"TOSCheckpoints"
BOOL created = [fileManager createDirectoryAtURL:directoryURL
withIntermediateDirectories:YES
NSLog(@"Create checkpoint directory failed: %@", error);
return [[directoryURL URLByAppendingPathComponent:fileName] path];
Create an upload request that enables checkpoint. Initial and resumed uploads must use the same bucket, object, source file, chunk size, and checkpoint path.
static TOSUploadFileInputV2 *TOSCreateUploadInput(
NSString *checkpointPath,
TOSCancelHook *cancelHook) {
TOSUploadFileInputV2 *input = [TOSUploadFileInputV2 new];
input.tosBucket = bucket;
input.tosKey = objectKey;
input.tosFilePath = filePath;
input.tosPartSize = 20LL * 1024 * 1024;
input.tosEnableCheckpoint = YES;
input.tosCheckpointFile = checkpointPath;
input.tosMaxRetryCount = 3;
input.tosCancelHook = cancelHook;
input.tosDataTransferListener = ^(TOSDataTransferStatus *status) {
if (status.tosTotalBytes <= 0) {
status.tosConsumedBytes * 100.0 / status.tosTotalBytes;
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"Upload progress: %.2f%%", progress);
NSString *bucket = @"YOUR_BUCKET";
NSString *objectKey = @"example/large-file.bin";
NSString *sourceFilePath = @"YOUR_LOCAL_FILE_PATH";
NSString *uploadCheckpoint = TOSCheckpointPath(@"upload-large-file.json");
TOSCancelHook *uploadCancelHook = [TOSCancelHook new];
TOSUploadFileInputV2 *uploadInput =
TOSCreateUploadInput(bucket,
TOSTask *uploadTask = [client uploadFile:uploadInput];
[uploadTask continueWithBlock:^id(TOSTask *finishedTask) {
if (finishedTask.error) {
NSLog(@"Upload file failed: %@", finishedTask.error);
TOSUploadFileOutputV2 *output = finishedTask.result;
NSLog(@"Upload file succeeded, ETag: %@", output.tosETag);
Call the following interface to pause the upload task when the user triggers the pause operation:
[uploadCancelHook cancel:NO];
After waiting for the original task to complete the callback, recreate the request and TOSCancelHook, reusing the same checkpoint path:
TOSCancelHook *newUploadCancelHook = [TOSCancelHook new];
TOSUploadFileInputV2 *resumedUploadInput =
TOSCreateUploadInput(bucket,
TOSTask *resumedUploadTask = [client uploadFile:resumedUploadInput];
[resumedUploadTask continueWithBlock:^id(TOSTask *finishedTask) {
if (finishedTask.error) {
NSLog(@"Resume upload failed: %@", finishedTask.error);
NSLog(@"Resume upload succeeded");
After a successful upload, the SDK automatically deletes the checkpoint.
Calling TOSCancelHook immediately terminates the task and clears the resumable upload state. When calling the corresponding interface again after termination, the task restarts from the beginning.
Terminate the task through the TOSCancelHook in each request:
[uploadCancelHook cancel:YES];
Warning
Do not reuse the old TOSCancelHook after the task has succeeded or already terminated.