189 lines
7.2 KiB
Objective-C
189 lines
7.2 KiB
Objective-C
//
|
|
// QNPartsUploadApiV1.m
|
|
// QiniuSDK
|
|
//
|
|
// Created by yangsen on 2020/11/30.
|
|
// Copyright © 2020 Qiniu. All rights reserved.
|
|
//
|
|
|
|
#import "QNLogUtil.h"
|
|
#import "QNDefine.h"
|
|
#import "QNRequestTransaction.h"
|
|
#import "QNUploadInfoV1.h"
|
|
#import "QNPartsUploadPerformerV1.h"
|
|
|
|
@interface QNPartsUploadPerformerV1()
|
|
@end
|
|
@implementation QNPartsUploadPerformerV1
|
|
+ (long long)blockSize{
|
|
return 4 * 1024 * 1024;
|
|
}
|
|
|
|
- (QNUploadInfo *)getFileInfoWithDictionary:(NSDictionary *)fileInfoDictionary {
|
|
return [QNUploadInfoV1 info:self.uploadSource dictionary:fileInfoDictionary];
|
|
}
|
|
|
|
- (QNUploadInfo *)getDefaultUploadInfo {
|
|
return [QNUploadInfoV1 info:self.uploadSource configuration:self.config];
|
|
}
|
|
|
|
- (void)serverInit:(void(^)(QNResponseInfo * _Nullable responseInfo,
|
|
QNUploadRegionRequestMetrics * _Nullable metrics,
|
|
NSDictionary * _Nullable response))completeHandler {
|
|
QNResponseInfo *responseInfo = [QNResponseInfo successResponse];
|
|
completeHandler(responseInfo, nil, nil);
|
|
}
|
|
|
|
- (void)uploadNextData:(void(^)(BOOL stop,
|
|
QNResponseInfo * _Nullable responseInfo,
|
|
QNUploadRegionRequestMetrics * _Nullable metrics,
|
|
NSDictionary * _Nullable response))completeHandler {
|
|
QNUploadInfoV1 *uploadInfo = (QNUploadInfoV1 *)self.uploadInfo;
|
|
|
|
NSError *error;
|
|
QNUploadBlock *block = nil;
|
|
QNUploadData *chunk = nil;
|
|
@synchronized (self) {
|
|
block = [uploadInfo nextUploadBlock:&error];
|
|
chunk = [uploadInfo nextUploadData:block];
|
|
chunk.state = QNUploadStateUploading;
|
|
}
|
|
|
|
if (error) {
|
|
QNResponseInfo *responseInfo = [QNResponseInfo responseInfoWithLocalIOError:[NSString stringWithFormat:@"%@", error]];
|
|
completeHandler(YES, responseInfo, nil, nil);
|
|
return;
|
|
}
|
|
|
|
if (block == nil || chunk == nil) {
|
|
QNLogInfo(@"key:%@ no chunk left", self.key);
|
|
|
|
QNResponseInfo *responseInfo = nil;
|
|
if (uploadInfo.getSourceSize == 0) {
|
|
responseInfo = [QNResponseInfo responseInfoOfZeroData:@"file is empty"];
|
|
} else {
|
|
responseInfo = [QNResponseInfo responseInfoWithSDKInteriorError:@"no chunk left"];
|
|
}
|
|
completeHandler(YES, responseInfo, nil, nil);
|
|
return;
|
|
}
|
|
|
|
if (chunk.data == nil) {
|
|
QNLogInfo(@"key:%@ chunk data is nil", self.key);
|
|
|
|
QNResponseInfo *responseInfo = [QNResponseInfo responseInfoOfZeroData:@"chunk data is nil"];;
|
|
completeHandler(YES, responseInfo, nil, nil);
|
|
return;
|
|
}
|
|
|
|
kQNWeakSelf;
|
|
void (^progress)(long long, long long) = ^(long long totalBytesWritten, long long totalBytesExpectedToWrite){
|
|
kQNStrongSelf;
|
|
chunk.uploadSize = totalBytesWritten;
|
|
[self notifyProgress:false];
|
|
};
|
|
|
|
void (^completeHandlerP)(QNResponseInfo *, QNUploadRegionRequestMetrics *, NSDictionary *) = ^(QNResponseInfo * _Nullable responseInfo, QNUploadRegionRequestMetrics * _Nullable metrics, NSDictionary * _Nullable response) {
|
|
kQNStrongSelf;
|
|
|
|
NSString *blockContext = response[@"ctx"];
|
|
NSNumber *expiredAt = response[@"expired_at"];
|
|
if (responseInfo.isOK && blockContext && expiredAt) {
|
|
block.context = blockContext;
|
|
block.expiredAt = expiredAt;
|
|
chunk.state = QNUploadStateComplete;
|
|
[self recordUploadInfo];
|
|
[self notifyProgress:false];
|
|
} else {
|
|
chunk.state = QNUploadStateWaitToUpload;
|
|
}
|
|
completeHandler(NO, responseInfo, metrics, response);
|
|
};
|
|
|
|
if ([uploadInfo isFirstData:chunk]) {
|
|
QNLogInfo(@"key:%@ makeBlock", self.key);
|
|
[self makeBlock:block firstChunk:chunk chunkData:chunk.data progress:progress completeHandler:completeHandlerP];
|
|
} else {
|
|
QNLogInfo(@"key:%@ uploadChunk", self.key);
|
|
[self uploadChunk:block chunk:chunk chunkData:chunk.data progress:progress completeHandler:completeHandlerP];
|
|
}
|
|
}
|
|
|
|
- (void)completeUpload:(void(^)(QNResponseInfo * _Nullable responseInfo,
|
|
QNUploadRegionRequestMetrics * _Nullable metrics,
|
|
NSDictionary * _Nullable response))completeHandler {
|
|
QNUploadInfoV1 *uploadInfo = (QNUploadInfoV1 *)self.uploadInfo;
|
|
|
|
QNRequestTransaction *transaction = [self createUploadRequestTransaction];
|
|
|
|
kQNWeakSelf;
|
|
kQNWeakObj(transaction);
|
|
[transaction makeFile:[uploadInfo getSourceSize]
|
|
fileName:self.fileName
|
|
blockContexts:[uploadInfo allBlocksContexts]
|
|
complete:^(QNResponseInfo * _Nullable responseInfo, QNUploadRegionRequestMetrics * _Nullable metrics, NSDictionary * _Nullable response) {
|
|
kQNStrongSelf;
|
|
kQNStrongObj(transaction);
|
|
if (responseInfo.isOK) {
|
|
[self notifyProgress:true];
|
|
}
|
|
completeHandler(responseInfo, metrics, response);
|
|
[self destroyUploadRequestTransaction:transaction];
|
|
}];
|
|
}
|
|
|
|
|
|
- (void)makeBlock:(QNUploadBlock *)block
|
|
firstChunk:(QNUploadData *)chunk
|
|
chunkData:(NSData *)chunkData
|
|
progress:(void(^)(long long totalBytesWritten,
|
|
long long totalBytesExpectedToWrite))progress
|
|
completeHandler:(void(^)(QNResponseInfo * _Nullable responseInfo,
|
|
QNUploadRegionRequestMetrics * _Nullable metrics,
|
|
NSDictionary * _Nullable response))completeHandler {
|
|
|
|
QNRequestTransaction *transaction = [self createUploadRequestTransaction];
|
|
kQNWeakSelf;
|
|
kQNWeakObj(transaction);
|
|
[transaction makeBlock:block.offset
|
|
blockSize:block.size
|
|
firstChunkData:chunkData
|
|
progress:progress
|
|
complete:^(QNResponseInfo * _Nullable responseInfo, QNUploadRegionRequestMetrics * _Nullable metrics, NSDictionary * _Nullable response) {
|
|
kQNStrongSelf;
|
|
kQNStrongObj(transaction);
|
|
|
|
completeHandler(responseInfo, metrics, response);
|
|
[self destroyUploadRequestTransaction:transaction];
|
|
}];
|
|
}
|
|
|
|
|
|
- (void)uploadChunk:(QNUploadBlock *)block
|
|
chunk:(QNUploadData *)chunk
|
|
chunkData:(NSData *)chunkData
|
|
progress:(void(^)(long long totalBytesWritten,
|
|
long long totalBytesExpectedToWrite))progress
|
|
completeHandler:(void(^)(QNResponseInfo * _Nullable responseInfo,
|
|
QNUploadRegionRequestMetrics * _Nullable metrics,
|
|
NSDictionary * _Nullable response))completeHandler {
|
|
|
|
QNRequestTransaction *transaction = [self createUploadRequestTransaction];
|
|
kQNWeakSelf;
|
|
kQNWeakObj(transaction);
|
|
[transaction uploadChunk:block.context
|
|
blockOffset:block.offset
|
|
chunkData:chunkData
|
|
chunkOffset:chunk.offset
|
|
progress:progress
|
|
complete:^(QNResponseInfo * _Nullable responseInfo, QNUploadRegionRequestMetrics * _Nullable metrics, NSDictionary * _Nullable response) {
|
|
kQNStrongSelf;
|
|
kQNStrongObj(transaction);
|
|
|
|
completeHandler(responseInfo, metrics, response);
|
|
[self destroyUploadRequestTransaction:transaction];
|
|
}];
|
|
}
|
|
|
|
@end
|