QNPartsUploadPerformerV1.m 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. //
  2. // QNPartsUploadApiV1.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 "QNUploadInfoV1.h"
  12. #import "QNPartsUploadPerformerV1.h"
  13. @interface QNPartsUploadPerformerV1()
  14. @end
  15. @implementation QNPartsUploadPerformerV1
  16. + (long long)blockSize{
  17. return 4 * 1024 * 1024;
  18. }
  19. - (QNUploadInfo *)getFileInfoWithDictionary:(NSDictionary *)fileInfoDictionary {
  20. return [QNUploadInfoV1 info:self.uploadSource dictionary:fileInfoDictionary];
  21. }
  22. - (QNUploadInfo *)getDefaultUploadInfo {
  23. return [QNUploadInfoV1 info:self.uploadSource configuration:self.config];
  24. }
  25. - (void)serverInit:(void(^)(QNResponseInfo * _Nullable responseInfo,
  26. QNUploadRegionRequestMetrics * _Nullable metrics,
  27. NSDictionary * _Nullable response))completeHandler {
  28. QNResponseInfo *responseInfo = [QNResponseInfo successResponse];
  29. completeHandler(responseInfo, nil, nil);
  30. }
  31. - (void)uploadNextData:(void(^)(BOOL stop,
  32. QNResponseInfo * _Nullable responseInfo,
  33. QNUploadRegionRequestMetrics * _Nullable metrics,
  34. NSDictionary * _Nullable response))completeHandler {
  35. QNUploadInfoV1 *uploadInfo = (QNUploadInfoV1 *)self.uploadInfo;
  36. NSError *error;
  37. QNUploadBlock *block = nil;
  38. QNUploadData *chunk = nil;
  39. @synchronized (self) {
  40. block = [uploadInfo nextUploadBlock:&error];
  41. chunk = [uploadInfo nextUploadData:block];
  42. chunk.state = QNUploadStateUploading;
  43. }
  44. if (error) {
  45. QNResponseInfo *responseInfo = [QNResponseInfo responseInfoWithLocalIOError:[NSString stringWithFormat:@"%@", error]];
  46. completeHandler(YES, responseInfo, nil, nil);
  47. return;
  48. }
  49. if (block == nil || chunk == nil) {
  50. QNLogInfo(@"key:%@ no chunk left", self.key);
  51. QNResponseInfo *responseInfo = nil;
  52. if (uploadInfo.getSourceSize == 0) {
  53. responseInfo = [QNResponseInfo responseInfoOfZeroData:@"file is empty"];
  54. } else {
  55. responseInfo = [QNResponseInfo responseInfoWithSDKInteriorError:@"no chunk left"];
  56. }
  57. completeHandler(YES, responseInfo, nil, nil);
  58. return;
  59. }
  60. if (chunk.data == nil) {
  61. QNLogInfo(@"key:%@ chunk data is nil", self.key);
  62. QNResponseInfo *responseInfo = [QNResponseInfo responseInfoOfZeroData:@"chunk data is nil"];;
  63. completeHandler(YES, responseInfo, nil, nil);
  64. return;
  65. }
  66. kQNWeakSelf;
  67. void (^progress)(long long, long long) = ^(long long totalBytesWritten, long long totalBytesExpectedToWrite){
  68. kQNStrongSelf;
  69. chunk.uploadSize = totalBytesWritten;
  70. [self notifyProgress:false];
  71. };
  72. void (^completeHandlerP)(QNResponseInfo *, QNUploadRegionRequestMetrics *, NSDictionary *) = ^(QNResponseInfo * _Nullable responseInfo, QNUploadRegionRequestMetrics * _Nullable metrics, NSDictionary * _Nullable response) {
  73. kQNStrongSelf;
  74. NSString *blockContext = response[@"ctx"];
  75. NSNumber *expiredAt = response[@"expired_at"];
  76. if (responseInfo.isOK && blockContext && expiredAt) {
  77. block.context = blockContext;
  78. block.expiredAt = expiredAt;
  79. chunk.state = QNUploadStateComplete;
  80. [self recordUploadInfo];
  81. [self notifyProgress:false];
  82. } else {
  83. chunk.state = QNUploadStateWaitToUpload;
  84. }
  85. completeHandler(NO, responseInfo, metrics, response);
  86. };
  87. if ([uploadInfo isFirstData:chunk]) {
  88. QNLogInfo(@"key:%@ makeBlock", self.key);
  89. [self makeBlock:block firstChunk:chunk chunkData:chunk.data progress:progress completeHandler:completeHandlerP];
  90. } else {
  91. QNLogInfo(@"key:%@ uploadChunk", self.key);
  92. [self uploadChunk:block chunk:chunk chunkData:chunk.data progress:progress completeHandler:completeHandlerP];
  93. }
  94. }
  95. - (void)completeUpload:(void(^)(QNResponseInfo * _Nullable responseInfo,
  96. QNUploadRegionRequestMetrics * _Nullable metrics,
  97. NSDictionary * _Nullable response))completeHandler {
  98. QNUploadInfoV1 *uploadInfo = (QNUploadInfoV1 *)self.uploadInfo;
  99. QNRequestTransaction *transaction = [self createUploadRequestTransaction];
  100. kQNWeakSelf;
  101. kQNWeakObj(transaction);
  102. [transaction makeFile:[uploadInfo getSourceSize]
  103. fileName:self.fileName
  104. blockContexts:[uploadInfo allBlocksContexts]
  105. complete:^(QNResponseInfo * _Nullable responseInfo, QNUploadRegionRequestMetrics * _Nullable metrics, NSDictionary * _Nullable response) {
  106. kQNStrongSelf;
  107. kQNStrongObj(transaction);
  108. if (responseInfo.isOK) {
  109. [self notifyProgress:true];
  110. }
  111. completeHandler(responseInfo, metrics, response);
  112. [self destroyUploadRequestTransaction:transaction];
  113. }];
  114. }
  115. - (void)makeBlock:(QNUploadBlock *)block
  116. firstChunk:(QNUploadData *)chunk
  117. chunkData:(NSData *)chunkData
  118. progress:(void(^)(long long totalBytesWritten,
  119. long long totalBytesExpectedToWrite))progress
  120. completeHandler:(void(^)(QNResponseInfo * _Nullable responseInfo,
  121. QNUploadRegionRequestMetrics * _Nullable metrics,
  122. NSDictionary * _Nullable response))completeHandler {
  123. QNRequestTransaction *transaction = [self createUploadRequestTransaction];
  124. kQNWeakSelf;
  125. kQNWeakObj(transaction);
  126. [transaction makeBlock:block.offset
  127. blockSize:block.size
  128. firstChunkData:chunkData
  129. progress:progress
  130. complete:^(QNResponseInfo * _Nullable responseInfo, QNUploadRegionRequestMetrics * _Nullable metrics, NSDictionary * _Nullable response) {
  131. kQNStrongSelf;
  132. kQNStrongObj(transaction);
  133. completeHandler(responseInfo, metrics, response);
  134. [self destroyUploadRequestTransaction:transaction];
  135. }];
  136. }
  137. - (void)uploadChunk:(QNUploadBlock *)block
  138. chunk:(QNUploadData *)chunk
  139. chunkData:(NSData *)chunkData
  140. progress:(void(^)(long long totalBytesWritten,
  141. long long totalBytesExpectedToWrite))progress
  142. completeHandler:(void(^)(QNResponseInfo * _Nullable responseInfo,
  143. QNUploadRegionRequestMetrics * _Nullable metrics,
  144. NSDictionary * _Nullable response))completeHandler {
  145. QNRequestTransaction *transaction = [self createUploadRequestTransaction];
  146. kQNWeakSelf;
  147. kQNWeakObj(transaction);
  148. [transaction uploadChunk:block.context
  149. blockOffset:block.offset
  150. chunkData:chunkData
  151. chunkOffset:chunk.offset
  152. progress:progress
  153. complete:^(QNResponseInfo * _Nullable responseInfo, QNUploadRegionRequestMetrics * _Nullable metrics, NSDictionary * _Nullable response) {
  154. kQNStrongSelf;
  155. kQNStrongObj(transaction);
  156. completeHandler(responseInfo, metrics, response);
  157. [self destroyUploadRequestTransaction:transaction];
  158. }];
  159. }
  160. @end