|
@@ -9,8 +9,10 @@
|
9
|
9
|
#import "RCTLog.h"
|
10
|
10
|
#import <Foundation/Foundation.h>
|
11
|
11
|
#import "RCTBridge.h"
|
|
12
|
+#import "RNFetchBlob.h"
|
12
|
13
|
#import "RCTEventDispatcher.h"
|
13
|
14
|
#import "RNFetchBlobFS.h"
|
|
15
|
+#import "RCTRootView.h"
|
14
|
16
|
#import "RNFetchBlobNetwork.h"
|
15
|
17
|
#import "RNFetchBlobConst.h"
|
16
|
18
|
#import "RNFetchBlobReqBuilder.h"
|
|
@@ -24,6 +26,7 @@
|
24
|
26
|
////////////////////////////////////////
|
25
|
27
|
|
26
|
28
|
NSMapTable * taskTable;
|
|
29
|
+NSMapTable * expirationTable;
|
27
|
30
|
NSMutableDictionary * progressTable;
|
28
|
31
|
NSMutableDictionary * uploadProgressTable;
|
29
|
32
|
|
|
@@ -37,6 +40,7 @@ typedef NS_ENUM(NSUInteger, ResponseFormat) {
|
37
|
40
|
@interface RNFetchBlobNetwork ()
|
38
|
41
|
{
|
39
|
42
|
BOOL * respFile;
|
|
43
|
+ BOOL * isIncrement;
|
40
|
44
|
NSString * destPath;
|
41
|
45
|
NSOutputStream * writeStream;
|
42
|
46
|
long bodyLength;
|
|
@@ -70,7 +74,12 @@ NSOperationQueue *taskQueue;
|
70
|
74
|
taskQueue = [[NSOperationQueue alloc] init];
|
71
|
75
|
taskQueue.maxConcurrentOperationCount = 10;
|
72
|
76
|
}
|
73
|
|
- if(taskTable == nil) {
|
|
77
|
+ if(expirationTable == nil)
|
|
78
|
+ {
|
|
79
|
+ expirationTable = [[NSMapTable alloc] init];
|
|
80
|
+ }
|
|
81
|
+ if(taskTable == nil)
|
|
82
|
+ {
|
74
|
83
|
taskTable = [[NSMapTable alloc] init];
|
75
|
84
|
}
|
76
|
85
|
if(progressTable == nil)
|
|
@@ -133,6 +142,7 @@ NSOperationQueue *taskQueue;
|
133
|
142
|
self.expectedBytes = 0;
|
134
|
143
|
self.receivedBytes = 0;
|
135
|
144
|
self.options = options;
|
|
145
|
+ isIncrement = [options valueForKey:@"increment"] == nil ? NO : [[options valueForKey:@"increment"] boolValue];
|
136
|
146
|
redirects = [[NSMutableArray alloc] init];
|
137
|
147
|
[redirects addObject:req.URL.absoluteString];
|
138
|
148
|
|
|
@@ -153,7 +163,9 @@ NSOperationQueue *taskQueue;
|
153
|
163
|
bodyLength = contentLength;
|
154
|
164
|
|
155
|
165
|
// the session trust any SSL certification
|
156
|
|
- NSURLSessionConfiguration *defaultConfigObject = [NSURLSessionConfiguration defaultSessionConfiguration];
|
|
166
|
+// NSURLSessionConfiguration *defaultConfigObject = [NSURLSessionConfiguration defaultSessionConfiguration];
|
|
167
|
+ NSURLSessionConfiguration *defaultConfigObject = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:taskId];
|
|
168
|
+
|
157
|
169
|
// set request timeout
|
158
|
170
|
float timeout = [options valueForKey:@"timeout"] == nil ? -1 : [[options valueForKey:@"timeout"] floatValue];
|
159
|
171
|
if(timeout > 0)
|
|
@@ -190,13 +202,39 @@ NSOperationQueue *taskQueue;
|
190
|
202
|
respData = [[NSMutableData alloc] init];
|
191
|
203
|
respFile = NO;
|
192
|
204
|
}
|
193
|
|
- NSURLSessionDataTask * task = [session dataTaskWithRequest:req];
|
|
205
|
+
|
|
206
|
+ __block NSURLSessionDataTask * task = [session dataTaskWithRequest:req];
|
194
|
207
|
[taskTable setObject:task forKey:taskId];
|
195
|
208
|
[task resume];
|
196
|
209
|
|
197
|
210
|
// network status indicator
|
198
|
211
|
if([[options objectForKey:CONFIG_INDICATOR] boolValue] == YES)
|
199
|
212
|
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
|
|
213
|
+ __block UIApplication * app = [UIApplication sharedApplication];
|
|
214
|
+
|
|
215
|
+ // #115 handling task expired when application entering backgound for a long time
|
|
216
|
+ [app beginBackgroundTaskWithName:taskId expirationHandler:^{
|
|
217
|
+ NSLog([NSString stringWithFormat:@"session %@ expired event emit", taskId ]);
|
|
218
|
+ [expirationTable setObject:task forKey:taskId];
|
|
219
|
+ [app endBackgroundTask:task];
|
|
220
|
+
|
|
221
|
+ }];
|
|
222
|
+
|
|
223
|
+
|
|
224
|
+}
|
|
225
|
+
|
|
226
|
+// #115 Invoke fetch.expire event on those expired requests so that the expired event can be handled
|
|
227
|
++ (void) getExpiredTasks
|
|
228
|
+{
|
|
229
|
+ NSEnumerator * emu = [expirationTable keyEnumerator];
|
|
230
|
+ NSString * key;
|
|
231
|
+
|
|
232
|
+ while((key = [emu nextObject]))
|
|
233
|
+ {
|
|
234
|
+ RCTBridge * bridge = [RNFetchBlob getRCTBridge];
|
|
235
|
+ NSData * args = @{ @"taskId": key };
|
|
236
|
+ [bridge.eventDispatcher sendDeviceEventWithName:EVENT_EXPIRE body:args];
|
|
237
|
+ }
|
200
|
238
|
}
|
201
|
239
|
|
202
|
240
|
////////////////////////////////////////
|
|
@@ -306,7 +344,7 @@ NSOperationQueue *taskQueue;
|
306
|
344
|
receivedBytes += [received longValue];
|
307
|
345
|
NSString * chunkString = @"";
|
308
|
346
|
|
309
|
|
- if(isInrement == YES)
|
|
347
|
+ if(isIncrement == YES)
|
310
|
348
|
{
|
311
|
349
|
chunkString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
|
312
|
350
|
}
|
|
@@ -480,6 +518,11 @@ NSOperationQueue *taskQueue;
|
480
|
518
|
}
|
481
|
519
|
}
|
482
|
520
|
|
|
521
|
+- (void) URLSessionDidFinishEventsForBackgroundURLSession:(NSURLSession *)session
|
|
522
|
+{
|
|
523
|
+ NSLog(@"sess done in background");
|
|
524
|
+}
|
|
525
|
+
|
483
|
526
|
- (void) URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task willPerformHTTPRedirection:(NSHTTPURLResponse *)response newRequest:(NSURLRequest *)request completionHandler:(void (^)(NSURLRequest * _Nullable))completionHandler
|
484
|
527
|
{
|
485
|
528
|
[redirects addObject:[request.URL absoluteString]];
|