Brak opisu

RNFetchBlobNetwork.m 4.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. //
  2. // RNFetchBlobNetwork.m
  3. // RNFetchBlob
  4. //
  5. // Created by wkh237 on 2016/6/6.
  6. // Copyright © 2016 wkh237. All rights reserved.
  7. //
  8. #import <Foundation/Foundation.h>
  9. #import "RNFetchBlobNetwork.h"
  10. #import "RNFetchBlob.h"
  11. #import "RNFetchBlobConst.h"
  12. #import "RNFetchBlobProgress.h"
  13. #if __has_include(<React/RCTAssert.h>)
  14. #import <React/RCTRootView.h>
  15. #import <React/RCTLog.h>
  16. #import <React/RCTEventDispatcher.h>
  17. #import <React/RCTBridge.h>
  18. #else
  19. #import "RCTRootView.h"
  20. #import "RCTLog.h"
  21. #import "RCTEventDispatcher.h"
  22. #import "RCTBridge.h"
  23. #endif
  24. ////////////////////////////////////////
  25. //
  26. // HTTP request handler
  27. //
  28. ////////////////////////////////////////
  29. NSMapTable * expirationTable;
  30. __attribute__((constructor))
  31. static void initialize_tables() {
  32. if (expirationTable == nil) {
  33. expirationTable = [[NSMapTable alloc] init];
  34. }
  35. }
  36. @implementation RNFetchBlobNetwork
  37. - (id)init {
  38. self = [super init];
  39. if (self) {
  40. self.requestsTable = [NSMapTable mapTableWithKeyOptions:NSMapTableStrongMemory valueOptions:NSMapTableWeakMemory];
  41. self.taskQueue = [[NSOperationQueue alloc] init];
  42. self.taskQueue.qualityOfService = NSQualityOfServiceUtility;
  43. self.taskQueue.maxConcurrentOperationCount = 10;
  44. }
  45. return self;
  46. }
  47. + (RNFetchBlobNetwork* _Nullable)sharedInstance {
  48. static id _sharedInstance = nil;
  49. static dispatch_once_t onceToken;
  50. dispatch_once(&onceToken, ^{
  51. _sharedInstance = [[self alloc] init];
  52. });
  53. return _sharedInstance;
  54. }
  55. - (void) sendRequest:(__weak NSDictionary * _Nullable )options
  56. contentLength:(long) contentLength
  57. bridge:(RCTBridge * _Nullable)bridgeRef
  58. taskId:(NSString * _Nullable)taskId
  59. withRequest:(__weak NSURLRequest * _Nullable)req
  60. callback:(_Nullable RCTResponseSenderBlock) callback
  61. {
  62. RNFetchBlobRequest *request = [[RNFetchBlobRequest alloc] init];
  63. [request sendRequest:options
  64. contentLength:contentLength
  65. bridge:bridgeRef
  66. taskId:taskId
  67. withRequest:req
  68. taskOperationQueue:self.taskQueue
  69. callback:callback];
  70. @synchronized([RNFetchBlobNetwork class]) {
  71. [self.requestsTable setObject:request forKey:taskId];
  72. }
  73. }
  74. - (void) enableProgressReport:(NSString *) taskId config:(RNFetchBlobProgress *)config
  75. {
  76. if (config) {
  77. @synchronized ([RNFetchBlobNetwork class]) {
  78. [self.requestsTable objectForKey:taskId].progressConfig = config;
  79. }
  80. }
  81. }
  82. - (void) enableUploadProgress:(NSString *) taskId config:(RNFetchBlobProgress *)config
  83. {
  84. if (config) {
  85. @synchronized ([RNFetchBlobNetwork class]) {
  86. [self.requestsTable objectForKey:taskId].uploadProgressConfig = config;
  87. }
  88. }
  89. }
  90. - (void) cancelRequest:(NSString *)taskId
  91. {
  92. NSURLSessionDataTask * task;
  93. @synchronized ([RNFetchBlobNetwork class]) {
  94. task = [self.requestsTable objectForKey:taskId].task;
  95. }
  96. if (task && task.state == NSURLSessionTaskStateRunning) {
  97. [task cancel];
  98. }
  99. }
  100. // removing case from headers
  101. + (NSMutableDictionary *) normalizeHeaders:(NSDictionary *)headers
  102. {
  103. NSMutableDictionary * mheaders = [[NSMutableDictionary alloc]init];
  104. for (NSString * key in headers) {
  105. [mheaders setValue:[headers valueForKey:key] forKey:[key lowercaseString]];
  106. }
  107. return mheaders;
  108. }
  109. // #115 Invoke fetch.expire event on those expired requests so that the expired event can be handled
  110. + (void) emitExpiredTasks
  111. {
  112. @synchronized ([RNFetchBlobNetwork class]){
  113. NSEnumerator * emu = [expirationTable keyEnumerator];
  114. NSString * key;
  115. while ((key = [emu nextObject]))
  116. {
  117. RCTBridge * bridge = [RNFetchBlob getRCTBridge];
  118. id args = @{ @"taskId": key };
  119. [bridge.eventDispatcher sendDeviceEventWithName:EVENT_EXPIRE body:args];
  120. }
  121. // clear expired task entries
  122. [expirationTable removeAllObjects];
  123. expirationTable = [[NSMapTable alloc] init];
  124. }
  125. }
  126. @end