Skip to content
This repository was archived by the owner on Mar 16, 2019. It is now read-only.

Commit e612ea5

Browse files
committed
#24 Change IOS fetch implementation to NSURLSession API
1 parent e245d34 commit e612ea5

File tree

3 files changed

+122
-81
lines changed

3 files changed

+122
-81
lines changed

src/ios/RNFetchBlob/RNFetchBlob.m

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -76,9 +76,9 @@ - (NSDictionary *)constantsToExport
7676
// generate boundary
7777
NSString * boundary = [NSString stringWithFormat:@"RNFetchBlob%d", timeStampObj];
7878
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
79+
NSMutableData * postData = [[NSMutableData alloc] init];
7980
// if method is POST or PUT, convert data string format
8081
if([[method lowercaseString] isEqualToString:@"post"] || [[method lowercaseString] isEqualToString:@"put"]) {
81-
NSMutableData * postData = [[NSMutableData alloc] init];
8282

8383
// combine multipart/form-data body
8484
for(id field in form) {
@@ -129,7 +129,7 @@ - (NSDictionary *)constantsToExport
129129

130130
// send HTTP request
131131
FetchBlobUtils * utils = [[FetchBlobUtils alloc] init];
132-
[utils sendRequest:options bridge:self.bridge taskId:taskId withRequest:request callback:callback];
132+
[utils sendRequest:options bridge:self.bridge taskId:taskId withRequest:request withData:postData callback:callback];
133133
});
134134
}
135135

@@ -149,11 +149,11 @@ - (NSDictionary *)constantsToExport
149149
NSMutableDictionary *mheaders = [[NSMutableDictionary alloc] initWithDictionary:[FetchBlobUtils normalizeHeaders:headers]];
150150
// move heavy task to another thread
151151
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
152+
NSMutableData * blobData;
152153
// if method is POST or PUT, convert data string format
153154
if([[method lowercaseString] isEqualToString:@"post"] || [[method lowercaseString] isEqualToString:@"put"]) {
154155
// generate octet-stream body
155156
if(body != nil) {
156-
NSMutableData * blobData;
157157

158158
// when body is a string contains file path prefix, try load file from the path
159159
if([body hasPrefix:self.filePathPrefix]) {
@@ -174,7 +174,7 @@ - (NSDictionary *)constantsToExport
174174

175175
// send HTTP request
176176
FetchBlobUtils * utils = [[FetchBlobUtils alloc] init];
177-
[utils sendRequest:options bridge:self.bridge taskId:taskId withRequest:request callback:callback];
177+
[utils sendRequest:options bridge:self.bridge taskId:taskId withRequest:request withData:blobData callback:callback];
178178
});
179179
}
180180

src/ios/RNFetchBlobResp.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
#import <Foundation/Foundation.h>
1313
#import "RCTBridgeModule.h"
1414

