瀏覽代碼

Merge branch 'master' of https://github.com/joltup/rn-fetch-blob into hash-fix

# Conflicts:
#	android/src/main/java/com/RNFetchBlob/RNFetchBlobFS.java
Ankit Makwana 5 年之前
父節點
當前提交
fc7ae6cac8

+ 3
- 3
README.md 查看文件

@@ -20,7 +20,7 @@ rn-fetch-blob version 0.10.16 is only compatible with react native 0.60 and up.
20 20
 * [Installation](#user-content-installation)
21 21
 * [HTTP Data Transfer](#user-content-http-data-transfer)
22 22
  * [Regular Request](#user-content-regular-request)
23
- * [Download file](#user-content-download-example--fetch-files-that-needs-authorization-token)
23
+ * [Download file](#download-example-fetch-files-that-need-authorization-token)
24 24
  * [Upload file](#user-content-upload-example--dropbox-files-upload-api)
25 25
  * [Multipart/form upload](#user-content-multipartform-data-example--post-form-data-with-file-and-data)
26 26
  * [Upload/Download progress](#user-content-uploaddownload-progress)
@@ -79,7 +79,7 @@ If automatically linking doesn't work for you, see instructions on [manually lin
79 79
 For 0.29.2+ projects, simply link native packages via the following command (note: rnpm has been merged into react-native)
80 80
 
81 81
 ```
82
-react-native link
82
+react-native link rn-fetch-blob
83 83
 ```
84 84
 
85 85
 As for projects < 0.29 you need `rnpm` to link native packages
@@ -91,7 +91,7 @@ rnpm link
91 91
 Optionally, use the following command to add Android permissions to `AndroidManifest.xml` automatically
92 92
 
93 93
 ```sh
94
-RNFB_ANDROID_PERMISSIONS=true react-native link
94
+RNFB_ANDROID_PERMISSIONS=true react-native link rn-fetch-blob
95 95
 ```
96 96
 
97 97
 pre 0.29 projects

+ 5
- 1
android/src/main/java/com/RNFetchBlob/RNFetchBlob.java 查看文件

@@ -118,7 +118,11 @@ public class RNFetchBlob extends ReactContextBaseJavaModule {
118 118
 
119 119
                 // Set flag to give temporary permission to external app to use FileProvider
120 120
                 intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
121
+                 // All the activity to be opened outside of an activity
122
+                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
121 123
 
124
+                // All the activity to be opened outside of an activity
125
+                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
122 126
                 // Validate that the device can open the file
123 127
                 PackageManager pm = getCurrentActivity().getPackageManager();
124 128
                 if (intent.resolveActivity(pm) != null) {
@@ -409,4 +413,4 @@ public class RNFetchBlob extends ReactContextBaseJavaModule {
409 413
     public void getSDCardApplicationDir(Promise promise) {
410 414
         RNFetchBlobFS.getSDCardApplicationDir(this.getReactApplicationContext(), promise);
411 415
     }
412
-}
416
+}

+ 37
- 24
android/src/main/java/com/RNFetchBlob/RNFetchBlobFS.java 查看文件

@@ -21,9 +21,7 @@ import com.facebook.react.bridge.WritableMap;
21 21
 import com.facebook.react.modules.core.DeviceEventManagerModule;
22 22
 
23 23
 import java.io.*;
24
-import java.nio.ByteBuffer;
25 24
 import java.nio.charset.Charset;
26
-import java.nio.charset.CharsetEncoder;
27 25
 import java.security.MessageDigest;
28 26
 import java.util.ArrayList;
29 27
 import java.util.HashMap;
@@ -69,32 +67,45 @@ class RNFetchBlobFS {
69 67
                 }
70 68
             }
71 69
 
72
-            FileOutputStream fout = new FileOutputStream(f, append);
73 70
             // write data from a file
74 71
             if(encoding.equalsIgnoreCase(RNFetchBlobConst.DATA_ENCODE_URI)) {
75 72
                 String normalizedData = normalizePath(data);
76 73
                 File src = new File(normalizedData);
77 74
                 if (!src.exists()) {
78 75
                     promise.reject("ENOENT", "No such file '" + path + "' " + "('" + normalizedData + "')");
79
-                    fout.close();
80 76
                     return;
81 77
                 }
82
-                FileInputStream fin = new FileInputStream(src);
83 78
                 byte[] buffer = new byte [10240];
84 79
                 int read;
85 80
                 written = 0;
86
-                while((read = fin.read(buffer)) > 0) {
87
-                    fout.write(buffer, 0, read);
88
-                    written += read;
81
+                FileInputStream fin = null;
82
+                FileOutputStream fout = null;
83
+                try {
84
+                    fin = new FileInputStream(src);
85
+                    fout = new FileOutputStream(f, append);
86
+                    while ((read = fin.read(buffer)) > 0) {
87
+                        fout.write(buffer, 0, read);
88
+                        written += read;
89
+                    }
90
+                } finally {
91
+                    if (fin != null) {
92
+                        fin.close();
93
+                    }
94
+                    if (fout != null) {
95
+                        fout.close();
96
+                    }
89 97
                 }
90
-                fin.close();
91 98
             }
92 99
             else {
93 100
                 byte[] bytes = stringToBytes(data, encoding);
94
-                fout.write(bytes);
95
-                written = bytes.length;
101
+                FileOutputStream fout = new FileOutputStream(f, append);
102
+                try {
103
+                    fout.write(bytes);
104
+                    written = bytes.length;
105
+                } finally {
106
+                    fout.close();
107
+                }
96 108
             }
97
-            fout.close();
98 109
             promise.resolve(written);
99 110
         } catch (FileNotFoundException e) {
100 111
             // According to https://docs.oracle.com/javase/7/docs/api/java/io/FileOutputStream.html
@@ -129,12 +140,15 @@ class RNFetchBlobFS {
129 140
             }
130 141
 
131 142
             FileOutputStream os = new FileOutputStream(f, append);
132
-            byte[] bytes = new byte[data.size()];
133
-            for(int i=0;i<data.size();i++) {
134
-                bytes[i] = (byte) data.getInt(i);
143
+            try {
144
+                byte[] bytes = new byte[data.size()];
145
+                for (int i = 0; i < data.size(); i++) {
146
+                    bytes[i] = (byte) data.getInt(i);
147
+                }
148
+                os.write(bytes);
149
+            } finally {
150
+                os.close();
135 151
             }
136
-            os.write(bytes);
137
-            os.close();
138 152
             promise.resolve(data.size());
139 153
         } catch (FileNotFoundException e) {
140 154
             // According to https://docs.oracle.com/javase/7/docs/api/java/io/FileOutputStream.html
@@ -325,9 +339,7 @@ class RNFetchBlobFS {
325 339
             boolean error = false;
326 340
 
327 341
             if (encoding.equalsIgnoreCase("utf8")) {
328
-                CharsetEncoder encoder = Charset.forName("UTF-8").newEncoder();
329 342
                 while ((cursor = fs.read(buffer)) != -1) {
330
-                    encoder.encode(ByteBuffer.wrap(buffer).asCharBuffer());
331 343
                     String chunk = new String(buffer, 0, cursor);
332 344
                     emitStreamEvent(streamId, "data", chunk);
333 345
                     if(tick > 0)
@@ -523,7 +535,7 @@ class RNFetchBlobFS {
523 535
     static void mkdir(String path, Promise promise) {
524 536
         File dest = new File(path);
525 537
         if(dest.exists()) {
526
-            promise.reject("EEXIST", dest.isDirectory() ? "Folder" : "File" + " '" + path + "' already exists");
538
+            promise.reject("EEXIST", (dest.isDirectory() ? "Folder" : "File") + " '" + path + "' already exists");
527 539
             return;
528 540
         }
529 541
         try {
@@ -876,12 +888,13 @@ class RNFetchBlobFS {
876 888
             MessageDigest md = MessageDigest.getInstance(algorithms.get(algorithm));
877 889
 
878 890
             FileInputStream inputStream = new FileInputStream(path);
879
-            byte[] buffer = new byte[(int)file.length()];
891
+            int chunkSize = 4096 * 256; // 1Mb
892
+            byte[] buffer = new byte[chunkSize];
880 893
 
881 894
             if(file.length() != 0) {
882
-                int read;
883
-                while ((read = inputStream.read(buffer)) != -1) {
884
-                    md.update(buffer, 0, read);
895
+                int bytesRead;
896
+                while ((bytesRead = inputStream.read(buffer)) != -1) {
897
+                    md.update(buffer, 0, bytesRead);
885 898
                 }
886 899
             }
887 900
 

+ 45
- 45
android/src/main/java/com/RNFetchBlob/RNFetchBlobReq.java 查看文件

@@ -36,10 +36,6 @@ import java.net.MalformedURLException;
36 36
 import java.net.SocketException;
37 37
 import java.net.SocketTimeoutException;
38 38
 import java.net.URL;
39
-import java.nio.ByteBuffer;
40
-import java.nio.charset.CharacterCodingException;
41
-import java.nio.charset.Charset;
42
-import java.nio.charset.CharsetEncoder;
43 39
 import java.security.KeyStore;
44 40
 import java.util.ArrayList;
45 41
 import java.util.Arrays;
@@ -502,44 +498,38 @@ public class RNFetchBlobReq extends BroadcastReceiver implements Runnable {
502 498
                         // encoding will somehow break the UTF8 string format, to encode UTF8
503 499
                         // string correctly, we should do URL encoding before BASE64.
504 500
                         byte[] b = resp.body().bytes();
505
-                        CharsetEncoder encoder = Charset.forName("UTF-8").newEncoder();
506 501
                         if(responseFormat == ResponseFormat.BASE64) {
507 502
                             callback.invoke(null, RNFetchBlobConst.RNFB_RESPONSE_BASE64, android.util.Base64.encodeToString(b, Base64.NO_WRAP));
508 503
                             return;
509 504
                         }
510
-                        try {
511
-                            encoder.encode(ByteBuffer.wrap(b).asCharBuffer());
512
-                            // if the data contains invalid characters the following lines will be
513
-                            // skipped.
514
-                            String utf8 = new String(b);
515
-                            callback.invoke(null, RNFetchBlobConst.RNFB_RESPONSE_UTF8, utf8);
516
-                        }
517
-                        // This usually mean the data is contains invalid unicode characters, it's
518
-                        // binary data
519
-                        catch(CharacterCodingException ignored) {
520
-                            if(responseFormat == ResponseFormat.UTF8) {
521
-                                callback.invoke(null, RNFetchBlobConst.RNFB_RESPONSE_UTF8, "");
522
-                            }
523
-                            else {
524
-                                callback.invoke(null, RNFetchBlobConst.RNFB_RESPONSE_BASE64, android.util.Base64.encodeToString(b, Base64.NO_WRAP));
525
-                            }
526
-                        }
505
+                        String utf8 = new String(b);
506
+                        callback.invoke(null, RNFetchBlobConst.RNFB_RESPONSE_UTF8, utf8);
527 507
                     }
528 508
                 } catch (IOException e) {
529 509
                     callback.invoke("RNFetchBlob failed to encode response data to BASE64 string.", null);
530 510
                 }
531 511
                 break;
532 512
             case FileStorage:
513
+                ResponseBody responseBody = resp.body();
514
+
533 515
                 try {
534 516
                     // In order to write response data to `destPath` we have to invoke this method.
535 517
                     // It uses customized response body which is able to report download progress
536 518
                     // and write response data to destination path.
537
-                    resp.body().bytes();
519
+                    responseBody.bytes();
538 520
                 } catch (Exception ignored) {
539 521
 //                    ignored.printStackTrace();
540 522
                 }
541
-                this.destPath = this.destPath.replace("?append=true", "");
542
-                callback.invoke(null, RNFetchBlobConst.RNFB_RESPONSE_PATH, this.destPath);
523
+
524
+                RNFetchBlobFileResp rnFetchBlobFileResp = (RNFetchBlobFileResp) responseBody;
525
+
526
+                if(rnFetchBlobFileResp != null && rnFetchBlobFileResp.isDownloadComplete() == false){
527
+                    callback.invoke("RNFetchBlob failed. Download interrupted.", null);
528
+                }
529
+                else {
530
+                    this.destPath = this.destPath.replace("?append=true", "");
531
+                    callback.invoke(null, RNFetchBlobConst.RNFB_RESPONSE_PATH, this.destPath);
532
+                }
543 533
                 break;
544 534
             default:
545 535
                 try {
@@ -666,30 +656,40 @@ public class RNFetchBlobReq extends BroadcastReceiver implements Runnable {
666 656
                 DownloadManager dm = (DownloadManager) appCtx.getSystemService(Context.DOWNLOAD_SERVICE);
667 657
                 dm.query(query);
668 658
                 Cursor c = dm.query(query);
669
-
659
+                // #236 unhandled null check for DownloadManager.query() return value
660
+                if (c == null) {
661
+                    this.callback.invoke("Download manager failed to download from  " + this.url + ". Query was unsuccessful ", null, null);
662
+                    return;
663
+                }
670 664
 
671 665
                 String filePath = null;
672
-                // the file exists in media content database
673
-                if (c.moveToFirst()) {
674
-                    // #297 handle failed request
675
-                    int statusCode = c.getInt(c.getColumnIndex(DownloadManager.COLUMN_STATUS));
676
-                    if(statusCode == DownloadManager.STATUS_FAILED) {
677
-                        this.callback.invoke("Download manager failed to download from  " + this.url + ". Status Code = " + statusCode, null, null);
678
-                        return;
679
-                    }
680
-                    String contentUri = c.getString(c.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI));
681
-                    if ( contentUri != null &&
682
-                            options.addAndroidDownloads.hasKey("mime") &&
683
-                            options.addAndroidDownloads.getString("mime").contains("image")) {
684
-                        Uri uri = Uri.parse(contentUri);
685
-                        Cursor cursor = appCtx.getContentResolver().query(uri, new String[]{android.provider.MediaStore.Images.ImageColumns.DATA}, null, null, null);
686
-                        // use default destination of DownloadManager
687
-                        if (cursor != null) {
688
-                            cursor.moveToFirst();
689
-                            filePath = cursor.getString(0);
690
-                            cursor.close();
666
+                try {    
667
+                    // the file exists in media content database
668
+                    if (c.moveToFirst()) {
669
+                        // #297 handle failed request
670
+                        int statusCode = c.getInt(c.getColumnIndex(DownloadManager.COLUMN_STATUS));
671
+                        if(statusCode == DownloadManager.STATUS_FAILED) {
672
+                            this.callback.invoke("Download manager failed to download from  " + this.url + ". Status Code = " + statusCode, null, null);
673
+                            return;
674
+                        }
675
+                        String contentUri = c.getString(c.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI));
676
+                        if ( contentUri != null &&
677
+                                options.addAndroidDownloads.hasKey("mime") &&
678
+                                options.addAndroidDownloads.getString("mime").contains("image")) {
679
+                            Uri uri = Uri.parse(contentUri);
680
+                            Cursor cursor = appCtx.getContentResolver().query(uri, new String[]{android.provider.MediaStore.Images.ImageColumns.DATA}, null, null, null);
681
+                            // use default destination of DownloadManager
682
+                            if (cursor != null) {
683
+                                cursor.moveToFirst();
684
+                                filePath = cursor.getString(0);
685
+                                cursor.close();
686
+                            }
691 687
                         }
692 688
                     }
689
+                } finally {
690
+                    if (c != null) {
691
+                        c.close();
692
+                    }
693 693
                 }
694 694
 
695 695
                 // When the file is not found in media content database, check if custom path exists

+ 4
- 0
android/src/main/java/com/RNFetchBlob/Response/RNFetchBlobFileResp.java 查看文件

@@ -68,6 +68,10 @@ public class RNFetchBlobFileResp extends ResponseBody {
68 68
         return originalBody.contentLength();
69 69
     }
70 70
 
71
+    public boolean isDownloadComplete() {
72
+        return bytesDownloaded == contentLength();
73
+    }
74
+
71 75
     @Override
72 76
     public BufferedSource source() {
73 77
         ProgressReportingSource countable = new ProgressReportingSource();

+ 18
- 5
android/src/main/java/com/RNFetchBlob/Utils/PathResolver.java 查看文件

@@ -37,12 +37,25 @@ public class PathResolver {
37 37
             }
38 38
             // DownloadsProvider
39 39
             else if (isDownloadsDocument(uri)) {
40
+                try {
41
+                    final String id = DocumentsContract.getDocumentId(uri);
42
+                    //Starting with Android O, this "id" is not necessarily a long (row number),
43
+                    //but might also be a "raw:/some/file/path" URL
44
+                    if (id != null && id.startsWith("raw:/")) {
45
+                        Uri rawuri = Uri.parse(id);
46
+                        String path = rawuri.getPath();
47
+                        return path;
48
+                    }
49
+                    final Uri contentUri = ContentUris.withAppendedId(
50
+                            Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));
40 51
 
41
-                final String id = DocumentsContract.getDocumentId(uri);
42
-                final Uri contentUri = ContentUris.withAppendedId(
43
-                        Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));
44
-
45
-                return getDataColumn(context, contentUri, null, null);
52
+                    return getDataColumn(context, contentUri, null, null);
53
+                }
54
+                catch (Exception ex) {
55
+                    //something went wrong, but android should still be able to handle the original uri by returning null here (see readFile(...))
56
+                    return null;
57
+                }
58
+                
46 59
             }
47 60
             // MediaProvider
48 61
             else if (isMediaDocument(uri)) {

+ 4
- 1
android/src/main/res/xml/provider_paths.xml 查看文件

@@ -6,4 +6,7 @@
6 6
     <files-path
7 7
         name="files-path"
8 8
         path="." /> <!-- Used to access into application data files -->
9
-</paths>
9
+    <cache-path
10
+        name="cache-path"
11
+        path="." /> <!-- Used to access files in cache directory -->
12
+</paths>

+ 14
- 0
fs.js 查看文件

@@ -135,6 +135,19 @@ function pathForAppGroup(groupName: string): Promise {
135 135
   return RNFetchBlob.pathForAppGroup(groupName)
136 136
 }
137 137
 
138
+/**
139
+ * Returns the path for the app group synchronous.
140
+ * @param  {string} groupName Name of app group
141
+ * @return {string} Path of App Group dir
142
+ */
143
+function syncPathAppGroup(groupName: string): string {
144
+  if (Platform.OS === 'ios') {
145
+    return RNFetchBlob.syncPathAppGroup(groupName);
146
+  } else {
147
+    return '';
148
+  }
149
+}
150
+
138 151
 /**
139 152
  * Wrapper method of readStream.
140 153
  * @param  {string} path Path of the file.
@@ -402,6 +415,7 @@ export default {
402 415
   writeFile,
403 416
   appendFile,
404 417
   pathForAppGroup,
418
+  syncPathAppGroup,
405 419
   readFile,
406 420
   hash,
407 421
   exists,

+ 10
- 0
index.d.ts 查看文件

@@ -96,6 +96,7 @@ export interface FetchBlobResponse {
96 96
      */
97 97
     flush(): void;
98 98
     respInfo: RNFetchBlobResponseInfo;
99
+    info(): RNFetchBlobResponseInfo;
99 100
     session(name: string): RNFetchBlobSession | null;
100 101
     /**
101 102
      * Read file content with given encoding, if the response does not contains
@@ -293,6 +294,7 @@ export interface Net {
293 294
     removeCookies(domain?: string): Promise<null>;
294 295
 }
295 296
 
297
+type HashAlgorithm = "md5" | "sha1" | "sha224" | "sha256" | "sha384" | "sha512";
296 298
 export interface FS {
297 299
     RNFetchBlobSession: RNFetchBlobSession;
298 300
 
@@ -316,6 +318,14 @@ export interface FS {
316 318
 
317 319
     ls(path: string): Promise<string[]>;
318 320
 
321
+    /**
322
+     * Read the file from the given path and calculate a cryptographic hash sum over its contents.
323
+     *
324
+     * @param path Path to the file
325
+     * @param algorithm The hash algorithm to use
326
+     */
327
+    hash(path: string, algorithm: HashAlgorithm): Promise<string>;
328
+
319 329
     /**
320 330
      * Create file stream from file at `path`.
321 331
      * @param  path   The file path.

+ 7
- 0
index.js 查看文件

@@ -228,8 +228,14 @@ function fetch(...args:any):Promise {
228 228
     return fetchFile(options, method, url, headers, body)
229 229
   }
230 230
 
231
+  let promiseResolve;
232
+  let promiseReject;
233
+
231 234
   // from remote HTTP(S)
232 235
   let promise = new Promise((resolve, reject) => {
236
+    promiseResolve = resolve;
237
+    promiseReject = reject;
238
+
233 239
     let nativeMethodName = Array.isArray(body) ? 'fetchBlobForm' : 'fetchBlob'
234 240
 
235 241
     // on progress event listener
@@ -370,6 +376,7 @@ function fetch(...args:any):Promise {
370 376
     subscriptionUpload.remove()
371 377
     stateEvent.remove()
372 378
     RNFetchBlob.cancelRequest(taskId, fn)
379
+    promiseReject(new Error("canceled"))
373 380
   }
374 381
   promise.taskId = taskId
375 382
 

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

@@ -68,9 +68,14 @@ RCT_EXPORT_MODULE();
68 68
 - (NSDictionary *)constantsToExport
69 69
 {
70 70
     return @{
71
-             @"MainBundleDir" : [RNFetchBlobFS getMainBundleDir],
71
+             @"CacheDir" : [RNFetchBlobFS getCacheDir],
72 72
              @"DocumentDir": [RNFetchBlobFS getDocumentDir],
73
-             @"CacheDir" : [RNFetchBlobFS getCacheDir]
73
+             @"DownloadDir" : [RNFetchBlobFS getDownloadDir],
74
+             @"LibraryDir" : [RNFetchBlobFS getLibraryDir],
75
+             @"MainBundleDir" : [RNFetchBlobFS getMainBundleDir],
76
+             @"MovieDir" : [RNFetchBlobFS getMovieDir],
77
+             @"MusicDir" : [RNFetchBlobFS getMusicDir],
78
+             @"PictureDir" : [RNFetchBlobFS getPictureDir],
74 79
              };
75 80
 }
76 81
 
@@ -228,6 +233,18 @@ RCT_EXPORT_METHOD(pathForAppGroup:(NSString *)groupName
228 233
     }
229 234
 }
230 235
 
236
+#pragma mark - fs.syncPathAppGroup
237
+RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(syncPathAppGroup:(NSString *)groupName) {
238
+    NSURL *pathUrl = [[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:groupName];
239
+    NSString *path = [pathUrl path];
240
+
241
+    if(path) {
242
+        return path;
243
+    } else {
244
+        return @"";
245
+    }
246
+}
247
+
231 248
 #pragma mark - fs.exists
232 249
 RCT_EXPORT_METHOD(exists:(NSString *)path callback:(RCTResponseSenderBlock)callback) {
233 250
     [RNFetchBlobFS exists:path callback:callback];

+ 7
- 2
ios/RNFetchBlobFS.h 查看文件

@@ -46,10 +46,15 @@
46 46
 @property (nonatomic) BOOL appendData;
47 47
 
48 48
 // get dirs
49
-+ (NSString *) getMainBundleDir;
50
-+ (NSString *) getTempPath;
51 49
 + (NSString *) getCacheDir;
52 50
 + (NSString *) getDocumentDir;
51
++ (NSString *) getDownloadDir;
52
++ (NSString *) getLibraryDir;
53
++ (NSString *) getMainBundleDir;
54
++ (NSString *) getMovieDir;
55
++ (NSString *) getMusicDir;
56
++ (NSString *) getPictureDir;
57
++ (NSString *) getTempPath;
53 58
 + (NSString *) getTempPath:(NSString*)taskId withExtension:(NSString *)ext;
54 59
 + (NSString *) getPathOfAsset:(NSString *)assetURI;
55 60
 + (NSString *) getPathForAppGroup:(NSString *)groupName;

+ 8
- 0
ios/RNFetchBlobFS.m 查看文件

@@ -104,6 +104,14 @@ NSMutableDictionary *fileStreams = nil;
104 104
     return [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
105 105
 }
106 106
 
107
++ (NSString *) getDownloadDir {
108
+    return [NSSearchPathForDirectoriesInDomains(NSDownloadsDirectory, NSUserDomainMask, YES) firstObject];
109
+}
110
+
111
++ (NSString *) getLibraryDir {
112
+    return [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) firstObject];
113
+}
114
+
107 115
 + (NSString *) getMusicDir {
108 116
     return [NSSearchPathForDirectoriesInDomains(NSMusicDirectory, NSUserDomainMask, YES) firstObject];
109 117
 }

+ 1
- 1
ios/RNFetchBlobReqBuilder.m 查看文件

@@ -69,7 +69,7 @@
69 69
                 [mheaders setValue:[NSString stringWithFormat:@"%lu",[postData length]] forKey:@"Content-Length"];
70 70
                 [mheaders setValue:@"100-continue" forKey:@"Expect"];
71 71
                 // appaned boundary to content-type
72
-                [mheaders setValue:[NSString stringWithFormat:@"multipart/form-data; charset=utf-8; boundary=%@", boundary] forKey:@"content-type"];
72
+                [mheaders setValue:[NSString stringWithFormat:@"multipart/form-data; boundary=%@", boundary] forKey:@"content-type"];
73 73
                 [request setHTTPMethod: method];
74 74
                 [request setAllHTTPHeaderFields:mheaders];
75 75
                 onComplete(request, [formData length]);

+ 1
- 6
package.json 查看文件

@@ -1,6 +1,6 @@
1 1
 {
2 2
   "name": "rn-fetch-blob",
3
-  "version": "0.10.16",
3
+  "version": "0.11.1",
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": {
@@ -21,11 +21,6 @@
21 21
     "filestream",
22 22
     "image header"
23 23
   ],
24
-  "rnpm": {
25
-    "commands": {
26
-      "prelink": "node ./node_modules/rn-fetch-blob/scripts/prelink.js"
27
-    }
28
-  },
29 24
   "repository": {
30 25
     "url": "https://github.com/joltup/rn-fetch-blob.git"
31 26
   },

+ 7
- 0
react-native.config.js 查看文件

@@ -0,0 +1,7 @@
1
+module.exports = {
2
+  dependency: {
3
+    hooks: {
4
+      prelink: 'node ./node_modules/rn-fetch-blob/scripts/prelink.js',
5
+    },
6
+  },
7
+};

+ 7
- 4
rn-fetch-blob.podspec 查看文件

@@ -1,11 +1,14 @@
1
+require "json"
2
+package = JSON.parse(File.read('package.json'))
3
+
1 4
 Pod::Spec.new do |s|
2
-  s.name             = "rn-fetch-blob"
3
-  s.version          = "0.10.16"
4
-  s.summary          = "A project committed to make file acess and data transfer easier, effiecient for React Native developers."
5
+  s.name             = package['name']
6
+  s.version          = package['version']
7
+  s.summary          = package['description']
5 8
   s.requires_arc = true
6 9
   s.license      = 'MIT'
7 10
   s.homepage     = 'n/a'
8
-  s.source       = { :git => "https://github.com/joltup/rn-fetch-blob", :tag => 'v0.10.16'}
11
+  s.source       = { :git => "https://github.com/joltup/rn-fetch-blob" }
9 12
   s.author       = 'Joltup'
10 13
   s.source_files = 'ios/**/*.{h,m}'
11 14
   s.platform     = :ios, "8.0"