Upload objects

Last Updated: Oct 13, 2017

Simple upload

You can directly upload OSSData by uploading objects, or upload an object through NSURL.

  1. OSSPutObjectRequest * put = [OSSPutObjectRequest new];
  2. // Mandatory field
  3. put.bucketName = @"<bucketName>";
  4. put.objectKey = @"<objectKey>";
  5. put.uploadingFileURL = [NSURL fileURLWithPath:@"<filepath>"];
  6. // put.uploadingData = <NSData *>; // Upload NSData directly
  7. // Optional fields, which can be left unspecified
  8. put.uploadProgress = ^(int64_t bytesSent, int64_t totalByteSent, int64_t totalBytesExpectedToSend) {
  9. // Length of bytes uploaded, total length of bytes uploaded, and total length of bytes expected to be uploaded
  10. NSLog(@"%lld, %lld, %lld", bytesSent, totalByteSent, totalBytesExpectedToSend);
  11. };
  12. // Reference for the meanings of the following optional fields: https://docs.aliyun.com/#/pub/oss/api-reference/object&PutObject
  13. // put.contentType = @"";
  14. // put.contentMd5 = @"";
  15. // put.contentEncoding = @"";
  16. // put.contentDisposition = @"";
  17. // put.objectMeta = [NSMutableDictionary dictionaryWithObjectsAndKeys:@"value1", @"x-oss-meta-name1", nil]; // You can set the metainformation or other HTTP header for the upload
  18. OSSTask * putTask = [client putObject:put];
  19. [putTask continueWithBlock:^id(OSSTask *task) {
  20. if (!task.error) {
  21. NSLog(@"upload object success!");
  22. } else {
  23. NSLog(@"upload object failed, error: %@" , task.error);
  24. }
  25. return nil;
  26. }];
  27. // [putTask waitUntilFinished];
  28. // [put cancel];

Upload a file to a directory

OSS does not use folders. All elements are stored as objects. But it offers a mode for you to create a simulated folder. The creation of a simulated folder is essentially the creation of an object ended with “/“ in its name. This object can be uploaded and downloaded as a normal object, but the OSS console will display any object whose name ends with a slash (/) as a folder.

For example, when you upload a file, if you write the ObjectKey as "folder/subfolder/file", you are simulating uploading the file to the file object under the folder/subfolder/ directory.

Note: The default path is the root directory and does not need to start with /.

Set Content-Type and enable MD5 check during the upload

You can explicitly set Content-Type during the upload process. Otherwise, the SDK will determine its value according to the object name or the uploaded ObjectKey. In addition, if you set Content-MD5 when uploading an object, OSS will use the parameter to check whether the message content it receives is consistent with the sent content. The SDK provides methods to conveniently calculate the Base64 and MD5 values.

  1. OSSPutObjectRequest * put = [OSSPutObjectRequest new];
  2. // Mandatory field
  3. put.bucketName = @"<bucketName>";
  4. put.objectKey = @"<objectKey>";
  5. put.uploadingFileURL = [NSURL fileURLWithPath:@"<filepath>"];
  6. // put.uploadingData = <NSData *>; // Directly upload NSData
  7. // Set Content-Type (optional)
  8. put.contentType = @"application/octet-stream";
  9. // Configure MD5 check (optional)
  10. put.contentMd5 = [OSSUtil base64Md5ForFilePath:@"<filePath>"]; // If it is an object path
  11. // put.contentMd5 = [OSSUtil base64Md5ForData:<NSData *>]; // If it is binary data
  12. // Upload progress settings (optional)
  13. put.uploadProgress = ^(int64_t bytesSent, int64_t totalByteSent, int64_t totalBytesExpectedToSend) {
  14. // Length of bytes uploaded, total length of bytes uploaded, and total length of bytes expected to be uploaded
  15. NSLog(@"%lld, %lld, %lld", bytesSent, totalByteSent, totalBytesExpectedToSend);
  16. };
  17. OSSTask * putTask = [client putObject:put];
  18. [putTask continueWithBlock:^id(OSSTask *task) {
  19. if (!task.error) {
  20. NSLog(@"upload object success!");
  21. } else {
  22. NSLog(@"upload object failed, error: %@" , task.error);
  23. }
  24. return nil;
  25. }];
  26. // [putTask waitUntilFinished];
  27. // [put cancel];

