浏览代码

Merge branch 'master' into 0.6.0

Ben Hsieh 8 年前
父节点
当前提交
119199c5b9

+ 4
- 2
README.md 查看文件

@@ -1,4 +1,4 @@
1
-# react-native-fetch-blob [![npm version](https://img.shields.io/badge/npm package-0.5.3-brightgreen.svg)](https://badge.fury.io/js/react-native-fetch-blob) ![](https://img.shields.io/badge/PR-Welcome-brightgreen.svg) ![](https://img.shields.io/badge/in progress-0.6.0-yellow.svg)
1
+# react-native-fetch-blob [![npm version](https://img.shields.io/badge/npm package-0.5.5-brightgreen.svg)](https://badge.fury.io/js/react-native-fetch-blob) ![](https://img.shields.io/badge/PR-Welcome-brightgreen.svg) ![](https://img.shields.io/badge/in progress-0.6.0-yellow.svg)
2 2
 
3 3
 A module provides upload, download, and files access API. Supports file stream read/write for process large files.
4 4
 
@@ -26,7 +26,7 @@ This update is `backward-compatible` generally you don't have to change existing
26 26
  * [File access](#user-content-file-access)
27 27
  * [File stream](#user-content-file-stream)
28 28
  * [Manage cached files](#user-content-manage-cached-files)
29
- * [Self-Signed SSL Server](#user-content-selfsigned-ssl-server)
29
+ * [Self-Signed SSL Server](#user-content-self-signed-ssl-server)
30 30
 * [API](#user-content-api)
31 31
  * [config](#user-content-configoptionsrnfetchblobconfigfetch)
32 32
  * [fetch](#user-content-fetchmethod-url-headers-bodypromisefetchblobresponse)
@@ -871,6 +871,8 @@ A `session` is an object that helps you manage files. It simply maintains a list
871 871
 
872 872
 | Version | |
873 873
 |---|---|
874
+| 0.5.5 | Remove work in progress code added in 0.5.2 which may cause memory leaks. |
875
+| 0.5.4 | Fix #30 #31 build build error, and improve memory efficiency. |
874 876
 | 0.5.3 | Add API for access untrusted SSL server |
875 877
 | 0.5.2 | Fix improper url params bug [#26](https://github.com/wkh237/react-native-fetch-blob/issues/26) and change IOS HTTP implementation from NSURLConnection to NSURLSession |
876 878
 | 0.5.0 | Upload/download with direct access to file storage, and also added file access APIs |

+ 1
- 1
package.json 查看文件

@@ -1,6 +1,6 @@
1 1
 {
2 2
   "name": "fetchblob",
3
-  "version": "0.5.2",
3
+  "version": "0.5.5",
4 4
   "private": true,
5 5
   "scripts": {
6 6
     "start": "node node_modules/react-native/local-cli/cli.js start",

+ 4
- 2
src/README.md 查看文件

@@ -1,4 +1,4 @@
1
-# react-native-fetch-blob [![npm version](https://img.shields.io/badge/npm package-0.5.3-brightgreen.svg)](https://badge.fury.io/js/react-native-fetch-blob) ![](https://img.shields.io/badge/PR-Welcome-brightgreen.svg) ![](https://img.shields.io/badge/in progress-0.6.0-yellow.svg)
1
+# react-native-fetch-blob [![npm version](https://img.shields.io/badge/npm package-0.5.5-brightgreen.svg)](https://badge.fury.io/js/react-native-fetch-blob) ![](https://img.shields.io/badge/PR-Welcome-brightgreen.svg) ![](https://img.shields.io/badge/in progress-0.6.0-yellow.svg)
2 2
 
3 3
 A module provides upload, download, and files access API. Supports file stream read/write for process large files.
4 4
 
@@ -26,7 +26,7 @@ This update is `backward-compatible` generally you don't have to change existing
26 26
  * [File access](#user-content-file-access)
27 27
  * [File stream](#user-content-file-stream)
28 28
  * [Manage cached files](#user-content-manage-cached-files)
29
- * [Self-Signed SSL Server](#user-content-selfsigned-ssl-server)
29
+ * [Self-Signed SSL Server](#user-content-self-signed-ssl-server)
30 30
 * [API](#user-content-api)
31 31
  * [config](#user-content-configoptionsrnfetchblobconfigfetch)
32 32
  * [fetch](#user-content-fetchmethod-url-headers-bodypromisefetchblobresponse)
@@ -847,6 +847,8 @@ A `session` is an object that helps you manage files. It simply maintains a list
847 847
 
848 848
 | Version | |
849 849
 |---|---|
850
+| 0.5.5 | Remove work in progress code added in 0.5.2 which may cause memory leaks. |
851
+| 0.5.4 | Fix #30 #31 build build error, and improve memory efficiency. |
850 852
 | 0.5.3 | Add API for access untrusted SSL server |
851 853
 | 0.5.2 | Fix improper url params bug [#26](https://github.com/wkh237/react-native-fetch-blob/issues/26) and change IOS HTTP implementation from NSURLConnection to NSURLSession |
852 854
 | 0.5.0 | Upload/download with direct access to file storage, and also added file access APIs |

+ 2
- 0
src/ios/RNFetchBlob.xcodeproj/project.pbxproj 查看文件

@@ -233,6 +233,7 @@
233 233
 			isa = XCBuildConfiguration;
234 234
 			buildSettings = {
235 235
 				ALWAYS_SEARCH_USER_PATHS = NO;
236
+				GCC_INPUT_FILETYPE = automatic;
236 237
 				HEADER_SEARCH_PATHS = (
237 238
 					"$(inherited)",
238 239
 					"$(SRCROOT)/Libraries/**",
@@ -253,6 +254,7 @@
253 254
 			isa = XCBuildConfiguration;
254 255
 			buildSettings = {
255 256
 				ALWAYS_SEARCH_USER_PATHS = NO;
257
+				GCC_INPUT_FILETYPE = automatic;
256 258
 				HEADER_SEARCH_PATHS = (
257 259
 					"$(inherited)",
258 260
 					"$(SRCROOT)/Libraries/**",

+ 2
- 0
src/ios/RNFetchBlob/RNFetchBlob.m 查看文件

@@ -130,6 +130,7 @@ RCT_EXPORT_METHOD(fetchBlobForm:(NSDictionary *)options
130 130
         // send HTTP request
131 131
         RNFetchBlobNetwork * utils = [[RNFetchBlobNetwork alloc] init];
132 132
         [utils sendRequest:options bridge:self.bridge taskId:taskId withRequest:request callback:callback];
133
+        utils = nil;
133 134
     });
134 135
 }
135 136
 
@@ -178,6 +179,7 @@ RCT_EXPORT_METHOD(fetchBlob:(NSDictionary *)options
178 179
         // send HTTP request
179 180
         RNFetchBlobNetwork * utils = [[RNFetchBlobNetwork alloc] init];
180 181
         [utils sendRequest:options bridge:self.bridge taskId:taskId withRequest:request callback:callback];
182
+        utils = nil;
181 183
     });
182 184
 }
183 185
 

+ 16
- 10
src/ios/RNFetchBlobFS.m 查看文件

@@ -258,19 +258,18 @@ void runOnMainQueueWithoutDeadlocking(void (^block)(void))
258 258
             // read stream incoming chunk
259 259
         case NSStreamEventHasBytesAvailable:
260 260
         {
261
-            NSMutableData * chunkData = [[NSMutableData data] init];
261
+            NSMutableData * chunkData = [[NSMutableData alloc] init];
262 262
             NSInteger chunkSize = 4096;
263 263
             if([[self.encoding lowercaseString] isEqualToString:@"base64"])
264 264
                 chunkSize = 4095;
265 265
             if(self.bufferSize > 0)
266 266
                 chunkSize = self.bufferSize;
267
-            uint8_t buf[chunkSize];
267
+            uint8_t * buf = (uint8_t *)malloc(chunkSize);
268 268
             unsigned int len = 0;
269
-            
270 269
             len = [(NSInputStream *)stream read:buf maxLength:chunkSize];
271 270
             // still have data in stream
272 271
             if(len) {
273
-                [chunkData appendBytes:(const void *)buf length:len];
272
+                [chunkData appendBytes:buf length:len];
274 273
                 // dispatch data event
275 274
                 NSString * encodedChunk = [NSString alloc];
276 275
                 if( [[self.encoding lowercaseString] isEqualToString:@"utf8"] ) {
@@ -286,29 +285,33 @@ void runOnMainQueueWithoutDeadlocking(void (^block)(void))
286 285
                         NSInteger byteLen = chunkData.length/sizeof(uint8_t);
287 286
                         for (int i = 0; i < byteLen; i++)
288 287
                         {
289
-                            uint8_t * byteFromArray = chunkData.bytes;
290 288
                             NSInteger val = bytePtr[i];
291 289
                             if(i+1 < byteLen)
292 290
                                 asciiStr = [asciiStr stringByAppendingFormat:@"%d,", val];
293 291
                             else
294 292
                                 asciiStr = [asciiStr stringByAppendingFormat:@"%d", val];
295 293
                         }
294
+                        free(bytePtr);
296 295
                     }
297 296
                     asciiStr = [asciiStr stringByAppendingString:@"]"];
298 297
                     [self.bridge.eventDispatcher
299 298
                      sendDeviceEventWithName:streamEventCode
300
-                     body:@{
301
-                            @"event": FS_EVENT_DATA,
302
-                            @"detail": asciiStr
299
+                     body: @{
300
+                             @"event": FS_EVENT_DATA,
301
+                             @"detail": asciiStr
303 302
                             }
304 303
                      ];
304
+                    free(buf);
305
+                    asciiStr = nil;
306
+                    buf = nil;
307
+                    chunkData = nil;
305 308
                     return;
306 309
                 }
307 310
                 // convert byte array to base64 data chunks
308 311
                 else if ( [[self.encoding lowercaseString] isEqualToString:@"base64"] ) {
309 312
                     encodedChunk = [chunkData base64EncodedStringWithOptions:0];
310 313
                 }
311
-                // unknown encoding, send erro event
314
+                // unknown encoding, send error event
312 315
                 else {
313 316
                     [self.bridge.eventDispatcher
314 317
                      sendDeviceEventWithName:streamEventCode
@@ -327,7 +330,8 @@ void runOnMainQueueWithoutDeadlocking(void (^block)(void))
327 330
                         @"detail": encodedChunk
328 331
                         }
329 332
                  ];
330
-                
333
+                chunkData = nil;
334
+                free(buf);
331 335
             }
332 336
             // end of stream
333 337
             else {
@@ -338,6 +342,8 @@ void runOnMainQueueWithoutDeadlocking(void (^block)(void))
338 342
                         @"detail": @""
339 343
                         }
340 344
                  ];
345
+                chunkData = nil;
346
+                free(buf);
341 347
             }
342 348
             break;
343 349
         }

+ 3
- 3
src/ios/RNFetchBlobNetwork.h 查看文件

@@ -21,12 +21,12 @@ typedef void(^DataTaskCompletionHander) (NSData * _Nullable resp, NSURLResponse
21 21
 @property (nonatomic) int expectedBytes;
22 22
 @property (nonatomic) int receivedBytes;
23 23
 @property (nullable, nonatomic) NSMutableData * respData;
24
-@property (nullable, nonatomic) RCTResponseSenderBlock callback;
24
+@property (strong, nonatomic) RCTResponseSenderBlock callback;
25 25
 @property (nullable, nonatomic) RCTBridge * bridge;
26 26
 @property (nullable, nonatomic) NSDictionary * options;
27 27
 @property (nullable, nonatomic) RNFetchBlobFS * fileStream;
28
-@property (nullable, nonatomic) CompletionHander fileTaskCompletionHandler;
29
-@property (nullable, nonatomic) DataTaskCompletionHander dataTaskCompletionHandler;
28
+//@property (strong, nonatomic) CompletionHander fileTaskCompletionHandler;
29
+//@property (strong, nonatomic) DataTaskCompletionHander dataTaskCompletionHandler;
30 30
 @property (nullable, nonatomic) NSError * error;
31 31
 
32 32
 

+ 26
- 22
src/ios/RNFetchBlobNetwork.m 查看文件

@@ -32,8 +32,8 @@ NSOperationQueue *taskQueue;
32 32
 @synthesize callback;
33 33
 @synthesize bridge;
34 34
 @synthesize options;
35
-@synthesize fileTaskCompletionHandler;
36
-@synthesize dataTaskCompletionHandler;
35
+//@synthesize fileTaskCompletionHandler;
36
+//@synthesize dataTaskCompletionHandler;
37 37
 @synthesize error;
38 38
 
39 39
 
@@ -88,7 +88,8 @@ NSOperationQueue *taskQueue;
88 88
     // file will be stored at a specific path
89 89
     if( path != nil) {
90 90
         
91
-        self.fileTaskCompletionHandler = ^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) {
91
+//        self.fileTaskCompletionHandler = ;
92
+        NSURLSessionDownloadTask * task = [session downloadTaskWithRequest:req completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) {
92 93
             if(error != nil) {
93 94
                 callback(@[[error localizedDescription]]);
94 95
                 return;
@@ -102,14 +103,16 @@ NSOperationQueue *taskQueue;
102 103
                 return;
103 104
             }
104 105
             callback(@[[NSNull null], path]);
105
-        };
106
-        NSURLSessionDownloadTask * task = [session downloadTaskWithRequest:req completionHandler:fileTaskCompletionHandler];
106
+            // prevent memory leaks
107
+            self.respData = nil;
108
+        }];
107 109
         [task resume];
108 110
     }
109 111
     // file will be stored at tmp path
110 112
     else if ( [self.options valueForKey:CONFIG_USE_TEMP]!= nil ) {
111 113
         
112
-        self.fileTaskCompletionHandler = ^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) {
114
+//        self.fileTaskCompletionHandler;
115
+        NSURLSessionDownloadTask * task = [session downloadTaskWithRequest:req completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) {
113 116
             if(error != nil) {
114 117
                 callback(@[[error localizedDescription]]);
115 118
                 return;
@@ -124,13 +127,15 @@ NSOperationQueue *taskQueue;
124 127
                 return;
125 128
             }
126 129
             callback(@[[NSNull null], tmpPath]);
127
-        };
128
-        NSURLSessionDownloadTask * task = [session downloadTaskWithRequest:req completionHandler:fileTaskCompletionHandler];
130
+            // prevent memory leaks
131
+            self.respData = nil;
132
+        }];
129 133
         [task resume];
130 134
     }
131 135
     // base64 response
132 136
     else {
133
-        self.dataTaskCompletionHandler = ^(NSData * _Nullable resp, NSURLResponse * _Nullable response, NSError * _Nullable error) {
137
+//        self.dataTaskCompletionHandler = ;
138
+        NSURLSessionDataTask * task = [session dataTaskWithRequest:req completionHandler:^(NSData * _Nullable resp, NSURLResponse * _Nullable response, NSError * _Nullable error) {
134 139
             if(error != nil) {
135 140
                 callback(@[[error localizedDescription]]);
136 141
                 return;
@@ -138,8 +143,7 @@ NSOperationQueue *taskQueue;
138 143
             else {
139 144
                 callback(@[[NSNull null], [resp base64EncodedStringWithOptions:0]]);
140 145
             }
141
-        };
142
-        NSURLSessionDataTask * task = [session dataTaskWithRequest:req completionHandler:dataTaskCompletionHandler];
146
+        }];
143 147
         [task resume];
144 148
     }
145 149
 }
@@ -205,17 +209,17 @@ NSOperationQueue *taskQueue;
205 209
     
206 210
 }
207 211
 
208
-- (void) URLSessionDidFinishEventsForBackgroundURLSession:(NSURLSession *)session
209
-{
210
-    if(self.dataTaskCompletionHandler != nil)
211
-    {
212
-        dataTaskCompletionHandler(self.respData, nil, error);
213
-    }
214
-    else if(self.fileTaskCompletionHandler != nil)
215
-    {
216
-        fileTaskCompletionHandler(nil, nil, self.error);
217
-    }
218
-}
212
+//- (void) URLSessionDidFinishEventsForBackgroundURLSession:(NSURLSession *)session
213
+//{
214
+//    if(self.dataTaskCompletionHandler != nil)
215
+//    {
216
+//        dataTaskCompletionHandler(self.respData, nil, error);
217
+//    }
218
+//    else if(self.fileTaskCompletionHandler != nil)
219
+//    {
220
+//        fileTaskCompletionHandler(nil, nil, self.error);
221
+//    }
222
+//}
219 223
 
220 224
 - (void) URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential * _Nullable))completionHandler
221 225
 {

+ 1
- 1
src/package.json 查看文件

@@ -1,6 +1,6 @@
1 1
 {
2 2
   "name": "react-native-fetch-blob",
3
-  "version": "0.5.3",
3
+  "version": "0.5.5",
4 4
   "description": "A module provides upload, download, and files access API. Supports file stream read/write for process large files.",
5 5
   "main": "index.js",
6 6
   "scripts": {