All Products
Search
Document Center

Object Storage Service:Prevent overwriting objects that have the same name (iOS SDK)

Last Updated:Mar 20, 2026

By default, if you upload an object whose key matches an existing object you have access to, OSS overwrites the existing object. Set the x-oss-forbid-overwrite request header to true to block overwrites during simple upload, copy object, and multipart upload operations.

Prerequisites

Before you begin, ensure that you have:

  • An OSSClient instance initialized using a custom domain name, Security Token Service (STS), or another method. See Initialization (iOS SDK)

How x-oss-forbid-overwrite works

All three examples in this topic set x-oss-forbid-overwrite in a metadata dictionary. The following table summarizes how each value affects the operation:

ValueBehavior
Not setOverwrites an existing object with the same key (default)
falseOverwrites an existing object with the same key
trueFails with an error if an object with the same key already exists

Simple upload

The following example prevents an object from being overwritten during a simple upload:

OSSPutObjectRequest *put = [OSSPutObjectRequest new];

// Specify the bucket name. Example: examplebucket.
put.bucketName = @"examplebucket";
// Specify the full object key, excluding the bucket name. Example: exampledir/exampleobject.txt.
put.objectKey = @"exampledir/exampleobject.txt";
// Specify the full path of the local file to upload.
put.uploadingFileURL = [NSURL fileURLWithPath:@"/storage/emulated/0/oss/examplefile.txt"];

// Fail the upload if an object with the same key already exists.
put.objectMeta = @{@"x-oss-forbid-overwrite": @"true"};

// Optional: track upload progress.
put.uploadProgress = ^(int64_t bytesSent, int64_t totalByteSent, int64_t totalBytesExpectedToSend) {
    NSLog(@"%lld, %lld, %lld", bytesSent, totalByteSent, totalBytesExpectedToSend);
};

OSSTask *putTask = [client putObject:put];
[putTask continueWithBlock:^id(OSSTask *task) {
    if (!task.error) {
        NSLog(@"upload object success!");
    } else {
        NSLog(@"upload object failed, error: %@", task.error);
    }
    return nil;
}];
// [putTask waitUntilFinished];

Copy an object

The following example prevents an object from being overwritten when copying an object:

OSSCopyObjectRequest *copy = [OSSCopyObjectRequest new];
// Specify the source bucket name.
copy.sourceBucketName = @"srcbucket";
// Specify the full key of the source object.
copy.sourceObjectKey = @"dir1/srcobject.txt";
// Specify the destination bucket name.
copy.bucketName = @"destbucket";
// Specify the full key of the destination object.
copy.objectKey = @"dir2/destobject.txt";

// Fail the copy if an object with the same key already exists in the destination bucket.
copy.objectMeta = @{@"x-oss-forbid-overwrite": @"true"};

OSSTask *task = [client copyObject:copy];
[task continueWithBlock:^id(OSSTask *task) {
    if (!task.error) {
        NSLog(@"copy object success!");
    } else {
        NSLog(@"copy object failed, error: %@", task.error);
    }
    return nil;
}];
// [putTask waitUntilFinished];

Multipart upload

For multipart upload, set x-oss-forbid-overwrite in both the initiation request (init.objectMeta) and the complete request (complete.completeMetaHeader).

The following example prevents an object from being overwritten during a multipart upload:

__block NSString *uploadId = nil;
__block NSMutableArray *partInfos = [NSMutableArray new];

// Specify the bucket name. Example: examplebucket.
NSString *uploadToBucket = @"examplebucket";
// Specify the full object key, excluding the bucket name. Example: exampledir/exampleobject.txt.
NSString *uploadObjectkey = @"exampledir/exampleobject.txt";

// Initiate the multipart upload.
OSSInitMultipartUploadRequest *init = [OSSInitMultipartUploadRequest new];
init.bucketName = uploadToBucket;
init.objectKey = uploadObjectkey;

// Fail the upload if an object with the same key already exists.
init.objectMeta = @{@"x-oss-forbid-overwrite": @"true"};

// The upload ID uniquely identifies this multipart upload task. Use it to upload parts, cancel, or query the task.
OSSTask *initTask = [client multipartUploadInit:init];
[initTask waitUntilFinished];
if (!initTask.error) {
    OSSInitMultipartUploadResult *result = initTask.result;
    uploadId = result.uploadId;
} else {
    NSLog(@"multipart upload failed, error: %@", initTask.error);
    return;
}

// Upload parts.
// Specify the full path of the local file to upload.
NSString *filePath = @"/storage/emulated/0/oss/examplefile.txt";
// Get the file size.
uint64_t fileSize = [[[NSFileManager defaultManager] attributesOfItemAtPath:filePath error:nil] fileSize];
// Part numbers start from 1 and range from 1 to 10,000.
int chuckCount = *;
// Part size ranges from 100 KB to 5 GB.
uint64_t offset = fileSize / chuckCount;

for (int i = 1; i <= chuckCount; i++) {
    OSSUploadPartRequest *uploadPart = [OSSUploadPartRequest new];
    uploadPart.bucketName = uploadToBucket;
    uploadPart.objectkey = uploadObjectkey;
    uploadPart.uploadId = uploadId;
    uploadPart.partNumber = i; // part number start from 1

    NSFileHandle *readHandle = [NSFileHandle fileHandleForReadingAtPath:filePath];
    [readHandle seekToFileOffset:offset * (i - 1)];

    NSData *data = [readHandle readDataOfLength:offset];
    uploadPart.uploadPartData = data;

    OSSTask *uploadPartTask = [client uploadPart:uploadPart];
    [uploadPartTask waitUntilFinished];

    if (!uploadPartTask.error) {
        OSSUploadPartResult *result = uploadPartTask.result;
        uint64_t fileSize = [[[NSFileManager defaultManager] attributesOfItemAtPath:uploadPart.uploadPartFileURL.absoluteString error:nil] fileSize];
        [partInfos addObject:[OSSPartInfo partInfoWithPartNum:i eTag:result.eTag size:fileSize]];
    } else {
        NSLog(@"upload part error: %@", uploadPartTask.error);
        return;
    }
}

// Complete the multipart upload.
OSSCompleteMultipartUploadRequest *complete = [OSSCompleteMultipartUploadRequest new];
complete.bucketName = uploadToBucket;
complete.objectKey = uploadObjectkey;
complete.uploadId = uploadId;
complete.partInfos = partInfos;

// Fail the upload if an object with the same key already exists.
complete.completeMetaHeader = @{@"x-oss-forbid-overwrite": @"true"};

OSSTask *completeTask = [client completeMultipartUpload:complete];
[[completeTask continueWithBlock:^id(OSSTask *task) {
    if (!task.error) {
        NSLog(@"multipart upload success!");
    } else {
        NSLog(@"multipart upload error: %@", task.error);
    }
    return nil;
}] waitUntilFinished];

What's next