itinance / react-native-fs

Native filesystem access for react-native
MIT License
4.89k stars 954 forks source link

Two issues with uploading/downloading #1234

Open gontovnik opened 2 weeks ago

gontovnik commented 2 weeks ago

Hi! 👋

Firstly, thanks for your work on this project! 🙂

Today I used patch-package to patch react-native-fs@2.20.0 for the project I'm working on.

There are two fixes:

  1. The issue is related to subscription removal upon download/upload failure.
  2. Could not valuable for the community, but for our case we had to use uploadTaskWithStreamedRequest instead of the dataTaskWithRequest, so that the upload can happen in the background too.

Here is the diff that solved my problem:

diff --git a/node_modules/react-native-fs/FS.common.js b/node_modules/react-native-fs/FS.common.js
index 62b7ba7..ad9d507 100755
--- a/node_modules/react-native-fs/FS.common.js
+++ b/node_modules/react-native-fs/FS.common.js
@@ -538,10 +538,10 @@ var RNFS = {
       promise: RNFSManager.downloadFile(bridgeOptions).then(res => {
         subscriptions.forEach(sub => sub.remove());
         return res;
+      }).catch(e => {
+        subscriptions.forEach(sub => sub.remove());
+        throw e;
       })
-        .catch(e => {
-          return Promise.reject(e);
-        })
     };
   },

@@ -594,6 +594,9 @@ var RNFS = {
       promise: RNFSManager.uploadFiles(bridgeOptions).then(res => {
         subscriptions.forEach(sub => sub.remove());
         return res;
+      }).catch(e => {
+        subscriptions.forEach(sub => sub.remove());
+        throw e;
       })
     };
   },
diff --git a/node_modules/react-native-fs/Uploader.h b/node_modules/react-native-fs/Uploader.h
index e75cef0..bbb0d21 100644
--- a/node_modules/react-native-fs/Uploader.h
+++ b/node_modules/react-native-fs/Uploader.h
@@ -24,7 +24,7 @@ typedef void (^UploadProgressCallback)(NSNumber*, NSNumber*);

 @end

-@interface RNFSUploader : NSObject <NSURLConnectionDelegate>
+@interface RNFSUploader : NSObject <NSURLConnectionDelegate, NSURLSessionDelegate, NSURLSessionDataDelegate>

 - (void)uploadFiles:(RNFSUploadParams*)params;
 - (void)stopUpload;
diff --git a/node_modules/react-native-fs/Uploader.m b/node_modules/react-native-fs/Uploader.m
index 9463c81..cbf1136 100644
--- a/node_modules/react-native-fs/Uploader.m
+++ b/node_modules/react-native-fs/Uploader.m
@@ -102,12 +102,10 @@
   // send request
   [req setHTTPBody:reqBody];

-  NSURLSessionConfiguration *sessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration];
-  NSURLSession *session = [NSURLSession sessionWithConfiguration:sessionConfiguration delegate:(id)self delegateQueue:[NSOperationQueue mainQueue]];
-  _task = [session dataTaskWithRequest:req completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
-      NSString * str = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
-      return self->_params.completeCallback(str, response);
-  }];
+  NSString *identifier = [NSString stringWithFormat:@"RNFS.Uploader.%@", [NSUUID UUID].UUIDString];
+  NSURLSessionConfiguration *sessionConfiguration = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:identifier];
+  NSURLSession *session = [NSURLSession sessionWithConfiguration:sessionConfiguration delegate:self delegateQueue:[NSOperationQueue mainQueue]];
+  _task = [session uploadTaskWithStreamedRequest:req];
   [_task resume];
   [session finishTasksAndInvalidate];
   if (_params.beginCallback) {
@@ -147,6 +145,12 @@
   }
 }

+- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data
+{
+  NSString *str = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
+  _params.completeCallback(str, dataTask.response);
+}
+
 - (void)stopUpload
 {
   [_task cancel];

This issue body was partially generated by patch-package.