Append upload

Append Object is used to upload files in the appending mode. The type of the objects created with the Append Object operation is Appendable Object, and the type of the objects uploaded with the Put Object operation is Normal Object.

  1. OSSAppendObjectRequest * append = [OSSAppendObjectRequest new];
  2. // Mandatory field
  3. append.bucketName = @"<bucketName>";
  4. append.objectKey = @"<objectKey>";
  5. append.appendPosition = 0; // Specify the append position
  6. NSString * docDir = [self getDocumentDirectory];
  7. append.uploadingFileURL = [NSURL fileURLWithPath:@"<filepath>"];
  8. // Optional field
  9. append.uploadProgress = ^(int64_t bytesSent, int64_t totalByteSent, int64_t totalBytesExpectedToSend) {
  10. NSLog(@"%lld, %lld, %lld", bytesSent, totalByteSent, totalBytesExpectedToSend);
  11. };
  12. // For the meanings of the following optional fields, go to https://docs.aliyun.com/#/pub/oss/api-reference/object&AppendObject
  13. // append.contentType = @"";
  14. // append.contentMd5 = @"";
  15. // append.contentEncoding = @"";
  16. // append.contentDisposition = @"";
  17. OSSTask * appendTask = [client appendObject:append];
  18. [appendTask continueWithBlock:^id(OSSTask *task) {
  19. NSLog(@"objectKey: %@", append.objectKey);
  20. if (!task.error) {
  21. NSLog(@"append object success!");
  22. OSSAppendObjectResult * result = task.result;
  23. NSString * etag = result.eTag;
  24. long nextPosition = result.xOssNextAppendPosition;
  25. } else {
  26. NSLog(@"append object failed, error: %@" , task.error);
  27. }
  28. return nil;
  29. }];

Callback notification after upload

When you upload an object on the client, you can configure the OSS server to notify your business server of completed processing of upload requests. After the server receives the callback, it will return the callback result to the client. Compared with simple upload, upload with callback notifications requires the client to wait a longer time for processing the callback request and response.

For details, refer to Callback.

