21
21
//
22
22
// //////////////////////////////////////
23
23
24
+ @interface RNFetchBlobNetwork ()
25
+ {
26
+ BOOL * respFile;
27
+ NSString * destPath;
28
+ NSOutputStream * writeStream;
29
+ long bodyLength;
30
+ }
31
+
32
+ @end
33
+
24
34
@implementation RNFetchBlobNetwork
25
35
26
36
NSOperationQueue *taskQueue;
@@ -32,8 +42,8 @@ @implementation RNFetchBlobNetwork
32
42
@synthesize callback;
33
43
@synthesize bridge;
34
44
@synthesize options;
35
- // @synthesize fileTaskCompletionHandler;
36
- // @synthesize dataTaskCompletionHandler;
45
+ @synthesize fileTaskCompletionHandler;
46
+ @synthesize dataTaskCompletionHandler;
37
47
@synthesize error;
38
48
39
49
@@ -73,83 +83,28 @@ - (void) sendRequest:(NSDictionary * _Nullable )options bridge:(RCTBridge * _Nu
73
83
NSString * ext = [self .options valueForKey: CONFIG_FILE_EXT];
74
84
NSURLSession * session;
75
85
86
+ bodyLength = [[req HTTPBody ] length ];
87
+
76
88
// the session trust any SSL certification
77
- if ([options valueForKey: CONFIG_TRUSTY] != nil )
89
+
90
+ NSURLSessionConfiguration *defaultConfigObject = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier: taskId];
91
+ session = [NSURLSession sessionWithConfiguration: defaultConfigObject delegate: self delegateQueue: [NSOperationQueue mainQueue ]];
92
+
93
+ if (path != nil || [self .options valueForKey: CONFIG_USE_TEMP]!= nil )
78
94
{
79
- NSURLSessionConfiguration *defaultConfigObject = [NSURLSessionConfiguration defaultSessionConfiguration ];
80
- session = [NSURLSession sessionWithConfiguration: defaultConfigObject delegate: self delegateQueue: [NSOperationQueue mainQueue ]];
95
+ respFile = YES ;
96
+ if (path != nil )
97
+ destPath = path;
98
+ else
99
+ destPath = [RNFetchBlobFS getTempPath: taskId withExtension: [self .options valueForKey: CONFIG_FILE_EXT]];
81
100
}
82
- // the session validates SSL certification, self-signed certification will be aborted
83
101
else
84
102
{
85
- session = [NSURLSession sharedSession ];
86
- }
87
-
88
- // file will be stored at a specific path
89
- if ( path != nil ) {
90
-
91
- // self.fileTaskCompletionHandler = ;
92
- NSURLSessionDownloadTask * task = [session downloadTaskWithRequest: req completionHandler: ^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) {
93
- if (error != nil ) {
94
- callback (@[[error localizedDescription ]]);
95
- return ;
96
- }
97
- NSError * taskErr;
98
- NSFileManager * fm = [NSFileManager defaultManager ];
99
- // move temp file to desination
100
- [fm moveItemAtURL: location toURL: [NSURL fileURLWithPath: path] error: &taskErr];
101
- if (taskErr != nil ) {
102
- callback (@[[taskErr localizedDescription ]]);
103
- return ;
104
- }
105
- callback (@[[NSNull null ], path]);
106
- // prevent memory leaks
107
- self.respData = nil ;
108
- [[UIApplication sharedApplication ] setNetworkActivityIndicatorVisible: NO ];
109
- }];
110
- [task resume ];
111
- }
112
- // file will be stored at tmp path
113
- else if ( [self .options valueForKey: CONFIG_USE_TEMP]!= nil ) {
114
-
115
- // self.fileTaskCompletionHandler;
116
- NSURLSessionDownloadTask * task = [session downloadTaskWithRequest: req completionHandler: ^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) {
117
- if (error != nil ) {
118
- callback (@[[error localizedDescription ]]);
119
- return ;
120
- }
121
- NSError * taskErr;
122
- NSFileManager * fm = [NSFileManager defaultManager ];
123
- NSString * tmpPath = [RNFetchBlobFS getTempPath: self .taskId withExtension: [self .options valueForKey: CONFIG_FILE_EXT]];
124
- // move temp file to desination
125
- [fm moveItemAtURL: location toURL: [NSURL fileURLWithPath: tmpPath] error: &taskErr];
126
- if (taskErr != nil ) {
127
- callback (@[[taskErr localizedDescription ]]);
128
- return ;
129
- }
130
- callback (@[[NSNull null ], tmpPath]);
131
- [[UIApplication sharedApplication ] setNetworkActivityIndicatorVisible: NO ];
132
- // prevent memory leaks
133
- self.respData = nil ;
134
- }];
135
- [task resume ];
136
- }
137
- // base64 response
138
- else {
139
- // self.dataTaskCompletionHandler = ;
140
- NSURLSessionDataTask * task = [session dataTaskWithRequest: req completionHandler: ^(NSData * _Nullable resp, NSURLResponse * _Nullable response, NSError * _Nullable error) {
141
- if (error != nil ) {
142
- callback (@[[error localizedDescription ]]);
143
- return ;
144
- }
145
- else {
146
- callback (@[[NSNull null ], [resp base64EncodedStringWithOptions: 0 ]]);
147
- }
148
- self.respData = nil ;
149
- [[UIApplication sharedApplication ] setNetworkActivityIndicatorVisible: NO ];
150
- }];
151
- [task resume ];
103
+ respData = [[NSMutableData alloc ] init ];
104
+ respFile = NO ;
152
105
}
106
+ NSURLSessionDataTask * task = [session dataTaskWithRequest: req];
107
+ [task resume ];
153
108
154
109
// network status indicator
155
110
if ([[options objectForKey: CONFIG_INDICATOR] boolValue ] == YES )
@@ -169,19 +124,34 @@ - (void) sendRequest:(NSDictionary * _Nullable )options bridge:(RCTBridge * _Nu
169
124
- (void ) URLSession : (NSURLSession *)session dataTask : (NSURLSessionDataTask *)dataTask didReceiveResponse : (NSURLResponse *)response completionHandler : (void (^)(NSURLSessionResponseDisposition ))completionHandler
170
125
{
171
126
expectedBytes = [response expectedContentLength ];
127
+
128
+ if (respFile == YES )
129
+ {
130
+ NSFileManager * fm = [NSFileManager defaultManager ];
131
+ NSString * folder = [destPath stringByDeletingLastPathComponent ];
132
+ if (![fm fileExistsAtPath: folder]) {
133
+ [fm createDirectoryAtPath: folder withIntermediateDirectories: YES attributes: NULL error: nil ];
134
+ }
135
+ [fm createFileAtPath: destPath contents: [[NSData alloc ] init ] attributes: nil ];
136
+ writeStream = [[NSOutputStream alloc ] initToFileAtPath: destPath append: YES ];
137
+ [writeStream scheduleInRunLoop: [NSRunLoop currentRunLoop ] forMode: NSRunLoopCommonModes ];
138
+ [writeStream open ];
139
+ }
140
+ completionHandler (NSURLSessionResponseAllow );
172
141
}
173
142
174
143
// download progress handler
175
144
- (void ) URLSession : (NSURLSession *)session dataTask : (NSURLSessionDataTask *)dataTask didReceiveData : (NSData *)data
176
145
{
177
146
receivedBytes += [data length ];
178
-
179
- Boolean fileCache = [self .options valueForKey: CONFIG_USE_TEMP];
180
- NSString * path = [self .options valueForKey: CONFIG_FILE_PATH];
181
- // cache data in memory
182
- if (path == nil && fileCache == nil ) {
147
+ if (respFile == NO )
148
+ {
183
149
[respData appendData: data];
184
150
}
151
+ else
152
+ {
153
+ [writeStream write :[data bytes ] maxLength: [data length ]];
154
+ }
185
155
186
156
[self .bridge.eventDispatcher
187
157
sendDeviceEventWithName: @" RNFetchBlobProgress"
@@ -191,6 +161,20 @@ - (void) URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dat
191
161
@" total" : [NSString stringWithFormat: @" %d " , expectedBytes]
192
162
}
193
163
];
164
+
165
+ if (receivedBytes >= expectedBytes)
166
+ {
167
+ if (respFile == YES )
168
+ {
169
+ [writeStream close ];
170
+ callback (@[[NSNull null ], destPath]);
171
+ }
172
+ // base64 response
173
+ else {
174
+ callback (@[[NSNull null ], [respData base64EncodedStringWithOptions: 0 ]]);
175
+ }
176
+ [[UIApplication sharedApplication ] setNetworkActivityIndicatorVisible: NO ];
177
+ }
194
178
}
195
179
196
180
- (void ) URLSession : (NSURLSession *)session task : (NSURLSessionTask *)task didCompleteWithError : (NSError *)error {
@@ -202,14 +186,12 @@ - (void) URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCom
202
186
// upload progress handler
203
187
- (void ) URLSession : (NSURLSession *)session task : (NSURLSessionTask *)task didSendBodyData : (int64_t )bytesSent totalBytesSent : (int64_t )totalBytesWritten totalBytesExpectedToSend : (int64_t )totalBytesExpectedToWrite
204
188
{
205
- expectedBytes = totalBytesExpectedToWrite;
206
- receivedBytes += totalBytesWritten;
207
189
[self .bridge.eventDispatcher
208
190
sendDeviceEventWithName: @" RNFetchBlobProgress"
209
191
body: @{
210
192
@" taskId" : taskId,
211
- @" written" : [NSString stringWithFormat: @" %d " , receivedBytes ],
212
- @" total" : [NSString stringWithFormat: @" %d " , expectedBytes ]
193
+ @" written" : [NSString stringWithFormat: @" %d " , totalBytesWritten ],
194
+ @" total" : [NSString stringWithFormat: @" %d " , totalBytesExpectedToWrite ]
213
195
}
214
196
];
215
197
}
@@ -230,13 +212,34 @@ - (void) URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didSen
230
212
// }
231
213
// }
232
214
233
- - (void ) URLSession : (NSURLSession *)session task : ( NSURLSessionTask *) task didReceiveChallenge : (NSURLAuthenticationChallenge *)challenge completionHandler : (void (^)(NSURLSessionAuthChallengeDisposition , NSURLCredential * _Nullable))completionHandler
215
+ - (void ) URLSession : (NSURLSession *)session didReceiveChallenge : (NSURLAuthenticationChallenge *)challenge completionHandler : (void (^)(NSURLSessionAuthChallengeDisposition , NSURLCredential * _Nullable credantial ))completionHandler
234
216
{
235
217
if ([options valueForKey: CONFIG_TRUSTY] != nil )
236
- completionHandler (NSURLSessionAuthChallengeUseCredential , [NSURLCredential credentialForTrust: challenge.protectionSpace.serverTrust]);
237
- else {
238
- RCTLogWarn (@" counld not create connection with an unstrusted SSL certification, if you're going to create connection anyway, add `trusty:true` to RNFetchBlob.config" );
239
- [[UIApplication sharedApplication ] setNetworkActivityIndicatorVisible: NO ];
218
+ {
219
+ completionHandler (NSURLSessionAuthChallengePerformDefaultHandling , [NSURLCredential credentialForTrust: challenge.protectionSpace.serverTrust]);
220
+ }
221
+ else
222
+ {
223
+ NSURLSessionAuthChallengeDisposition disposition = NSURLSessionAuthChallengePerformDefaultHandling ;
224
+ __block NSURLCredential *credential = nil ;
225
+ if ([challenge.protectionSpace.authenticationMethod isEqualToString: NSURLAuthenticationMethodServerTrust ])
226
+ {
227
+ credential = [NSURLCredential credentialForTrust: challenge.protectionSpace.serverTrust];
228
+ if (credential) {
229
+ disposition = NSURLSessionAuthChallengeUseCredential ;
230
+ } else {
231
+ disposition = NSURLSessionAuthChallengePerformDefaultHandling ;
232
+ }
233
+ }
234
+ else
235
+ {
236
+ disposition = NSURLSessionAuthChallengeCancelAuthenticationChallenge ;
237
+ RCTLogWarn (@" counld not create connection with an unstrusted SSL certification, if you're going to create connection anyway, add `trusty:true` to RNFetchBlob.config" );
238
+ [[UIApplication sharedApplication ] setNetworkActivityIndicatorVisible: NO ];
239
+ }
240
+ if (completionHandler) {
241
+ completionHandler (disposition, credential);
242
+ }
240
243
}
241
244
}
242
245
0 commit comments