标准接口

标准接口由三个接口组合完成分片上传文件的功能,createMultipartUpload,uploadPart,completeMultipartUpload,abortMultipartUpload。

创建分片上传任务

创建分片上传任务,返回分片上传任务的ID。

接口定义:

- (AWSTask<AWSS3CreateMultipartUploadOutput *> *)createMultipartUpload:(AWSS3CreateMultipartUploadRequest *)request
  
- (void)createMultipartUpload:(AWSS3CreateMultipartUploadRequest *)request
     completionHandler:(void (^)(AWSS3CreateMultipartUploadOutput *response, NSError *error))completionHandler

参数:

参数名 类型 说明
bucket NSString bucket名
key NSString 要上传的对象名
ACL AWSS3ObjectCannedACL 权限设置

代码示例:

AWSS3CreateMultipartUploadRequest *createReq = [AWSS3CreateMultipartUploadRequest new];
createReq.key = self.fileName;
createReq.bucket = self.bucketName;
__weak CTYunStorageTask *weakSelf = self;

[self.requestArray addObject:createReq];

[[[AWSS3 defaultS3] createMultipartUpload:createReq] continueWithBlock:^id _Nullable(AWSTask<AWSS3CreateMultipartUploadOutput *> * _Nonnull t)
{
	dispatch_sync(weakSelf.queue, ^{
		LOGI(@"createMultipartUpload success");
		AWSS3CreateMultipartUploadOutput *outPut = t.result;
		weakSelf.uploadId = outPut.uploadId;
		[weakSelf.userDefault setObject:weakSelf.uploadId forKey:@"uploadId"];
		[weakSelf uploadPartData:progressBlock success:completion failure:failure];
	});
	
	return nil;
}];

上传一个分片

获取到分片任务ID之后,通过ID来上传分片内容到S3服务器。

接口定义:

- (AWSTask<AWSS3UploadPartOutput *> *)uploadPart:(AWSS3UploadPartRequest *)request
  
- (void)uploadPart:(AWSS3UploadPartRequest *)request
     completionHandler:(void (^)(AWSS3UploadPartOutput *response, NSError *error))completionHandler

参数:

参数名 类型 说明
bucket NSString bucket名
key NSString 要上传的对象名称
body id 上传的文件内容(NSData)
uploadId NSString 上传任务ID
contentLength NSNumber 上传内容长度
partNumber NSNumber 分片ID(1-10000)
uploadProgress AWSNetworkingUploadProgressBlock 上传进度回调接口

代码示例:

AWSS3UploadPartRequest *uploadPartRequest = [AWSS3UploadPartRequest new];
uploadPartRequest.key = self.fileName;
uploadPartRequest.partNumber = @(i);
uploadPartRequest.body = partData;
uploadPartRequest.contentLength = @(dataLength);
uploadPartRequest.uploadId = self.uploadId;
uploadPartRequest.bucket = self.bucketName;
uploadPartRequest.uploadProgress = ^(int64_t bytesSent, int64_t totalBytesSent, int64_t totalBytesExpectedToSend){
	dispatch_async(dispatch_get_main_queue(), ^{
		weakSelf.uploadByteSent += bytesSent;
		int64_t fileSize = [self.fileData length];
		if (weakSelf.uploadByteSent < fileSize){
			weakSelf.progress = weakSelf.uploadByteSent/(fileSize*1.0);
			progressBlock(weakSelf.progress);
		}
	});
};
[self.requestArray addObject:uploadPartRequest];