Example code:

  1. OSSPutObjectRequest * request = [OSSPutObjectRequest new];
  2. request.bucketName = @"<bucketName>";
  3. request.objectKey = @"<objectKey>";
  4. request.uploadingFileURL = [NSURL fileURLWithPath:@<filepath>"];
  5. // Set callback parameters
  6. request.callbackParam = @{
  7. @"callbackUrl": @"<your server callback address>",
  8. @"callbackBody": @"<your callback body>"
  9. };
  10. // Set custom variables
  11. request.callbackVar = @{
  12. @"<var1>": @"<value1>",
  13. @"<var2>": @"<value2>"
  14. };
  15. request.uploadProgress = ^(int64_t bytesSent, int64_t totalByteSent, int64_t totalBytesExpectedToSend) {
  16. NSLog(@"%lld, %lld, %lld", bytesSent, totalByteSent, totalBytesExpectedToSend);
  17. };
  18. OSSTask * task = [client putObject:request];
  19. [task continueWithBlock:^id(OSSTask *task) {
  20. if (task.error) {
  21. OSSLogError(@"%@", task.error);
  22. } else {
  23. OSSPutObjectResult * result = task.result;
  24. NSLog(@"Result - requestId: %@, headerFields: %@, servercallback: %@",
  25. result.requestId,
  26. result.httpResponseHeaderFields,
  27. result.serverReturnJsonString);
  28. }
  29. return nil;
  30. }];

Resumable upload

In a wireless network connection, it usually takes a relatively long time to upload a large object. The upload may fail due to poor network connectivity or network switching. In this case, the entire file needs to be uploaded all over again. To address this problem, the SDK provides the resumable upload feature.

Resumable upload depends on the multipart upload interfaces of OSS. It will not save any information to the local device. Before you upload a large file, obtain an UploadID through the InitMultipartUpload interface, and use the UploadID to call the resumable upload interface to upload the file. If the upload process is interrupted due to an exception, use the same UploadID to call the resumable upload interface. Then the upload task will be automatically resumed from the previously failed part.

The UploadID will become invalid once the upload is successful. If you use the same UploadID to upload another file, the system will return the NSError, with Domain being OSSClientErrorDomain and Code being OSSClientErrorCodeCannotResumeUpload. In this case, you need to obtain a new UploadID to upload the file.

This requires you to save and manage the UploadID corresponding to your file. For details about how to obtain an UploadID, refer to the Multipart Upload section.

When a resumable upload task fails and is not resumed for a long time, the uploaded parts may become useless fragments on the OSS. Under such circumstances, you can set the lifecycle rule for the bucket to clear fragments in a timely manner. Refer to Lifecycle Management.

Resumable upload depends on InitMultipartUpload/UploadPart/ListParts/CompleteMultipartUpload/AbortMultipartUpload. If you use the STS authentication mode, add the permissions required to use the APIs.

Resumable upload supports post-upload callback notifications in the same usage as the above general upload callback notifications.

Note: Resumable upload is not recommended for uploading small and medium-sized files from a mobile terminal. Resumable upload adopts the multipart upload method which initiates multiple network requests for uploading a single file, reducing the upload efficiency.

  1. __block NSString * uploadId = nil;
  2. OSSInitMultipartUploadRequest * init = [OSSInitMultipartUploadRequest new];
  3. init.bucketName = <bucketName>;
  4. init.objectKey = <objectKey>;
  5. // For the meanings of the following optional fields, go to https://docs.aliyun.com/#/pub/oss/api-reference/multipart-upload&InitiateMultipartUpload
  6. // append.contentType = @"";
  7. // append.contentMd5 = @"";
  8. // append.contentEncoding = @"";
  9. // append.contentDisposition = @"";
  10. // init.objectMeta = [NSMutableDictionary dictionaryWithObjectsAndKeys:@"value1", @"x-oss-meta-name1", nil];
  11. // Obtain the UploadID used to identify the entire upload event
  12. OSSTask * task = [client multipartUploadInit:init];
  13. [[task continueWithBlock:^id(OSSTask *task) {
  14. if (!task.error) {
  15. OSSInitMultipartUploadResult * result = task.result;
  16. uploadId = result.uploadId;
  17. } else {
  18. NSLog(@"init uploadid failed, error: %@", task.error);
  19. }
  20. return nil;
  21. }] waitUntilFinished];
  22. // Upload the file using the obtained UploadID. If the upload task fails and resumable upload is feasible, you can use the same UploadID to upload the same file to the same storage object on OSS
  23. OSSResumableUploadRequest * resumableUpload = [OSSResumableUploadRequest new];
  24. resumableUpload.bucketName = <bucketName>;
  25. resumableUpload.objectKey = <objectKey>;
  26. resumableUpload.uploadId = uploadId;
  27. resumableUpload.partSize = 1024 * 1024;
  28. resumableUpload.uploadProgress = ^(int64_t bytesSent, int64_t totalByteSent, int64_t totalBytesExpectedToSend) {
  29. NSLog(@"%lld, %lld, %lld", bytesSent, totalByteSent, totalBytesExpectedToSend);
  30. };
  31. resumableUpload.uploadingFileURL = [NSURL fileURLWithPath:<your file path>];
  32. OSSTask * resumeTask = [client resumableUpload:resumableUpload];
  33. [resumeTask continueWithBlock:^id(OSSTask *task) {
  34. if (task.error) {
  35. NSLog(@"error: %@", task.error);
  36. if ([task.error.domain isEqualToString:OSSClientErrorDomain] && task.error.code == OSSClientErrorCodeCannotResumeUpload) {
  37. // If resumable upload is infeasible, you need to obtain a new UploadID to upload the file all over again
  38. }
  39. } else {
  40. NSLog(@"Upload file success");
  41. }
  42. return nil;
  43. }];
  44. // [resumeTask waitUntilFinished];
  45. // [resumableUpload cancel];
Thank you! We've received your feedback.