15-
@interface FetchBlobUtils : NSObject <NSURLConnectionDelegate, NSURLConnectionDataDelegate> {
15+
@interface FetchBlobUtils : NSObject <NSURLSessionDelegate, NSURLSessionTaskDelegate, NSURLSessionDataDelegate> {
1616

1717
NSString * taskId;
1818
int expectedBytes;
@@ -37,7 +37,7 @@
3737
- (void) sendRequest;
3838

3939
+ (NSMutableDictionary *) normalizeHeaders:(NSDictionary *)headers;
40-
- (void) sendRequest:(NSDictionary *)options bridge:(RCTBridge *)bridgeRef taskId:(NSString *)taskId withRequest:(NSURLRequest *)req callback:(RCTResponseSenderBlock) callback;
40+
- (void) sendRequest:(NSDictionary *)options bridge:(RCTBridge *)bridgeRef taskId:(NSString *)taskId withRequest:(NSURLRequest *)req withData:( NSData * _Nullable )data callback:(RCTResponseSenderBlock) callback;
4141

4242

4343
@end

src/ios/RNFetchBlobResp.m

Lines changed: 116 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ - (id)init {
5050
}
5151

5252

53-
- (void) sendRequest:(NSDictionary *)options bridge:(RCTBridge *)bridgeRef taskId:(NSString *)taskId withRequest:(NSURLRequest *)req callback:(RCTResponseSenderBlock) callback {
53+
- (void) sendRequest:(NSDictionary *)options bridge:(RCTBridge *)bridgeRef taskId:(NSString *)taskId withRequest:(NSURLRequest *)req withData:( NSData * _Nullable )data callback:(RCTResponseSenderBlock) callback {
5454
self.taskId = taskId;
5555
self.respData = [[NSMutableData alloc] initWithLength:0];
5656
self.callback = callback;
@@ -61,52 +61,89 @@ - (void) sendRequest:(NSDictionary *)options bridge:(RCTBridge *)bridgeRef taskI
6161

6262
NSString * path = [self.options valueForKey:CONFIG_FILE_PATH];
6363
NSString * ext = [self.options valueForKey:CONFIG_FILE_EXT];
64+
65+
NSURLSession * session = [NSURLSession sharedSession];
6466

65-
// open file stream for write
67+
// file will be stored at a specific path
6668
if( path != nil) {
67-
self.fileStream = [[RNFetchBlobFS alloc]initWithCallback:self.callback];
68-
[self.fileStream openWithPath:path encode:@"ascii" appendData:YES ];
69+
NSURLSessionDownloadTask * task = [session downloadTaskWithRequest:req completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) {
70+
if(error != nil) {
71+
callback(@[[error localizedDescription]]);
72+
return;
73+
}
74+
NSError * taskErr;
75+
NSFileManager * fm = [NSFileManager defaultManager];
76+
// move temp file to desination
77+
[fm moveItemAtURL:location toURL:[NSURL fileURLWithPath:path] error:&taskErr];
78+
if(taskErr != nil) {
79+
callback(@[[taskErr localizedDescription]]);
80+
return;
81+
}
82+
callback(@[[NSNull null], path]);
83+
}];
84+
[task resume];
6985
}
86+
// file will be stored at tmp path
7087
else if ( [self.options valueForKey:CONFIG_USE_TEMP]!= nil ) {
71-
self.fileStream = [[RNFetchBlobFS alloc]initWithCallback:self.callback];
72-
[self.fileStream openWithPath:[RNFetchBlobFS getTempPath:taskId withExtension:ext] encode:@"ascii" appendData:YES];
88+
NSURLSessionDownloadTask * task = [session downloadTaskWithRequest:req completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) {
89+
if(error != nil) {
90+
callback(@[[error localizedDescription]]);
91+
return;
92+
}
93+
NSError * taskErr;
94+
NSFileManager * fm = [NSFileManager defaultManager];
95+
NSString * tmpPath = [RNFetchBlobFS getTempPath:self.taskId withExtension:[self.options valueForKey:CONFIG_FILE_EXT]];
96+
// move temp file to desination
97+
[fm moveItemAtURL:location toURL:[NSURL fileURLWithPath:tmpPath] error:&taskErr];
98+
if(taskErr != nil) {
99+
callback(@[[taskErr localizedDescription]]);
100+
return;
101+
}
102+
callback(@[[NSNull null], tmpPath]);
103+
}];
104+
[task resume];
73105
}
74-
75-
NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:req delegate:self startImmediately:NO];
76-
[conn scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
77-
[conn start];
78-
79-
if(!conn) {
80-
callback(@[[NSString stringWithFormat:@"RNFetchBlob could not initialize connection"], [NSNull null]]);
106+
// base64 response
107+
else {
108+
109+
NSURLSessionUploadTask * task =
110+
[session dataTaskWithRequest:req completionHandler:^(NSData * _Nullable resp, NSURLResponse * _Nullable response, NSError * _Nullable error) {
111+
if(error != nil) {
112+
callback(@[[error localizedDescription]]);
113+
return;
114+
}
115+
else
116+
callback(@[[NSNull null], [resp base64EncodedStringWithOptions:0]]);
117+
}];
118+
// [session uploadTaskWithRequest:req fromData:data completionHandler:^(NSData * _Nullable resp, NSURLResponse * _Nullable response, NSError * _Nullable error) {
119+
// if(error != nil) {
120+
// callback(@[[error localizedDescription]]);
121+
// return;
122+
// }
123+
// else
124+
// callback(@[[NSNull null], [resp base64EncodedStringWithOptions:0]]);
125+
// }];
126+
[task resume];
81127
}
128+
// callback(@[[NSString stringWithFormat:@"RNFetchBlob could not initialize connection"], [NSNull null]]);
82129
}
83130

84131

85-
#pragma mark NSURLConnection delegate methods
132+
#pragma mark NSURLSession delegate methods
86133

87-
88-
- (void) connection:(NSURLConnection *)connection didReceiveResponse:(nonnull NSURLResponse *)response {
89-
// [UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
134+
- (void) URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler
135+
{
90136
expectedBytes = [response expectedContentLength];
91137
}
92138

93-
94-
- (void) connection:(NSURLConnection *)connection didReceiveData:(nonnull NSData *)data {
139+
- (void) URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data
140+
{
95141
receivedBytes += [data length];
96142

97143
Boolean fileCache = [self.options valueForKey:CONFIG_USE_TEMP];
98144
NSString * path = [self.options valueForKey:CONFIG_FILE_PATH];
99-
if(path != nil) {
100-
101-
[self.fileStream write:data];
102-
}
103-
// write to tmp file
104-
else if( fileCache != nil) {
105-
NSString * ext = [self.options valueForKey:CONFIG_FILE_EXT];
106-
[self.fileStream write:data];
107-
}
108145
// cache data in memory
109-
else {
146+
if(path == nil && fileCache == nil) {
110147
[respData appendData:data];
111148
}
112149

@@ -120,8 +157,8 @@ - (void) connection:(NSURLConnection *)connection didReceiveData:(nonnull NSData
120157
];
121158
}
122159

123-
- (void) connection:(NSURLConnection *)connection didSendBodyData:(NSInteger)bytesWritten totalBytesWritten:(NSInteger)totalBytesWritten totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite {
124-
160+
- (void) URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didSendBodyData:(int64_t)bytesSent totalBytesSent:(int64_t)totalBytesWritten totalBytesExpectedToSend:(int64_t)totalBytesExpectedToWrite
161+
{
125162
expectedBytes = totalBytesExpectedToWrite;
126163
receivedBytes += totalBytesWritten;
127164
[self.bridge.eventDispatcher
@@ -132,57 +169,61 @@ - (void) connection:(NSURLConnection *)connection didSendBodyData:(NSInteger)byt
132169
@"total": [NSString stringWithFormat:@"%d", expectedBytes]
133170
}
134171
];
135-
136172
}
137173

138-
- (void) connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
139-
140-
// [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
141-
142-
[self.fileStream closeInStream];
143-
[self.fileStream closeOutStream];
144-
145-
callback(@[[error localizedDescription], [NSNull null]]);
146-
}
147174

148-
- (NSCachedURLResponse *) connection:(NSURLConnection *)connection willCacheResponse: (NSCachedURLResponse *)cachedResponse {
149-
return nil;
150-
}
175+
//- (void) URLSessionDidFinishEventsForBackgroundURLSession:(NSURLSession *)session
176+
//{
177+
//
178+
//}
179+
180+
181+
//- (void) connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
182+
//
183+
// // [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
184+
//
185+
// [self.fileStream closeInStream];
186+
// [self.fileStream closeOutStream];
187+
//
188+
// callback(@[[error localizedDescription], [NSNull null]]);
189+
//}
190+
191+
151192

152193

153194
// handle 301 and 302 responses
154-
- (NSURLRequest *)connection:(NSURLConnection *)connection willSendRequest:(NSURLRequest *)request redirectResponse:response {
155-
return request;
156-
}
195+
//- (NSURLRequest *)connection:(NSURLConnection *)connection willSendRequest:(NSURLRequest *)request redirectResponse:response {
196+
// return request;
197+
//}
157198

158199
// request complete
159-
- (void) connectionDidFinishLoading:(NSURLConnection *)connection {
160-
161-
NSData * data;
162-
if(respData != nil)
163-
data = [NSData dataWithData:respData];
164-
else
165-
data = [[NSData alloc] init];
166-
167-
NSString * path = [self.options valueForKey:CONFIG_FILE_PATH];
168-
NSString * ext = [self.options valueForKey:CONFIG_FILE_EXT];
169-
Boolean useCache = [self.options valueForKey:CONFIG_USE_TEMP];
170-
171-
[self.fileStream closeInStream];
172-
173-
// if fileCache is true or file path is given, return a path
174-
if( path != nil ) {
175-
callback(@[[NSNull null], path]);
176-
}
177-
// when fileCache option is set but no path specified, save to tmp path
178-
else if( [self.options valueForKey:CONFIG_USE_TEMP] != nil) {
179-
NSString * tmpPath = [RNFetchBlobFS getTempPath:taskId withExtension:ext];
180-
callback(@[[NSNull null], tmpPath]);
181-
}
182-
// otherwise return base64 string
183-
else {
184-
callback(@[[NSNull null], [data base64EncodedStringWithOptions:0]]);
185-
}
186-
}
200+
//- (void) connectionDidFinishLoading:(NSURLConnection *)connection {
201+
//
202+
// NSData * data;
203+
// if(respData != nil)
204+
// data = [NSData dataWithData:respData];
205+
// else
206+
// data = [[NSData alloc] init];
207+
//
208+
// NSString * path = [self.options valueForKey:CONFIG_FILE_PATH];
209+
// NSString * ext = [self.options valueForKey:CONFIG_FILE_EXT];
210+
// Boolean useCache = [self.options valueForKey:CONFIG_USE_TEMP];
211+
//
212+
// [self.fileStream closeInStream];
213+
//
214+
// // if fileCache is true or file path is given, return a path
215+
// if( path != nil ) {
216+
// callback(@[[NSNull null], path]);
217+
// }
218+
// // when fileCache option is set but no path specified, save to tmp path
219+
// else if( [self.options valueForKey:CONFIG_USE_TEMP] != nil) {
220+
// NSString * tmpPath = [RNFetchBlobFS getTempPath:taskId withExtension:ext];
221+
// callback(@[[NSNull null], tmpPath]);
222+
// }
223+
// // otherwise return base64 string
224+
// else {
225+
// callback(@[[NSNull null], [data base64EncodedStringWithOptions:0]]);
226+
// }
227+
//}
187228

188229
@end

0 commit comments

Comments
 (0)