QNPartsUploadPerformerV2.m 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. //
  2. // QNPartsUploadApiV2.m
  3. // QiniuSDK
  4. //
  5. // Created by yangsen on 2020/11/30.
  6. // Copyright © 2020 Qiniu. All rights reserved.
  7. //
  8. #import "QNLogUtil.h"
  9. #import "QNDefine.h"
  10. #import "QNRequestTransaction.h"
  11. #import "QNUploadFileInfoPartV2.h"
  12. #import "QNPartsUploadPerformerV2.h"
  13. @interface QNPartsUploadPerformerV2()
  14. @end
  15. @implementation QNPartsUploadPerformerV2
  16. - (QNUploadFileInfo *)getFileInfoWithDictionary:(NSDictionary *)fileInfoDictionary {
  17. return [QNUploadFileInfoPartV2 infoFromDictionary:fileInfoDictionary];
  18. }
  19. - (QNUploadFileInfo *)getDefaultUploadFileInfo {
  20. return [[QNUploadFileInfoPartV2 alloc] initWithFileSize:[self.file size]
  21. dataSize:self.config.chunkSize
  22. modifyTime:(NSInteger)[self.file modifyTime]];
  23. }
  24. - (void)serverInit:(void(^)(QNResponseInfo * _Nullable responseInfo,
  25. QNUploadRegionRequestMetrics * _Nullable metrics,
  26. NSDictionary * _Nullable response))completeHandler {
  27. QNUploadFileInfoPartV2 *fileInfo = (QNUploadFileInfoPartV2 *)self.fileInfo;
  28. if (fileInfo && [fileInfo isValid]) {
  29. QNLogInfo(@"key:%@ serverInit success", self.key);
  30. QNResponseInfo *responseInfo = [QNResponseInfo successResponse];
  31. completeHandler(responseInfo, nil, nil);
  32. return;
  33. }
  34. QNRequestTransaction *transaction = [self createUploadRequestTransaction];
  35. kQNWeakSelf;
  36. kQNWeakObj(transaction);
  37. [transaction initPart:^(QNResponseInfo * _Nullable responseInfo, QNUploadRegionRequestMetrics * _Nullable metrics, NSDictionary * _Nullable response) {
  38. kQNStrongSelf;
  39. kQNStrongObj(transaction);
  40. NSString *uploadId = response[@"uploadId"];
  41. NSNumber *expireAt = response[@"expireAt"];
  42. if (responseInfo.isOK && uploadId && expireAt) {
  43. fileInfo.uploadId = uploadId;
  44. fileInfo.expireAt = expireAt;
  45. [self recordUploadInfo];
  46. }
  47. completeHandler(responseInfo, metrics, response);
  48. [self destroyUploadRequestTransaction:transaction];
  49. }];
  50. }
  51. - (void)uploadNextData:(void(^)(BOOL stop,
  52. QNResponseInfo * _Nullable responseInfo,
  53. QNUploadRegionRequestMetrics * _Nullable metrics,
  54. NSDictionary * _Nullable response))completeHandler {
  55. QNUploadFileInfoPartV2 *fileInfo = (QNUploadFileInfoPartV2 *)self.fileInfo;
  56. QNUploadData *data = nil;
  57. @synchronized (self) {
  58. data = [fileInfo nextUploadData];
  59. data.isUploading = YES;
  60. data.isCompleted = NO;
  61. }
  62. // 上传完毕
  63. if (data == nil) {
  64. QNLogInfo(@"key:%@ no data left", self.key);
  65. QNResponseInfo *responseInfo = [QNResponseInfo responseInfoWithSDKInteriorError:@"no data left"];
  66. completeHandler(YES, responseInfo, nil, nil);
  67. return;
  68. }
  69. // 本地读异常
  70. NSData *uploadData = [self getUploadData:data];
  71. if (uploadData == nil) {
  72. QNLogInfo(@"key:%@ get data error", self.key);
  73. data.isUploading = NO;
  74. data.isCompleted = NO;
  75. QNResponseInfo *responseInfo = [QNResponseInfo responseInfoWithLocalIOError:@"get data error"];
  76. completeHandler(YES, responseInfo, nil, responseInfo.responseDictionary);
  77. return;
  78. }
  79. kQNWeakSelf;
  80. void (^progress)(long long, long long) = ^(long long totalBytesWritten, long long totalBytesExpectedToWrite){
  81. kQNStrongSelf;
  82. data.progress = (float)totalBytesWritten / (float)totalBytesExpectedToWrite;
  83. [self notifyProgress];
  84. };
  85. QNRequestTransaction *transaction = [self createUploadRequestTransaction];
  86. kQNWeakObj(transaction);
  87. [transaction uploadPart:fileInfo.uploadId
  88. partIndex:data.index
  89. partData:uploadData
  90. progress:progress
  91. complete:^(QNResponseInfo * _Nullable responseInfo, QNUploadRegionRequestMetrics * _Nullable metrics, NSDictionary * _Nullable response) {
  92. kQNStrongSelf;
  93. kQNStrongObj(transaction);
  94. NSString *etag = response[@"etag"];
  95. NSString *md5 = response[@"md5"];
  96. if (responseInfo.isOK && etag && md5) {
  97. data.etag = etag;
  98. data.progress = 1;
  99. data.isUploading = NO;
  100. data.isCompleted = YES;
  101. [self recordUploadInfo];
  102. [self notifyProgress];
  103. } else {
  104. data.isUploading = NO;
  105. data.isCompleted = NO;
  106. }
  107. completeHandler(NO, responseInfo, metrics, response);
  108. [self destroyUploadRequestTransaction:transaction];
  109. }];
  110. }
  111. - (void)completeUpload:(void(^)(QNResponseInfo * _Nullable responseInfo,
  112. QNUploadRegionRequestMetrics * _Nullable metrics,
  113. NSDictionary * _Nullable response))completeHandler {
  114. QNUploadFileInfoPartV2 *fileInfo = (QNUploadFileInfoPartV2 *)self.fileInfo;
  115. NSArray *partInfoArray = [(QNUploadFileInfoPartV2 *)self.fileInfo getPartInfoArray];
  116. QNRequestTransaction *transaction = [self createUploadRequestTransaction];
  117. kQNWeakSelf;
  118. kQNWeakObj(transaction);
  119. [transaction completeParts:self.fileName uploadId:fileInfo.uploadId partInfoArray:partInfoArray complete:^(QNResponseInfo * _Nullable responseInfo, QNUploadRegionRequestMetrics * _Nullable metrics, NSDictionary * _Nullable response) {
  120. kQNStrongSelf;
  121. kQNStrongObj(transaction);
  122. completeHandler(responseInfo, metrics, response);
  123. [self destroyUploadRequestTransaction:transaction];
  124. }];
  125. }
  126. - (NSData *)getUploadData:(QNUploadData *)data{
  127. if (!self.file) {
  128. return nil;
  129. }
  130. NSError *error = nil;
  131. NSData *dataByte = [self.file read:(long)data.offset
  132. size:(long)data.size
  133. error:&error];
  134. return error ? nil : dataByte;
  135. }
  136. @end