[[[AWSS3 defaultS3] uploadPart:uploadPartRequest] continueWithBlock:^id _Nullable(AWSTask<AWSS3UploadPartOutput *> * _Nonnull t)
{
	LOGI(@"uploadPartData finished");
	if (t.error){
		weakSelf.isError = YES;
	} else {
		AWSS3UploadPartOutput *outputPart = t.result;
		if (outputPart){
			AWSS3CompletedPart *partObj = [AWSS3CompletedPart new];
			partObj.partNumber = @(i);
			partObj.ETag = outputPart.ETag;
			NSDictionary *cacheDic = @{@"part":@(i), @"ETag":outputPart.ETag, @"size":@(dataLength)};
			[weakSelf.partETags setObject:cacheDic forKey:[NSString stringWithFormat:@"%d", i]];
			[weakSelf.mutArray addObject:partObj];
			[weakSelf.userDefault setObject:weakSelf.partETags forKey:@"partArray"];
			[weakSelf.userDefault synchronize];
		} else {
			LOGI(@"uploadPartData error, outputPart=nil");
		}
	}
	dispatch_group_leave(group);
	return nil;
}];

完成分片上传任务

完成所有分片的上传之后,调用完成接口,服务端会把所有分片合并成对象保存。

接口定义:

- (AWSTask<AWSS3CompleteMultipartUploadOutput *> *)completeMultipartUpload:(AWSS3CompleteMultipartUploadRequest *)request
  
- (void)completeMultipartUpload:(AWSS3CompleteMultipartUploadRequest *)request
     completionHandler:(void (^)(AWSS3CompleteMultipartUploadOutput *response, NSError *error))completionHandler

参数:

参数名 类型 说明
bucket NSString bucket名
key NSString 要上传的对象名
uploadId NSString 上传任务ID
multipartUpload AWSS3CompletedMultipartUpload 上传的分片信息列表

代码示例:

- (void)uploadComplete:(void (^)(float progress))progressBlock
               success:(void (^)(void))completion
               failure:(void (^)(NSError *))failure
{
    LOGI(@"uploadComplete send request");
    AWSS3 *transferManager = [AWSS3 defaultS3];
    AWSS3CompleteMultipartUploadRequest *completeUpload = [AWSS3CompleteMultipartUploadRequest new];
    completeUpload.key = self.fileName;
    completeUpload.uploadId = self.uploadId;
    completeUpload.bucket = self.bucketName;
    completeUpload.multipartUpload = [AWSS3CompletedMultipartUpload new];
    completeUpload.multipartUpload.parts = [NSArray arrayWithArray:self.mutArray] ;
    [self.requestArray addObject:completeUpload];
    
    [[transferManager completeMultipartUpload:completeUpload] continueWithBlock:^id _Nullable(AWSTask<AWSS3CompleteMultipartUploadOutput *> * _Nonnull t) {
        LOGI(@"uploadComplete recv response");
        if (t.error) {
            failure(t.error);
        } else {
            LOGI(@"uploadComplete success!");
            self.progress = 1;
            progressBlock(self.progress);
            completion();
        }
        return nil;
    }];
}

终止分片上传任务

上传失败的时候调用此接口,服务器会清除残留的分片数据。

接口定义:

- (AWSTask<AWSS3AbortMultipartUploadOutput *> *)abortMultipartUpload:(AWSS3AbortMultipartUploadRequest *)request;

- (void)abortMultipartUpload:(AWSS3AbortMultipartUploadRequest *)request completionHandler:(void (^ _Nullable)(AWSS3AbortMultipartUploadOutput * _Nullable response, NSError * _Nullable error))completionHandler;

参数:

参数名 类型 说明
bucket NSString bucket名
key NSString 要上传的对象名
uploadId NSString 上传任务ID

代码示例:

- (void) abortMultipartUpload:(NSString*) bucketName key:(NSString*)keyName uploadId:(NSString*)uploadId {
    AWSS3AbortMultipartUploadRequest *request = [[AWSS3AbortMultipartUploadRequest alloc] init];
    request.bucket = bucketName;
    request.key = keyName;
    request.uploadId = uploadId;
    [self.s3 abortMultipartUpload:request completionHandler:^(AWSS3AbortMultipartUploadOutput * _Nullable response, NSError * _Nullable error) {
        if (error != nil) {
            NSLog(@"error: %@", error);
            return;
        }
        NSLog(@"success");
    }];
}