react-native-blob-util 0.21.2 → 0.22.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (98) hide show
  1. package/.eslintrc.js +56 -56
  2. package/LICENSE +21 -21
  3. package/Migration.md +41 -41
  4. package/NuGet.config +11 -0
  5. package/README.md +1104 -1095
  6. package/android/gradle.properties +1 -1
  7. package/android/src/main/AndroidManifest.xml +37 -37
  8. package/android/src/main/java/com/ReactNativeBlobUtil/ReactNativeBlobUtilConfig.java +57 -57
  9. package/android/src/main/java/com/ReactNativeBlobUtil/ReactNativeBlobUtilConst.java +20 -20
  10. package/android/src/main/java/com/ReactNativeBlobUtil/ReactNativeBlobUtilFileTransformer.java +9 -9
  11. package/android/src/main/java/com/ReactNativeBlobUtil/ReactNativeBlobUtilImpl.java +431 -431
  12. package/android/src/main/java/com/ReactNativeBlobUtil/ReactNativeBlobUtilProgressConfig.java +39 -39
  13. package/android/src/main/java/com/ReactNativeBlobUtil/ReactNativeBlobUtilReq.java +1014 -1014
  14. package/android/src/main/java/com/ReactNativeBlobUtil/Response/ReactNativeBlobUtilDefaultResp.java +98 -98
  15. package/android/src/main/java/com/ReactNativeBlobUtil/Response/ReactNativeBlobUtilFileResp.java +166 -157
  16. package/android/src/main/java/com/ReactNativeBlobUtil/Utils/FileDescription.java +19 -19
  17. package/android/src/main/java/com/ReactNativeBlobUtil/Utils/FileProvider.java +4 -4
  18. package/android/src/main/java/com/ReactNativeBlobUtil/Utils/MimeType.java +70 -70
  19. package/android/src/main/java/com/ReactNativeBlobUtil/Utils/PathResolver.java +223 -223
  20. package/android/src/main/java/com/ReactNativeBlobUtil/Utils/Tls12SocketFactory.java +68 -68
  21. package/android/src/main/res/values/strings.xml +3 -3
  22. package/android/src/main/res/xml/provider_paths.xml +12 -12
  23. package/android.js +58 -58
  24. package/class/ReactNativeBlobUtilCanceledFetchError.js +9 -9
  25. package/class/ReactNativeBlobUtilFile.js +5 -5
  26. package/class/ReactNativeBlobUtilReadStream.js +84 -84
  27. package/class/ReactNativeBlobUtilSession.js +68 -68
  28. package/class/ReactNativeBlobUtilWriteStream.js +50 -50
  29. package/class/StatefulPromise.js +7 -7
  30. package/codegenSpecs/NativeBlobUtils.js +86 -86
  31. package/components/Fetch.onPress.js +10 -10
  32. package/components/Fetch.when.js +15 -15
  33. package/fetch.js +350 -350
  34. package/fs.js +480 -480
  35. package/index.js +64 -64
  36. package/index.js.flow +192 -192
  37. package/index.web.js +1 -1
  38. package/ios/PrivacyInfo.xcprivacy +28 -28
  39. package/ios/ReactNativeBlobUtil/ReactNativeBlobUtil.h +55 -55
  40. package/ios/ReactNativeBlobUtil/ReactNativeBlobUtil.mm +992 -992
  41. package/ios/ReactNativeBlobUtil.xcodeproj/project.pbxproj +405 -405
  42. package/ios/ReactNativeBlobUtilConst.h +58 -58
  43. package/ios/ReactNativeBlobUtilConst.mm +47 -47
  44. package/ios/ReactNativeBlobUtilFS.h +108 -108
  45. package/ios/ReactNativeBlobUtilFS.mm +1064 -1064
  46. package/ios/ReactNativeBlobUtilFileTransformer.h +23 -23
  47. package/ios/ReactNativeBlobUtilFileTransformer.mm +20 -20
  48. package/ios/ReactNativeBlobUtilNetwork.h +49 -49
  49. package/ios/ReactNativeBlobUtilNetwork.mm +159 -159
  50. package/ios/ReactNativeBlobUtilProgress.h +32 -32
  51. package/ios/ReactNativeBlobUtilProgress.mm +57 -57
  52. package/ios/ReactNativeBlobUtilReqBuilder.h +37 -37
  53. package/ios/ReactNativeBlobUtilReqBuilder.mm +292 -292
  54. package/ios/ReactNativeBlobUtilRequest.h +48 -48
  55. package/ios/ReactNativeBlobUtilRequest.mm +584 -584
  56. package/ios.js +61 -61
  57. package/json-stream.js +42 -42
  58. package/lib/oboe-browser.js +2703 -2703
  59. package/mediacollection.js +36 -36
  60. package/package.json +68 -55
  61. package/polyfill/Blob.js +362 -362
  62. package/polyfill/Event.js +11 -11
  63. package/polyfill/EventTarget.js +78 -78
  64. package/polyfill/Fetch.js +219 -219
  65. package/polyfill/File.js +27 -27
  66. package/polyfill/FileReader.js +91 -91
  67. package/polyfill/ProgressEvent.js +32 -32
  68. package/polyfill/XMLHttpRequest.js +466 -466
  69. package/polyfill/XMLHttpRequestEventTarget.js +126 -126
  70. package/polyfill/index.js +11 -11
  71. package/react-native-blob-util.podspec +48 -48
  72. package/types.js +69 -69
  73. package/utils/log.js +40 -40
  74. package/utils/unicode.js +7 -7
  75. package/utils/uri.js +33 -33
  76. package/utils/uuid.js +4 -4
  77. package/windows/ExperimentalFeatures.props +33 -0
  78. package/windows/README.md +2 -2
  79. package/windows/ReactNativeBlobUtil/PropertySheet.props +15 -15
  80. package/windows/ReactNativeBlobUtil/ReactNativeBlobUtil.cpp +1837 -1701
  81. package/windows/ReactNativeBlobUtil/ReactNativeBlobUtil.def +3 -3
  82. package/windows/ReactNativeBlobUtil/ReactNativeBlobUtil.h +373 -379
  83. package/windows/ReactNativeBlobUtil/ReactNativeBlobUtil.rc +0 -0
  84. package/windows/ReactNativeBlobUtil/ReactNativeBlobUtil.vcxproj +140 -181
  85. package/windows/ReactNativeBlobUtil/ReactNativeBlobUtil.vcxproj.filters +43 -31
  86. package/windows/ReactNativeBlobUtil/ReactPackageProvider.cpp +20 -15
  87. package/windows/ReactNativeBlobUtil/ReactPackageProvider.h +24 -20
  88. package/windows/ReactNativeBlobUtil/ReactPackageProvider.idl +9 -9
  89. package/windows/ReactNativeBlobUtil/codegen/.clang-format +2 -0
  90. package/windows/ReactNativeBlobUtil/codegen/NativeBlobUtilsDataTypes.g.h +42 -0
  91. package/windows/ReactNativeBlobUtil/codegen/NativeBlobUtilsSpec.g.h +353 -0
  92. package/windows/ReactNativeBlobUtil/packages.config +3 -3
  93. package/windows/ReactNativeBlobUtil/packages.lock.json +60 -0
  94. package/windows/ReactNativeBlobUtil/pch.cpp +1 -1
  95. package/windows/ReactNativeBlobUtil/pch.h +30 -4
  96. package/windows/ReactNativeBlobUtil/resource.h +5 -0
  97. package/windows/ReactNativeBlobUtil/targetver.h +8 -0
  98. package/windows/ReactNativeBlobUtil.sln +43 -0
@@ -1,992 +1,992 @@
1
- //
2
- // ReactNativeBlobUtil.m
3
- //
4
- // Created by wkh237 on 2016/4/28.
5
- //
6
-
7
- #import "ReactNativeBlobUtil.h"
8
- #import "ReactNativeBlobUtilFS.h"
9
- #import "ReactNativeBlobUtilNetwork.h"
10
- #import "ReactNativeBlobUtilConst.h"
11
- #import "ReactNativeBlobUtilReqBuilder.h"
12
- #import "ReactNativeBlobUtilProgress.h"
13
-
14
- #if RCT_NEW_ARCH_ENABLED
15
- #import <ReactNativeBlobUtilSpec/ReactNativeBlobUtilSpec.h>
16
- #endif
17
-
18
- dispatch_queue_t commonTaskQueue;
19
- dispatch_queue_t fsQueue;
20
-
21
- ////////////////////////////////////////
22
- //
23
- // Exported native methods
24
- //
25
- ////////////////////////////////////////
26
-
27
- #pragma mark ReactNativeBlobUtil exported methods
28
-
29
- @implementation ReactNativeBlobUtil
30
-
31
- @synthesize filePathPrefix;
32
- @synthesize documentController;
33
- @synthesize bridge;
34
- static bool hasListeners = NO;
35
-
36
- - (NSArray<NSString*> *)supportedEvents {
37
- return @[@"ReactNativeBlobUtilState", @"ReactNativeBlobUtilServerPush", @"ReactNativeBlobUtilProgress", @"ReactNativeBlobUtilProgress-upload", @"ReactNativeBlobUtilExpire", @"ReactNativeBlobUtilMessage", @"ReactNativeBlobUtilFilesystem", @"log", @"warn", @"error", @"data", @"end", @"reportProgress", @"reportUploadProgress"];
38
- }
39
-
40
- // Will be called when this module's first listener is added.
41
- -(void)startObserving {
42
- hasListeners = YES;
43
- // Set up any upstream listeners or background tasks as necessary
44
- }
45
-
46
- // Will be called when this module's last listener is removed, or on dealloc.
47
- -(void)stopObserving {
48
- hasListeners = NO;
49
- // Remove upstream listeners, stop unnecessary background tasks
50
- }
51
-
52
- - (void)emitEvent:(NSString *)name body:(NSString *) body
53
- {
54
- if (hasListeners) {// Only send events if anyone is listening
55
- [self sendEventWithName:name body:body];
56
- }
57
- }
58
- - (void)emitEventDict:(NSString *)name body:(NSDictionary *) body
59
- {
60
- NSError *error;
61
- NSData *jsonData = [NSJSONSerialization dataWithJSONObject:body
62
- options:NSJSONWritingPrettyPrinted
63
- error:&error];
64
-
65
- if (error) {
66
- NSLog(@"Got an error: %@", error);
67
- } else {
68
- NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
69
- [self emitEvent:name body:jsonString];
70
- }
71
- }
72
-
73
- - (dispatch_queue_t) methodQueue {
74
- if(commonTaskQueue == nil)
75
- commonTaskQueue = dispatch_queue_create("ReactNativeBlobUtil.queue", DISPATCH_QUEUE_SERIAL);
76
- return commonTaskQueue;
77
- }
78
-
79
-
80
- + (BOOL)requiresMainQueueSetup {
81
- return NO;
82
- }
83
-
84
- RCT_EXPORT_MODULE();
85
-
86
- - (id) init {
87
- self = [super init];
88
- self.filePathPrefix = FILE_PREFIX;
89
- if(commonTaskQueue == nil)
90
- commonTaskQueue = dispatch_queue_create("ReactNativeBlobUtil.queue", DISPATCH_QUEUE_SERIAL);
91
- if(fsQueue == nil)
92
- fsQueue = dispatch_queue_create("ReactNativeBlobUtil.fs.queue", DISPATCH_QUEUE_SERIAL);
93
- BOOL isDir;
94
- // if temp folder not exists, create one
95
- if(![[NSFileManager defaultManager] fileExistsAtPath: [ReactNativeBlobUtilFS getTempPath] isDirectory:&isDir]) {
96
- [[NSFileManager defaultManager] createDirectoryAtPath:[ReactNativeBlobUtilFS getTempPath] withIntermediateDirectories:YES attributes:nil error:NULL];
97
- }
98
-
99
- return self;
100
- }
101
-
102
- - (NSDictionary *)getConstants {
103
- return self.constantsToExport;
104
- }
105
-
106
- - (NSDictionary *)constantsToExport
107
- {
108
- return @{
109
- @"CacheDir" : [ReactNativeBlobUtilFS getCacheDir],
110
- @"DocumentDir": [ReactNativeBlobUtilFS getDocumentDir],
111
- @"DownloadDir" : [ReactNativeBlobUtilFS getDownloadDir],
112
- @"LibraryDir" : [ReactNativeBlobUtilFS getLibraryDir],
113
- @"MainBundleDir" : [ReactNativeBlobUtilFS getMainBundleDir],
114
- @"MovieDir" : [ReactNativeBlobUtilFS getMovieDir],
115
- @"MusicDir" : [ReactNativeBlobUtilFS getMusicDir],
116
- @"PictureDir" : [ReactNativeBlobUtilFS getPictureDir],
117
- @"ApplicationSupportDir" : [ReactNativeBlobUtilFS getApplicationSupportDir],
118
- // Android only. For the new architecture, we have a single spec for both platforms.
119
- @"RingtoneDir": @"",
120
- @"SDCardDir": @"",
121
- @"SDCardApplicationDir": @"",
122
- @"DCIMDir": @"",
123
- // Android only legacy constants
124
- @"LegacyDCIMDir": @"",
125
- @"LegacyPictureDir": @"",
126
- @"LegacyMusicDir": @"",
127
- @"LegacyDownloadDir": @"",
128
- @"LegacyMovieDir": @"",
129
- @"LegacyRingtoneDir": @"",
130
- @"LegacySDCardDir": @"",
131
- };
132
- }
133
-
134
- // Fetch blob data request
135
- RCT_EXPORT_METHOD(fetchBlobForm:(NSDictionary *)options
136
- taskId:(NSString *)taskId
137
- method:(NSString *)method
138
- url:(NSString *)url
139
- headers:(NSDictionary *)headers
140
- form:(NSArray *)form
141
- callback:(RCTResponseSenderBlock)callback)
142
- {
143
-
144
- [ReactNativeBlobUtilReqBuilder buildMultipartRequest:options
145
- taskId:taskId
146
- method:method
147
- url:url
148
- headers:headers
149
- form:form
150
- onComplete:^(__weak NSURLRequest *req, long bodyLength)
151
- {
152
- // something went wrong when building the request body
153
- if(req == nil)
154
- {
155
- callback(@[@"ReactNativeBlobUtil.fetchBlobForm failed to create request body"]);
156
- }
157
- // send HTTP request
158
- else
159
- {
160
- [[ReactNativeBlobUtilNetwork sharedInstance] sendRequest:options
161
- contentLength:bodyLength
162
- baseModule:self
163
- taskId:taskId
164
- withRequest:req
165
- callback:callback];
166
- }
167
- }];
168
-
169
- }
170
-
171
-
172
- // Fetch blob data request
173
- RCT_EXPORT_METHOD(fetchBlob:(NSDictionary *)options
174
- taskId:(NSString *)taskId
175
- method:(NSString *)method
176
- url:(NSString *)url
177
- headers:(NSDictionary *)headers
178
- body:(NSString *)body
179
- callback:(RCTResponseSenderBlock)callback)
180
- {
181
- [ReactNativeBlobUtilReqBuilder buildOctetRequest:options
182
- taskId:taskId
183
- method:method
184
- url:url
185
- headers:headers
186
- body:body
187
- onComplete:^(NSURLRequest *req, long bodyLength)
188
- {
189
- // something went wrong when building the request body
190
- if(req == nil)
191
- {
192
- callback(@[@"ReactNativeBlobUtil.fetchBlob failed to create request body"]);
193
- }
194
- // send HTTP request
195
- else
196
- {
197
- [[ReactNativeBlobUtilNetwork sharedInstance] sendRequest:options
198
- contentLength:bodyLength
199
- baseModule:self
200
- taskId:taskId
201
- withRequest:req
202
- callback:callback];
203
- }
204
- }];
205
- }
206
-
207
- #pragma mark - fs.createFile
208
- // Signature for the Old Architecture
209
- RCT_EXPORT_METHOD(createFile:(NSString *)path
210
- data:(NSString *)data
211
- encoding:(NSString *)encoding
212
- resolver:(RCTPromiseResolveBlock)resolve
213
- rejecter:(RCTPromiseRejectBlock)reject)
214
- {
215
- [self createFile:path data:data encoding:encoding resolve:resolve reject:reject];
216
- }
217
-
218
- // Signature for the New Architecture. Codegen can't change the resolve/reject param names and
219
- // If we change the RCT_EXPORT_METHOD we are going to introduce braking changes we may avoid.
220
- - (void)createFile:(NSString *)path
221
- data:(NSString *)data
222
- encoding:(NSString *)encoding
223
- resolve:(RCTPromiseResolveBlock)resolve
224
- reject:(RCTPromiseRejectBlock)reject
225
- {
226
- NSFileManager * fm = [NSFileManager defaultManager];
227
- NSData * fileContent = nil;
228
-
229
- if([[encoding lowercaseString] isEqualToString:@"utf8"]) {
230
- fileContent = [[NSData alloc] initWithData:[data dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES]];
231
- }
232
- else if([[encoding lowercaseString] isEqualToString:@"base64"]) {
233
- fileContent = [[NSData alloc] initWithBase64EncodedString:data options:0];
234
- }
235
- else if([[encoding lowercaseString] isEqualToString:@"uri"]) {
236
- NSString * orgPath = [data stringByReplacingOccurrencesOfString:FILE_PREFIX withString:@""];
237
- fileContent = [[NSData alloc] initWithContentsOfFile:orgPath];
238
- }
239
- else {
240
- fileContent = [[NSData alloc] initWithData:[data dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES]];
241
- }
242
-
243
- if ([fm fileExistsAtPath:path]) {
244
- reject(@"EEXIST", [NSString stringWithFormat:@"File '%@' already exists", path], nil);
245
- }
246
- else {
247
- BOOL success = [fm createFileAtPath:path contents:fileContent attributes:NULL];
248
- if(success == YES)
249
- resolve(@[[NSNull null]]);
250
- else
251
- reject(@"EUNSPECIFIED", [NSString stringWithFormat:@"Failed to create new file at path '%@', please ensure the folder exists", path], nil);
252
- }
253
- }
254
-
255
- #pragma mark - fs.createFileASCII
256
- // method for create file with ASCII content
257
- // Signature for the Old Architecture
258
- RCT_EXPORT_METHOD(createFileASCII:(NSString *)path
259
- data:(NSArray *)dataArray
260
- resolver:(RCTPromiseResolveBlock)resolve
261
- rejecter:(RCTPromiseRejectBlock)reject)
262
- {
263
- [self createFileASCII:path data:dataArray resolve:resolve reject:reject];
264
- }
265
-
266
- // Signature for the New Architecture. Codegen can't change the resolve/reject param names and
267
- // If we change the RCT_EXPORT_METHOD we are going to introduce braking changes we may avoid.
268
- - (void)createFileASCII:(NSString *)path
269
- data:(NSArray *)data
270
- resolve:(RCTPromiseResolveBlock)resolve
271
- reject:(RCTPromiseRejectBlock)reject
272
- {
273
- NSFileManager * fm = [NSFileManager defaultManager];
274
- NSMutableData * fileContent = [NSMutableData alloc];
275
- // prevent stack overflow, alloc on heap
276
- char * bytes = (char*) malloc([data count]);
277
-
278
- for(int i = 0; i < data.count; i++) {
279
- bytes[i] = [[data objectAtIndex:i] charValue];
280
- }
281
-
282
- [fileContent appendBytes:bytes length:data.count];
283
-
284
- if ([fm fileExistsAtPath:path]) {
285
- reject(@"EEXIST", [NSString stringWithFormat:@"File '%@' already exists", path], nil);
286
- }
287
- else {
288
- BOOL success = [fm createFileAtPath:path contents:fileContent attributes:NULL];
289
- if(success == YES)
290
- resolve(@[[NSNull null]]);
291
- else
292
- reject(@"EUNSPECIFIED", [NSString stringWithFormat:@"failed to create new file at path '%@', please ensure the folder exists", path], nil);
293
- }
294
-
295
- free(bytes);
296
- }
297
-
298
- #pragma mark - fs.pathForAppGroup
299
- // Signature for the Old Architecture
300
- RCT_EXPORT_METHOD(pathForAppGroup:(NSString *)groupName
301
- resolver:(RCTPromiseResolveBlock)resolve
302
- rejecter:(RCTPromiseRejectBlock)reject)
303
- {
304
- [self pathForAppGroup:groupName resolve:resolve reject:reject];
305
- }
306
-
307
- // Signature for the New Architecture. Codegen can't change the resolve/reject param names and
308
- // If we change the RCT_EXPORT_METHOD we are going to introduce braking changes we may avoid.
309
- - (void)pathForAppGroup:(NSString *)groupName
310
- resolve:(RCTPromiseResolveBlock)resolve
311
- reject:(RCTPromiseRejectBlock)reject
312
- {
313
- NSString * path = [ReactNativeBlobUtilFS getPathForAppGroup:groupName];
314
-
315
- if(path) {
316
- resolve(path);
317
- } else {
318
- reject(@"EUNSPECIFIED", @"could not find path for app group", nil);
319
- }
320
- }
321
-
322
- #pragma mark - fs.syncPathAppGroup
323
- RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(syncPathAppGroup:(NSString *)groupName) {
324
- NSURL *pathUrl = [[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:groupName];
325
- NSString *path = [pathUrl path];
326
-
327
- if(path) {
328
- return path;
329
- } else {
330
- return @"";
331
- }
332
- }
333
-
334
- #pragma mark - fs.exists
335
- RCT_EXPORT_METHOD(exists:(NSString *)path callback:(RCTResponseSenderBlock)callback) {
336
- [ReactNativeBlobUtilFS exists:path callback:callback];
337
- }
338
-
339
- #pragma mark - fs.writeFile
340
- // Signature for the Old Architecture
341
- RCT_EXPORT_METHOD(writeFile:(NSString *)path
342
- encoding:(NSString *)encoding
343
- data:(NSString *)data
344
- transformFile:(BOOL)transformFile
345
- append:(BOOL)append
346
- resolver:(RCTPromiseResolveBlock)resolve
347
- rejecter:(RCTPromiseRejectBlock)reject)
348
- {
349
- [self writeFile:path encoding:encoding data:data transformFile:transformFile append:append resolve:resolve reject:reject];
350
- }
351
-
352
- // Signature for the New Architecture. Codegen can't change the resolve/reject param names and
353
- // If we change the RCT_EXPORT_METHOD we are going to introduce braking changes we may avoid.
354
- - (void)writeFile:(NSString *)path
355
- encoding:(NSString *)encoding
356
- data:(NSString *)data
357
- transformFile:(BOOL)transformFile
358
- append:(BOOL)append
359
- resolve:(RCTPromiseResolveBlock)resolve
360
- reject:(RCTPromiseRejectBlock)reject;
361
- {
362
- [ReactNativeBlobUtilFS writeFile:path encoding:[NSString stringWithString:encoding] data:data transformFile:transformFile append:append resolver:resolve rejecter:reject];
363
- }
364
-
365
- #pragma mark - fs.writeArray
366
- // Signature for the Old Architecture
367
- RCT_EXPORT_METHOD(writeFileArray:(NSString *)path
368
- data:(NSArray *)data
369
- append:(BOOL)append
370
- resolver:(RCTPromiseResolveBlock)resolve
371
- rejecter:(RCTPromiseRejectBlock)reject)
372
- {
373
- [self writeFileArray:path data:data append:append resolve:resolve reject:reject];
374
- }
375
-
376
- // Signature for the New Architecture. Codegen can't change the resolve/reject param names and
377
- // If we change the RCT_EXPORT_METHOD we are going to introduce braking changes we may avoid.
378
- - (void)writeFileArray:(NSString *)path
379
- data:(NSArray *)data
380
- append:(BOOL)append
381
- resolve:(RCTPromiseResolveBlock)resolve
382
- reject:(RCTPromiseRejectBlock)reject
383
- {
384
- [ReactNativeBlobUtilFS writeFileArray:path data:data append:append resolver:resolve rejecter:reject];
385
- }
386
-
387
- #pragma mark - fs.writeStream
388
- RCT_EXPORT_METHOD(writeStream:(NSString *)path
389
- withEncoding:(NSString *)encoding
390
- appendData:(BOOL)append
391
- callback:(RCTResponseSenderBlock)callback)
392
- {
393
- ReactNativeBlobUtilFS * fileStream = [[ReactNativeBlobUtilFS alloc] init];
394
- NSFileManager * fm = [NSFileManager defaultManager];
395
- NSString * folder = [path stringByDeletingLastPathComponent];
396
- NSError* err = nil;
397
- BOOL isDir = NO;
398
- BOOL exists = [fm fileExistsAtPath:path isDirectory: &isDir];
399
-
400
- if(!exists) {
401
- [fm createDirectoryAtPath:folder withIntermediateDirectories:YES attributes:NULL error:&err];
402
- if(err != nil) {
403
- callback(@[@"ENOTDIR", [NSString stringWithFormat:@"Failed to create parent directory of '%@'; error: %@", path, [err description]]]);
404
- }
405
- if(![fm createFileAtPath:path contents:nil attributes:nil]) {
406
- callback(@[@"ENOENT", [NSString stringWithFormat:@"File '%@' does not exist and could not be created", path]]);
407
- }
408
- }
409
- else if(isDir) {
410
- callback(@[@"EISDIR", [NSString stringWithFormat:@"Expecting a file but '%@' is a directory", path]]);
411
- }
412
-
413
- NSString * streamId = [fileStream openWithPath:path encode:encoding appendData:append];
414
- callback(@[[NSNull null], [NSNull null], streamId]);
415
- }
416
-
417
- #pragma mark - fs.writeArrayChunk
418
- RCT_EXPORT_METHOD(writeArrayChunk:(NSString *)streamId
419
- withArray:(NSArray *)dataArray
420
- callback:(RCTResponseSenderBlock) callback)
421
- {
422
- ReactNativeBlobUtilFS *fs = [[ReactNativeBlobUtilFS getFileStreams] valueForKey:streamId];
423
- char * bytes = (char *) malloc([dataArray count]);
424
- for(int i = 0; i < dataArray.count; i++) {
425
- bytes[i] = [[dataArray objectAtIndex:i] charValue];
426
- }
427
- NSMutableData * data = [NSMutableData alloc];
428
- [data appendBytes:bytes length:dataArray.count];
429
- [fs write:data];
430
- free(bytes);
431
- callback(@[[NSNull null]]);
432
- }
433
-
434
- #pragma mark - fs.writeChunk
435
- RCT_EXPORT_METHOD(writeChunk:(NSString *)streamId
436
- withData:(NSString *)data
437
- callback:(RCTResponseSenderBlock) callback)
438
- {
439
- ReactNativeBlobUtilFS *fs = [[ReactNativeBlobUtilFS getFileStreams] valueForKey:streamId];
440
- [fs writeEncodeChunk:data];
441
- callback(@[[NSNull null]]);
442
- }
443
-
444
- #pragma mark - fs.closeStream
445
- RCT_EXPORT_METHOD(closeStream:(NSString *)streamId callback:(RCTResponseSenderBlock) callback)
446
- {
447
- ReactNativeBlobUtilFS *fs = [[ReactNativeBlobUtilFS getFileStreams] valueForKey:streamId];
448
- [fs closeOutStream];
449
- callback(@[[NSNull null], @YES]);
450
- }
451
-
452
- #pragma mark - unlink
453
- RCT_EXPORT_METHOD(unlink:(NSString *)path callback:(RCTResponseSenderBlock) callback)
454
- {
455
- NSError * error = nil;
456
- [[NSFileManager defaultManager] removeItemAtPath:path error:&error];
457
- if(error == nil || [[NSFileManager defaultManager] fileExistsAtPath:path] == NO)
458
- callback(@[[NSNull null]]);
459
- else
460
- callback(@[[NSString stringWithFormat:@"failed to unlink file or path at %@", path]]);
461
- }
462
-
463
- #pragma mark - fs.removeSession
464
- RCT_EXPORT_METHOD(removeSession:(NSArray *)paths callback:(RCTResponseSenderBlock) callback)
465
- {
466
- NSError * error = nil;
467
-
468
- for(NSString * path in paths) {
469
- [[NSFileManager defaultManager] removeItemAtPath:path error:&error];
470
- if(error != nil) {
471
- callback(@[[NSString stringWithFormat:@"failed to remove session path at %@", path]]);
472
- return;
473
- }
474
- }
475
- callback(@[[NSNull null]]);
476
-
477
- }
478
-
479
- #pragma mark - fs.ls
480
- // Signature for the Old Architecture
481
- RCT_EXPORT_METHOD(ls:(NSString *)path resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
482
- {
483
- [self ls:path resolve:resolve reject:reject];
484
- }
485
-
486
- // Signature for the New Architecture. Codegen can't change the resolve/reject param names and
487
- // If we change the RCT_EXPORT_METHOD we are going to introduce braking changes we may avoid.
488
- - (void)ls:(NSString *)path
489
- resolve:(RCTPromiseResolveBlock)resolve
490
- reject:(RCTPromiseRejectBlock)reject
491
- {
492
- NSFileManager* fm = [NSFileManager defaultManager];
493
- BOOL exist = NO;
494
- BOOL isDir = NO;
495
- exist = [fm fileExistsAtPath:path isDirectory:&isDir];
496
- if(exist == NO) {
497
- return reject(@"ENOENT", [NSString stringWithFormat:@"No such file '%@'", path], nil);
498
- }
499
- if(isDir == NO) {
500
- return reject(@"ENOTDIR", [NSString stringWithFormat:@"Not a directory '%@'", path], nil);
501
- }
502
- NSError * error = nil;
503
- NSArray * result = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:path error:&error];
504
-
505
- if(error == nil)
506
- resolve(result);
507
- else
508
- reject(@"EUNSPECIFIED", [error description], nil);
509
- }
510
-
511
- #pragma mark - fs.stat
512
- RCT_EXPORT_METHOD(stat:(NSString *)target callback:(RCTResponseSenderBlock) callback)
513
- {
514
-
515
- [ReactNativeBlobUtilFS getPathFromUri:target completionHandler:^(NSString *path, ALAssetRepresentation *asset) {
516
- __block NSMutableDictionary * result;
517
- if(path != nil)
518
- {
519
- NSFileManager* fm = [NSFileManager defaultManager];
520
- BOOL exist = NO;
521
- BOOL isDir = NO;
522
- NSError * error = nil;
523
-
524
- exist = [fm fileExistsAtPath:path isDirectory:&isDir];
525
- if(exist == NO) {
526
- callback(@[[NSString stringWithFormat:@"failed to stat path `%@` because it does not exist or it is not a folder", path]]);
527
- return ;
528
- }
529
- result = [ReactNativeBlobUtilFS stat:path error:&error].mutableCopy;
530
-
531
- if(error == nil)
532
- callback(@[[NSNull null], result]);
533
- else
534
- callback(@[[error localizedDescription], [NSNull null]]);
535
-
536
- }
537
- else if(asset != nil)
538
- {
539
- __block NSNumber * size = [NSNumber numberWithLong:[asset size]];
540
- result = [asset metadata];
541
- [result setValue:size forKey:@"size"];
542
- callback(@[[NSNull null], result]);
543
- }
544
- else
545
- {
546
- callback(@[@"failed to stat path, could not resolve URI", [NSNull null]]);
547
- }
548
- }];
549
- }
550
-
551
- #pragma mark - fs.lstat
552
- RCT_EXPORT_METHOD(lstat:(NSString *)path callback:(RCTResponseSenderBlock) callback)
553
- {
554
- NSFileManager* fm = [NSFileManager defaultManager];
555
- BOOL exist = NO;
556
- BOOL isDir = NO;
557
-
558
- path = [ReactNativeBlobUtilFS getPathOfAsset:path];
559
-
560
- exist = [fm fileExistsAtPath:path isDirectory:&isDir];
561
- if(exist == NO) {
562
- callback(@[[NSString stringWithFormat:@"failed to lstat path `%@` because it does not exist or it is not a folder", path]]);
563
- return ;
564
- }
565
- NSError * error = nil;
566
- NSArray * files = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:path error:&error];
567
-
568
- NSMutableArray * res = [[NSMutableArray alloc] init];
569
- if(isDir == YES) {
570
- for(NSString * p in files) {
571
- NSString * filePath = [NSString stringWithFormat:@"%@/%@", path, p];
572
- [res addObject:[ReactNativeBlobUtilFS stat:filePath error:&error]];
573
- }
574
- }
575
- else {
576
- [res addObject:[ReactNativeBlobUtilFS stat:path error:&error]];
577
- }
578
-
579
- if(error == nil)
580
- callback(@[[NSNull null], res == nil ? [NSNull null] :res ]);
581
- else
582
- callback(@[[error localizedDescription], [NSNull null]]);
583
-
584
- }
585
-
586
- #pragma mark - fs.cp
587
- // Signature for the Old Architecture
588
- RCT_EXPORT_METHOD(cp:(NSString*)src toPath:(NSString *)dest callback:(RCTResponseSenderBlock) callback)
589
- {
590
- [self cp:src dest:dest callback:callback];
591
- }
592
-
593
- // Signature for the New Architecture. Codegen can't change the resolve/reject param names and
594
- // If we change the RCT_EXPORT_METHOD we are going to introduce braking changes we may avoid.
595
- - (void)cp:(NSString *)src
596
- dest:(NSString *)dest
597
- callback:(RCTResponseSenderBlock)callback
598
- {
599
- // path = [ReactNativeBlobUtilFS getPathOfAsset:path];
600
- [ReactNativeBlobUtilFS getPathFromUri:src completionHandler:^(NSString *path, ALAssetRepresentation *asset) {
601
- NSError * error = nil;
602
- if(path == nil)
603
- {
604
- [ReactNativeBlobUtilFS writeAssetToPath:asset dest:dest];
605
- callback(@[[NSNull null], @YES]);
606
- }
607
- else
608
- {
609
- // If the destination exists there will be an error
610
- BOOL result = [[NSFileManager defaultManager] copyItemAtURL:[NSURL fileURLWithPath:path] toURL:[NSURL fileURLWithPath:dest] error:&error];
611
-
612
- if(error == nil)
613
- callback(@[[NSNull null], @YES]);
614
- else
615
- callback(@[[error localizedDescription], @NO]);
616
- }
617
- }];
618
- }
619
-
620
- #pragma mark - fs.mv
621
- // Signature for the Old Architecture
622
- RCT_EXPORT_METHOD(mv:(NSString *)path toPath:(NSString *)dest callback:(RCTResponseSenderBlock) callback)
623
- {
624
- [self mv:path dest:dest callback:callback];
625
- }
626
-
627
- // Signature for the New Architecture. Codegen can't change the resolve/reject param names and
628
- // If we change the RCT_EXPORT_METHOD we are going to introduce braking changes we may avoid.
629
- - (void)mv:(NSString *)path
630
- dest:(NSString *)dest
631
- callback:(RCTResponseSenderBlock)callback
632
- {
633
- NSError * error = nil;
634
- BOOL result = [[NSFileManager defaultManager] moveItemAtURL:[NSURL fileURLWithPath:path] toURL:[NSURL fileURLWithPath:dest] error:&error];
635
-
636
- if(error == nil)
637
- callback(@[[NSNull null], @YES]);
638
- else
639
- callback(@[[error localizedDescription], @NO]);
640
-
641
- }
642
-
643
- #pragma mark - fs.mkdir
644
- RCT_EXPORT_METHOD(mkdir:(NSString *)path resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
645
- {
646
- [self mkdir:path resolve:resolve reject:reject];
647
- }
648
-
649
- - (void)mkdir:(NSString *)path
650
- resolve:(RCTPromiseResolveBlock)resolve
651
- reject:(RCTPromiseRejectBlock)reject
652
- {
653
- [ReactNativeBlobUtilFS mkdir:path resolver:resolve rejecter:reject];
654
- }
655
-
656
- #pragma mark - fs.readFile
657
- // Signature for the Old Architecture
658
- RCT_EXPORT_METHOD(readFile:(NSString *)path
659
- encoding:(NSString *)encoding
660
- transformFile:(BOOL) transformFile
661
- resolver:(RCTPromiseResolveBlock)resolve
662
- rejecter:(RCTPromiseRejectBlock)reject)
663
- {
664
- [self readFile:path encoding:encoding transformFile:transformFile resolve:resolve reject:reject];
665
- }
666
-
667
- // Signature for the New Architecture. Codegen can't change the resolve/reject param names and
668
- // If we change the RCT_EXPORT_METHOD we are going to introduce braking changes we may avoid.
669
- - (void)readFile:(NSString *)path
670
- encoding:(NSString *)encoding
671
- transformFile:(BOOL)transformFile
672
- resolve:(RCTPromiseResolveBlock)resolve
673
- reject:(RCTPromiseRejectBlock)reject
674
- {
675
-
676
- [ReactNativeBlobUtilFS readFile:path encoding:encoding transformFile:transformFile onComplete:^(NSData * content, NSString * code, NSString * err) {
677
- if(err != nil) {
678
- reject(code, err, nil);
679
- return;
680
- }
681
- if([encoding isEqualToString:@"ascii"]) {
682
- resolve((NSMutableArray *)content);
683
- } else if([encoding isEqualToString:@"base64"]) {
684
- resolve([content base64EncodedStringWithOptions:0]);
685
- } else {
686
- resolve([[NSString alloc] initWithData:content encoding:NSUTF8StringEncoding]);
687
- }
688
- }];
689
- }
690
-
691
- #pragma mark - fs.hash
692
- // Signature for the Old Architecture
693
- RCT_EXPORT_METHOD(hash:(NSString *)path
694
- algorithm:(NSString *)algorithm
695
- resolver:(RCTPromiseResolveBlock)resolve
696
- rejecter:(RCTPromiseRejectBlock)reject)
697
- {
698
- [self hash:path algorithm:algorithm resolve:resolve reject:reject];
699
- }
700
-
701
- // Signature for the New Architecture. Codegen can't change the resolve/reject param names and
702
- // If we change the RCT_EXPORT_METHOD we are going to introduce braking changes we may avoid.
703
- - (void)hash:(NSString *)path
704
- algorithm:(NSString *)algorithm
705
- resolve:(RCTPromiseResolveBlock)resolve
706
- reject:(RCTPromiseRejectBlock)reject
707
- {
708
- [ReactNativeBlobUtilFS hash:path algorithm:[NSString stringWithString:algorithm] resolver:resolve rejecter:reject];
709
- }
710
-
711
- #pragma mark - fs.readStream
712
- RCT_EXPORT_METHOD(readStream:(NSString *)path encoding:(NSString *)encoding bufferSize:(int)bufferSize tick:(int)tick streamId:(NSString *)streamId)
713
- {
714
- if(bufferSize == 0) {
715
- if([[encoding lowercaseString] isEqualToString:@"base64"])
716
- bufferSize = 4095;
717
- else
718
- bufferSize = 4096;
719
- }
720
-
721
- dispatch_async(fsQueue, ^{
722
- [ReactNativeBlobUtilFS readStream:path encoding:encoding bufferSize:bufferSize tick:tick streamId:streamId baseModule:self];
723
- });
724
- }
725
-
726
- #pragma mark - fs.getEnvironmentDirs
727
- RCT_EXPORT_METHOD(getEnvironmentDirs:(RCTResponseSenderBlock) callback)
728
- {
729
-
730
- callback(@[
731
- [ReactNativeBlobUtilFS getDocumentDir],
732
- [ReactNativeBlobUtilFS getCacheDir],
733
- ]);
734
- }
735
-
736
- #pragma mark - net.cancelRequest
737
- RCT_EXPORT_METHOD(cancelRequest:(NSString *)taskId callback:(RCTResponseSenderBlock)callback) {
738
- [[ReactNativeBlobUtilNetwork sharedInstance] cancelRequest:taskId];
739
- callback(@[[NSNull null], taskId]);
740
-
741
- }
742
-
743
- #pragma mark - net.enableProgressReport
744
- RCT_EXPORT_METHOD(enableProgressReport:(NSString *)taskId interval:(nonnull NSNumber*)interval count:(nonnull NSNumber*)count)
745
- {
746
-
747
- ReactNativeBlobUtilProgress * cfg = [[ReactNativeBlobUtilProgress alloc] initWithType:Download interval:interval count:count];
748
- [[ReactNativeBlobUtilNetwork sharedInstance] enableProgressReport:taskId config:cfg];
749
- }
750
-
751
- #pragma mark - net.enableUploadProgressReport
752
- RCT_EXPORT_METHOD(enableUploadProgressReport:(NSString *)taskId interval:(nonnull NSNumber*)interval count:(nonnull NSNumber*)count)
753
- {
754
- ReactNativeBlobUtilProgress * cfg = [[ReactNativeBlobUtilProgress alloc] initWithType:Upload interval:interval count:count];
755
- [[ReactNativeBlobUtilNetwork sharedInstance] enableUploadProgress:taskId config:cfg];
756
- }
757
-
758
- #pragma mark - fs.slice
759
- // Signature for the Old Architecture
760
- RCT_EXPORT_METHOD(slice:(NSString *)src dest:(NSString *)dest start:(nonnull NSNumber *)start end:(nonnull NSNumber *)end resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
761
- {
762
- [self slice:src dest:dest start:start.doubleValue end:end.doubleValue resolve:resolve reject:reject];
763
- }
764
-
765
- // Signature for the New Architecture. Codegen can't change the resolve/reject param names and
766
- // If we change the RCT_EXPORT_METHOD we are going to introduce braking changes we may avoid.
767
- - (void)slice:(NSString *)src
768
- dest:(NSString *)dest
769
- start:(double)start
770
- end:(double)end
771
- resolve:(RCTPromiseResolveBlock)resolve
772
- reject:(RCTPromiseRejectBlock)reject
773
- {
774
- [ReactNativeBlobUtilFS slice:src dest:dest start:@(start) end:@(end) encode:@"" resolver:resolve rejecter:reject];
775
- }
776
-
777
- // Signature for the Old Architecture
778
- RCT_EXPORT_METHOD(presentOptionsMenu:(NSString*)uri scheme:(NSString *)scheme resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
779
- {
780
- [self presentOptionsMenu:uri scheme:scheme resolve:resolve reject:reject];
781
- }
782
-
783
- // Signature for the New Architecture. Codegen can't change the resolve/reject param names and
784
- // If we change the RCT_EXPORT_METHOD we are going to introduce braking changes we may avoid.
785
- - (void)presentOptionsMenu:(NSString *)uri
786
- scheme:(NSString *)scheme
787
- resolve:(RCTPromiseResolveBlock)resolve
788
- reject:(RCTPromiseRejectBlock)reject
789
- {
790
- NSString * utf8uri = [uri stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
791
- NSURL * url = [[NSURL alloc] initWithString:utf8uri];
792
- // NSURL * url = [[NSURL alloc] initWithString:uri];
793
- documentController = [UIDocumentInteractionController interactionControllerWithURL:url];
794
- UIViewController *rootCtrl = [[[[UIApplication sharedApplication] delegate] window] rootViewController];
795
- documentController.delegate = self;
796
- if(scheme == nil || [[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:scheme]]) {
797
- CGRect rect = CGRectMake(0.0, 0.0, 0.0, 0.0);
798
- dispatch_sync(dispatch_get_main_queue(), ^{
799
- [documentController presentOptionsMenuFromRect:rect inView:rootCtrl.view animated:YES];
800
- });
801
- resolve(@[[NSNull null]]);
802
- } else {
803
- reject(@"EINVAL", @"scheme is not supported", nil);
804
- }
805
- }
806
-
807
- // Signature for the Old Architecture
808
- RCT_EXPORT_METHOD(presentOpenInMenu:(NSString*)uri scheme:(NSString *)scheme resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
809
- {
810
- [self presentOpenInMenu:uri scheme:scheme resolve:resolve reject:reject];
811
- }
812
-
813
- // Signature for the New Architecture. Codegen can't change the resolve/reject param names and
814
- // If we change the RCT_EXPORT_METHOD we are going to introduce braking changes we may avoid.
815
- - (void)presentOpenInMenu:(NSString *)uri
816
- scheme:(NSString *)scheme
817
- resolve:(RCTPromiseResolveBlock)resolve
818
- reject:(RCTPromiseRejectBlock)reject
819
- {
820
- NSString * utf8uri = [uri stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
821
- NSURL * url = [[NSURL alloc] initWithString:utf8uri];
822
- documentController = [UIDocumentInteractionController interactionControllerWithURL:url];
823
- UIViewController *rootCtrl = [[[[UIApplication sharedApplication] delegate] window] rootViewController];
824
- documentController.delegate = self;
825
- if(scheme == nil || [[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:scheme]]) {
826
- CGRect rect = CGRectMake(0.0, 0.0, 0.0, 0.0);
827
- dispatch_sync(dispatch_get_main_queue(), ^{
828
- [documentController presentOpenInMenuFromRect:rect inView:rootCtrl.view animated:YES];
829
- });
830
- resolve(@[[NSNull null]]);
831
- } else {
832
- reject(@"EINVAL", @"scheme is not supported", nil);
833
- }
834
- }
835
-
836
- # pragma mark - open file with UIDocumentInteractionController and delegate
837
- // Signature for the Old Architecture
838
- RCT_EXPORT_METHOD(presentPreview:(NSString*)uri scheme:(NSString *)scheme resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
839
- {
840
- [self presentPreview:uri scheme:scheme resolve:resolve reject:reject];
841
- }
842
-
843
- // Signature for the New Architecture. Codegen can't change the resolve/reject param names and
844
- // If we change the RCT_EXPORT_METHOD we are going to introduce braking changes we may avoid.
845
- - (void)presentPreview:(NSString *)uri
846
- scheme:(NSString *)scheme
847
- resolve:(RCTPromiseResolveBlock)resolve
848
- reject:(RCTPromiseRejectBlock)reject
849
- {
850
- NSString * utf8uri = [uri stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
851
- NSURL * url = [[NSURL alloc] initWithString:utf8uri];
852
- // NSURL * url = [[NSURL alloc] initWithString:uri];
853
- documentController = [UIDocumentInteractionController interactionControllerWithURL:url];
854
- documentController.delegate = self;
855
-
856
- if(scheme == nil || [[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:scheme]]) {
857
- dispatch_sync(dispatch_get_main_queue(), ^{
858
- if([documentController presentPreviewAnimated:YES]) {
859
- resolve(@[[NSNull null]]);
860
- } else {
861
- reject(@"EINVAL", @"document is not supported", nil);
862
- }
863
- });
864
- } else {
865
- reject(@"EINVAL", @"scheme is not supported", nil);
866
- }
867
- }
868
-
869
- # pragma mark - exclude from backup key
870
-
871
- RCT_EXPORT_METHOD(excludeFromBackupKey:(NSString *)url resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
872
- {
873
- [self excludeFromBackupKey:url resolve:resolve reject:reject];
874
- }
875
-
876
- - (void)excludeFromBackupKey:(NSString *)url
877
- resolve:(RCTPromiseResolveBlock)resolve
878
- reject:(RCTPromiseRejectBlock)reject
879
- {
880
- NSError *error = nil;
881
- [ [NSURL URLWithString:url] setResourceValue:[NSNumber numberWithBool:YES] forKey:NSURLIsExcludedFromBackupKey error:&error];
882
- if(!error)
883
- {
884
- resolve(@[[NSNull null]]);
885
- } else {
886
- reject(@"EUNSPECIFIED", [error description], nil);
887
- }
888
-
889
- }
890
-
891
-
892
- RCT_EXPORT_METHOD(df:(RCTResponseSenderBlock)callback)
893
- {
894
- [ReactNativeBlobUtilFS df:callback];
895
- }
896
-
897
- - (UIViewController *)documentInteractionControllerViewControllerForPreview: (UIDocumentInteractionController *) controller
898
- {
899
- UIWindow *window = [UIApplication sharedApplication].keyWindow;
900
- return window.rootViewController;
901
- }
902
-
903
- # pragma mark - Android Only methods
904
- // These methods are required because in the New Arch we have a single spec for both platforms
905
- - (void)actionViewIntent:(NSString *) path
906
- mime:(NSString *) mime
907
- chooserTitle:(NSString *) chooserTitle
908
- resolve:(RCTPromiseResolveBlock)resolve
909
- reject:(RCTPromiseRejectBlock)reject
910
- {
911
- reject(@"ENOT_SUPPORTED", @"This method is not supported on iOS", nil);
912
- }
913
-
914
- - (void)addCompleteDownload:(NSDictionary *)config
915
- resolve:(RCTPromiseResolveBlock)resolve
916
- reject:(RCTPromiseRejectBlock)reject
917
- {
918
- reject(@"ENOT_SUPPORTED", @"This method is not supported on iOS", nil);
919
- }
920
-
921
- - (void)copyToInternal:(NSString *)contentUri
922
- destpath:(NSString *) destpath
923
- resolve:(RCTPromiseResolveBlock)resolve
924
- reject:(RCTPromiseRejectBlock)reject
925
- {
926
- reject(@"ENOT_SUPPORTED", @"This method is not supported on iOS", nil);
927
- }
928
- - (void)copyToMediaStore:(NSDictionary *)filedata
929
- mt:(NSString *) mt
930
- path:(NSString *) path
931
- resolve:(RCTPromiseResolveBlock)resolve
932
- reject:(RCTPromiseRejectBlock)reject
933
- {
934
- reject(@"ENOT_SUPPORTED", @"This method is not supported on iOS", nil);
935
- }
936
-
937
- - (void)createMediaFile:(NSDictionary *)filedata
938
- mt:(NSString *) mt
939
- resolve:(RCTPromiseResolveBlock)resolve
940
- reject:(RCTPromiseRejectBlock)reject
941
- {
942
- reject(@"ENOT_SUPPORTED", @"This method is not supported on iOS", nil);
943
- }
944
-
945
- - (void)getBlob:(NSString *)contentUri
946
- encoding:(NSString *)encoding
947
- resolve:(RCTPromiseResolveBlock)resolve
948
- reject:(RCTPromiseRejectBlock)reject
949
- {
950
- reject(@"ENOT_SUPPORTED", @"This method is not supported on iOS", nil);
951
- }
952
-
953
- - (void)getContentIntent:(NSString *)mime
954
- resolve:(RCTPromiseResolveBlock)resolve
955
- reject:(RCTPromiseRejectBlock)reject
956
- {
957
- reject(@"ENOT_SUPPORTED", @"This method is not supported on iOS", nil);
958
- }
959
- - (void)getSDCardDir:(RCTPromiseResolveBlock)resolve
960
- reject:(RCTPromiseRejectBlock)reject
961
- {
962
- reject(@"ENOT_SUPPORTED", @"This method is not supported on iOS", nil);
963
- }
964
- - (void)getSDCardApplicationDir:(RCTPromiseResolveBlock)resolve
965
- reject:(RCTPromiseRejectBlock)reject
966
- {
967
- reject(@"ENOT_SUPPORTED", @"This method is not supported on iOS", nil);
968
- }
969
- - (void)scanFile:(NSArray *)pairs
970
- callback:(RCTResponseSenderBlock)callback
971
- {
972
- callback(@[@"Scan file method not supported in iOS"]);
973
- }
974
- - (void)writeToMediaFile:(NSString *)fileUri
975
- path:(NSString *)path
976
- transformFile:(BOOL)transformFile
977
- resolve:(RCTPromiseResolveBlock)resolve
978
- reject:(RCTPromiseRejectBlock)reject
979
- {
980
- reject(@"ENOT_SUPPORTED", @"This method is not supported on iOS", nil);
981
- }
982
-
983
- # pragma mark - New Architecture
984
- #if RCT_NEW_ARCH_ENABLED
985
- - (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:
986
- (const facebook::react::ObjCTurboModule::InitParams &)params
987
- {
988
- return std::make_shared<facebook::react::NativeBlobUtilsSpecJSI>(params);
989
- }
990
- #endif
991
-
992
- @end
1
+ //
2
+ // ReactNativeBlobUtil.m
3
+ //
4
+ // Created by wkh237 on 2016/4/28.
5
+ //
6
+
7
+ #import "ReactNativeBlobUtil.h"
8
+ #import "ReactNativeBlobUtilFS.h"
9
+ #import "ReactNativeBlobUtilNetwork.h"
10
+ #import "ReactNativeBlobUtilConst.h"
11
+ #import "ReactNativeBlobUtilReqBuilder.h"
12
+ #import "ReactNativeBlobUtilProgress.h"
13
+
14
+ #if RCT_NEW_ARCH_ENABLED
15
+ #import <ReactNativeBlobUtilSpec/ReactNativeBlobUtilSpec.h>
16
+ #endif
17
+
18
+ dispatch_queue_t commonTaskQueue;
19
+ dispatch_queue_t fsQueue;
20
+
21
+ ////////////////////////////////////////
22
+ //
23
+ // Exported native methods
24
+ //
25
+ ////////////////////////////////////////
26
+
27
+ #pragma mark ReactNativeBlobUtil exported methods
28
+
29
+ @implementation ReactNativeBlobUtil
30
+
31
+ @synthesize filePathPrefix;
32
+ @synthesize documentController;
33
+ @synthesize bridge;
34
+ static bool hasListeners = NO;
35
+
36
+ - (NSArray<NSString*> *)supportedEvents {
37
+ return @[@"ReactNativeBlobUtilState", @"ReactNativeBlobUtilServerPush", @"ReactNativeBlobUtilProgress", @"ReactNativeBlobUtilProgress-upload", @"ReactNativeBlobUtilExpire", @"ReactNativeBlobUtilMessage", @"ReactNativeBlobUtilFilesystem", @"log", @"warn", @"error", @"data", @"end", @"reportProgress", @"reportUploadProgress"];
38
+ }
39
+
40
+ // Will be called when this module's first listener is added.
41
+ -(void)startObserving {
42
+ hasListeners = YES;
43
+ // Set up any upstream listeners or background tasks as necessary
44
+ }
45
+
46
+ // Will be called when this module's last listener is removed, or on dealloc.
47
+ -(void)stopObserving {
48
+ hasListeners = NO;
49
+ // Remove upstream listeners, stop unnecessary background tasks
50
+ }
51
+
52
+ - (void)emitEvent:(NSString *)name body:(NSString *) body
53
+ {
54
+ if (hasListeners) {// Only send events if anyone is listening
55
+ [self sendEventWithName:name body:body];
56
+ }
57
+ }
58
+ - (void)emitEventDict:(NSString *)name body:(NSDictionary *) body
59
+ {
60
+ NSError *error;
61
+ NSData *jsonData = [NSJSONSerialization dataWithJSONObject:body
62
+ options:NSJSONWritingPrettyPrinted
63
+ error:&error];
64
+
65
+ if (error) {
66
+ NSLog(@"Got an error: %@", error);
67
+ } else {
68
+ NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
69
+ [self emitEvent:name body:jsonString];
70
+ }
71
+ }
72
+
73
+ - (dispatch_queue_t) methodQueue {
74
+ if(commonTaskQueue == nil)
75
+ commonTaskQueue = dispatch_queue_create("ReactNativeBlobUtil.queue", DISPATCH_QUEUE_SERIAL);
76
+ return commonTaskQueue;
77
+ }
78
+
79
+
80
+ + (BOOL)requiresMainQueueSetup {
81
+ return NO;
82
+ }
83
+
84
+ RCT_EXPORT_MODULE();
85
+
86
+ - (id) init {
87
+ self = [super init];
88
+ self.filePathPrefix = FILE_PREFIX;
89
+ if(commonTaskQueue == nil)
90
+ commonTaskQueue = dispatch_queue_create("ReactNativeBlobUtil.queue", DISPATCH_QUEUE_SERIAL);
91
+ if(fsQueue == nil)
92
+ fsQueue = dispatch_queue_create("ReactNativeBlobUtil.fs.queue", DISPATCH_QUEUE_SERIAL);
93
+ BOOL isDir;
94
+ // if temp folder not exists, create one
95
+ if(![[NSFileManager defaultManager] fileExistsAtPath: [ReactNativeBlobUtilFS getTempPath] isDirectory:&isDir]) {
96
+ [[NSFileManager defaultManager] createDirectoryAtPath:[ReactNativeBlobUtilFS getTempPath] withIntermediateDirectories:YES attributes:nil error:NULL];
97
+ }
98
+
99
+ return self;
100
+ }
101
+
102
+ - (NSDictionary *)getConstants {
103
+ return self.constantsToExport;
104
+ }
105
+
106
+ - (NSDictionary *)constantsToExport
107
+ {
108
+ return @{
109
+ @"CacheDir" : [ReactNativeBlobUtilFS getCacheDir],
110
+ @"DocumentDir": [ReactNativeBlobUtilFS getDocumentDir],
111
+ @"DownloadDir" : [ReactNativeBlobUtilFS getDownloadDir],
112
+ @"LibraryDir" : [ReactNativeBlobUtilFS getLibraryDir],
113
+ @"MainBundleDir" : [ReactNativeBlobUtilFS getMainBundleDir],
114
+ @"MovieDir" : [ReactNativeBlobUtilFS getMovieDir],
115
+ @"MusicDir" : [ReactNativeBlobUtilFS getMusicDir],
116
+ @"PictureDir" : [ReactNativeBlobUtilFS getPictureDir],
117
+ @"ApplicationSupportDir" : [ReactNativeBlobUtilFS getApplicationSupportDir],
118
+ // Android only. For the new architecture, we have a single spec for both platforms.
119
+ @"RingtoneDir": @"",
120
+ @"SDCardDir": @"",
121
+ @"SDCardApplicationDir": @"",
122
+ @"DCIMDir": @"",
123
+ // Android only legacy constants
124
+ @"LegacyDCIMDir": @"",
125
+ @"LegacyPictureDir": @"",
126
+ @"LegacyMusicDir": @"",
127
+ @"LegacyDownloadDir": @"",
128
+ @"LegacyMovieDir": @"",
129
+ @"LegacyRingtoneDir": @"",
130
+ @"LegacySDCardDir": @"",
131
+ };
132
+ }
133
+
134
+ // Fetch blob data request
135
+ RCT_EXPORT_METHOD(fetchBlobForm:(NSDictionary *)options
136
+ taskId:(NSString *)taskId
137
+ method:(NSString *)method
138
+ url:(NSString *)url
139
+ headers:(NSDictionary *)headers
140
+ form:(NSArray *)form
141
+ callback:(RCTResponseSenderBlock)callback)
142
+ {
143
+
144
+ [ReactNativeBlobUtilReqBuilder buildMultipartRequest:options
145
+ taskId:taskId
146
+ method:method
147
+ url:url
148
+ headers:headers
149
+ form:form
150
+ onComplete:^(__weak NSURLRequest *req, long bodyLength)
151
+ {
152
+ // something went wrong when building the request body
153
+ if(req == nil)
154
+ {
155
+ callback(@[@"ReactNativeBlobUtil.fetchBlobForm failed to create request body"]);
156
+ }
157
+ // send HTTP request
158
+ else
159
+ {
160
+ [[ReactNativeBlobUtilNetwork sharedInstance] sendRequest:options
161
+ contentLength:bodyLength
162
+ baseModule:self
163
+ taskId:taskId
164
+ withRequest:req
165
+ callback:callback];
166
+ }
167
+ }];
168
+
169
+ }
170
+
171
+
172
+ // Fetch blob data request
173
+ RCT_EXPORT_METHOD(fetchBlob:(NSDictionary *)options
174
+ taskId:(NSString *)taskId
175
+ method:(NSString *)method
176
+ url:(NSString *)url
177
+ headers:(NSDictionary *)headers
178
+ body:(NSString *)body
179
+ callback:(RCTResponseSenderBlock)callback)
180
+ {
181
+ [ReactNativeBlobUtilReqBuilder buildOctetRequest:options
182
+ taskId:taskId
183
+ method:method
184
+ url:url
185
+ headers:headers
186
+ body:body
187
+ onComplete:^(NSURLRequest *req, long bodyLength)
188
+ {
189
+ // something went wrong when building the request body
190
+ if(req == nil)
191
+ {
192
+ callback(@[@"ReactNativeBlobUtil.fetchBlob failed to create request body"]);
193
+ }
194
+ // send HTTP request
195
+ else
196
+ {
197
+ [[ReactNativeBlobUtilNetwork sharedInstance] sendRequest:options
198
+ contentLength:bodyLength
199
+ baseModule:self
200
+ taskId:taskId
201
+ withRequest:req
202
+ callback:callback];
203
+ }
204
+ }];
205
+ }
206
+
207
+ #pragma mark - fs.createFile
208
+ // Signature for the Old Architecture
209
+ RCT_EXPORT_METHOD(createFile:(NSString *)path
210
+ data:(NSString *)data
211
+ encoding:(NSString *)encoding
212
+ resolver:(RCTPromiseResolveBlock)resolve
213
+ rejecter:(RCTPromiseRejectBlock)reject)
214
+ {
215
+ [self createFile:path data:data encoding:encoding resolve:resolve reject:reject];
216
+ }
217
+
218
+ // Signature for the New Architecture. Codegen can't change the resolve/reject param names and
219
+ // If we change the RCT_EXPORT_METHOD we are going to introduce braking changes we may avoid.
220
+ - (void)createFile:(NSString *)path
221
+ data:(NSString *)data
222
+ encoding:(NSString *)encoding
223
+ resolve:(RCTPromiseResolveBlock)resolve
224
+ reject:(RCTPromiseRejectBlock)reject
225
+ {
226
+ NSFileManager * fm = [NSFileManager defaultManager];
227
+ NSData * fileContent = nil;
228
+
229
+ if([[encoding lowercaseString] isEqualToString:@"utf8"]) {
230
+ fileContent = [[NSData alloc] initWithData:[data dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES]];
231
+ }
232
+ else if([[encoding lowercaseString] isEqualToString:@"base64"]) {
233
+ fileContent = [[NSData alloc] initWithBase64EncodedString:data options:0];
234
+ }
235
+ else if([[encoding lowercaseString] isEqualToString:@"uri"]) {
236
+ NSString * orgPath = [data stringByReplacingOccurrencesOfString:FILE_PREFIX withString:@""];
237
+ fileContent = [[NSData alloc] initWithContentsOfFile:orgPath];
238
+ }
239
+ else {
240
+ fileContent = [[NSData alloc] initWithData:[data dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES]];
241
+ }
242
+
243
+ if ([fm fileExistsAtPath:path]) {
244
+ reject(@"EEXIST", [NSString stringWithFormat:@"File '%@' already exists", path], nil);
245
+ }
246
+ else {
247
+ BOOL success = [fm createFileAtPath:path contents:fileContent attributes:NULL];
248
+ if(success == YES)
249
+ resolve(@[[NSNull null]]);
250
+ else
251
+ reject(@"EUNSPECIFIED", [NSString stringWithFormat:@"Failed to create new file at path '%@', please ensure the folder exists", path], nil);
252
+ }
253
+ }
254
+
255
+ #pragma mark - fs.createFileASCII
256
+ // method for create file with ASCII content
257
+ // Signature for the Old Architecture
258
+ RCT_EXPORT_METHOD(createFileASCII:(NSString *)path
259
+ data:(NSArray *)dataArray
260
+ resolver:(RCTPromiseResolveBlock)resolve
261
+ rejecter:(RCTPromiseRejectBlock)reject)
262
+ {
263
+ [self createFileASCII:path data:dataArray resolve:resolve reject:reject];
264
+ }
265
+
266
+ // Signature for the New Architecture. Codegen can't change the resolve/reject param names and
267
+ // If we change the RCT_EXPORT_METHOD we are going to introduce braking changes we may avoid.
268
+ - (void)createFileASCII:(NSString *)path
269
+ data:(NSArray *)data
270
+ resolve:(RCTPromiseResolveBlock)resolve
271
+ reject:(RCTPromiseRejectBlock)reject
272
+ {
273
+ NSFileManager * fm = [NSFileManager defaultManager];
274
+ NSMutableData * fileContent = [NSMutableData alloc];
275
+ // prevent stack overflow, alloc on heap
276
+ char * bytes = (char*) malloc([data count]);
277
+
278
+ for(int i = 0; i < data.count; i++) {
279
+ bytes[i] = [[data objectAtIndex:i] charValue];
280
+ }
281
+
282
+ [fileContent appendBytes:bytes length:data.count];
283
+
284
+ if ([fm fileExistsAtPath:path]) {
285
+ reject(@"EEXIST", [NSString stringWithFormat:@"File '%@' already exists", path], nil);
286
+ }
287
+ else {
288
+ BOOL success = [fm createFileAtPath:path contents:fileContent attributes:NULL];
289
+ if(success == YES)
290
+ resolve(@[[NSNull null]]);
291
+ else
292
+ reject(@"EUNSPECIFIED", [NSString stringWithFormat:@"failed to create new file at path '%@', please ensure the folder exists", path], nil);
293
+ }
294
+
295
+ free(bytes);
296
+ }
297
+
298
+ #pragma mark - fs.pathForAppGroup
299
+ // Signature for the Old Architecture
300
+ RCT_EXPORT_METHOD(pathForAppGroup:(NSString *)groupName
301
+ resolver:(RCTPromiseResolveBlock)resolve
302
+ rejecter:(RCTPromiseRejectBlock)reject)
303
+ {
304
+ [self pathForAppGroup:groupName resolve:resolve reject:reject];
305
+ }
306
+
307
+ // Signature for the New Architecture. Codegen can't change the resolve/reject param names and
308
+ // If we change the RCT_EXPORT_METHOD we are going to introduce braking changes we may avoid.
309
+ - (void)pathForAppGroup:(NSString *)groupName
310
+ resolve:(RCTPromiseResolveBlock)resolve
311
+ reject:(RCTPromiseRejectBlock)reject
312
+ {
313
+ NSString * path = [ReactNativeBlobUtilFS getPathForAppGroup:groupName];
314
+
315
+ if(path) {
316
+ resolve(path);
317
+ } else {
318
+ reject(@"EUNSPECIFIED", @"could not find path for app group", nil);
319
+ }
320
+ }
321
+
322
+ #pragma mark - fs.syncPathAppGroup
323
+ RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(syncPathAppGroup:(NSString *)groupName) {
324
+ NSURL *pathUrl = [[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:groupName];
325
+ NSString *path = [pathUrl path];
326
+
327
+ if(path) {
328
+ return path;
329
+ } else {
330
+ return @"";
331
+ }
332
+ }
333
+
334
+ #pragma mark - fs.exists
335
+ RCT_EXPORT_METHOD(exists:(NSString *)path callback:(RCTResponseSenderBlock)callback) {
336
+ [ReactNativeBlobUtilFS exists:path callback:callback];
337
+ }
338
+
339
+ #pragma mark - fs.writeFile
340
+ // Signature for the Old Architecture
341
+ RCT_EXPORT_METHOD(writeFile:(NSString *)path
342
+ encoding:(NSString *)encoding
343
+ data:(NSString *)data
344
+ transformFile:(BOOL)transformFile
345
+ append:(BOOL)append
346
+ resolver:(RCTPromiseResolveBlock)resolve
347
+ rejecter:(RCTPromiseRejectBlock)reject)
348
+ {
349
+ [self writeFile:path encoding:encoding data:data transformFile:transformFile append:append resolve:resolve reject:reject];
350
+ }
351
+
352
+ // Signature for the New Architecture. Codegen can't change the resolve/reject param names and
353
+ // If we change the RCT_EXPORT_METHOD we are going to introduce braking changes we may avoid.
354
+ - (void)writeFile:(NSString *)path
355
+ encoding:(NSString *)encoding
356
+ data:(NSString *)data
357
+ transformFile:(BOOL)transformFile
358
+ append:(BOOL)append
359
+ resolve:(RCTPromiseResolveBlock)resolve
360
+ reject:(RCTPromiseRejectBlock)reject;
361
+ {
362
+ [ReactNativeBlobUtilFS writeFile:path encoding:[NSString stringWithString:encoding] data:data transformFile:transformFile append:append resolver:resolve rejecter:reject];
363
+ }
364
+
365
+ #pragma mark - fs.writeArray
366
+ // Signature for the Old Architecture
367
+ RCT_EXPORT_METHOD(writeFileArray:(NSString *)path
368
+ data:(NSArray *)data
369
+ append:(BOOL)append
370
+ resolver:(RCTPromiseResolveBlock)resolve
371
+ rejecter:(RCTPromiseRejectBlock)reject)
372
+ {
373
+ [self writeFileArray:path data:data append:append resolve:resolve reject:reject];
374
+ }
375
+
376
+ // Signature for the New Architecture. Codegen can't change the resolve/reject param names and
377
+ // If we change the RCT_EXPORT_METHOD we are going to introduce braking changes we may avoid.
378
+ - (void)writeFileArray:(NSString *)path
379
+ data:(NSArray *)data
380
+ append:(BOOL)append
381
+ resolve:(RCTPromiseResolveBlock)resolve
382
+ reject:(RCTPromiseRejectBlock)reject
383
+ {
384
+ [ReactNativeBlobUtilFS writeFileArray:path data:data append:append resolver:resolve rejecter:reject];
385
+ }
386
+
387
+ #pragma mark - fs.writeStream
388
+ RCT_EXPORT_METHOD(writeStream:(NSString *)path
389
+ withEncoding:(NSString *)encoding
390
+ appendData:(BOOL)append
391
+ callback:(RCTResponseSenderBlock)callback)
392
+ {
393
+ ReactNativeBlobUtilFS * fileStream = [[ReactNativeBlobUtilFS alloc] init];
394
+ NSFileManager * fm = [NSFileManager defaultManager];
395
+ NSString * folder = [path stringByDeletingLastPathComponent];
396
+ NSError* err = nil;
397
+ BOOL isDir = NO;
398
+ BOOL exists = [fm fileExistsAtPath:path isDirectory: &isDir];
399
+
400
+ if(!exists) {
401
+ [fm createDirectoryAtPath:folder withIntermediateDirectories:YES attributes:NULL error:&err];
402
+ if(err != nil) {
403
+ callback(@[@"ENOTDIR", [NSString stringWithFormat:@"Failed to create parent directory of '%@'; error: %@", path, [err description]]]);
404
+ }
405
+ if(![fm createFileAtPath:path contents:nil attributes:nil]) {
406
+ callback(@[@"ENOENT", [NSString stringWithFormat:@"File '%@' does not exist and could not be created", path]]);
407
+ }
408
+ }
409
+ else if(isDir) {
410
+ callback(@[@"EISDIR", [NSString stringWithFormat:@"Expecting a file but '%@' is a directory", path]]);
411
+ }
412
+
413
+ NSString * streamId = [fileStream openWithPath:path encode:encoding appendData:append];
414
+ callback(@[[NSNull null], [NSNull null], streamId]);
415
+ }
416
+
417
+ #pragma mark - fs.writeArrayChunk
418
+ RCT_EXPORT_METHOD(writeArrayChunk:(NSString *)streamId
419
+ withArray:(NSArray *)dataArray
420
+ callback:(RCTResponseSenderBlock) callback)
421
+ {
422
+ ReactNativeBlobUtilFS *fs = [[ReactNativeBlobUtilFS getFileStreams] valueForKey:streamId];
423
+ char * bytes = (char *) malloc([dataArray count]);
424
+ for(int i = 0; i < dataArray.count; i++) {
425
+ bytes[i] = [[dataArray objectAtIndex:i] charValue];
426
+ }
427
+ NSMutableData * data = [NSMutableData alloc];
428
+ [data appendBytes:bytes length:dataArray.count];
429
+ [fs write:data];
430
+ free(bytes);
431
+ callback(@[[NSNull null]]);
432
+ }
433
+
434
+ #pragma mark - fs.writeChunk
435
+ RCT_EXPORT_METHOD(writeChunk:(NSString *)streamId
436
+ withData:(NSString *)data
437
+ callback:(RCTResponseSenderBlock) callback)
438
+ {
439
+ ReactNativeBlobUtilFS *fs = [[ReactNativeBlobUtilFS getFileStreams] valueForKey:streamId];
440
+ [fs writeEncodeChunk:data];
441
+ callback(@[[NSNull null]]);
442
+ }
443
+
444
+ #pragma mark - fs.closeStream
445
+ RCT_EXPORT_METHOD(closeStream:(NSString *)streamId callback:(RCTResponseSenderBlock) callback)
446
+ {
447
+ ReactNativeBlobUtilFS *fs = [[ReactNativeBlobUtilFS getFileStreams] valueForKey:streamId];
448
+ [fs closeOutStream];
449
+ callback(@[[NSNull null], @YES]);
450
+ }
451
+
452
+ #pragma mark - unlink
453
+ RCT_EXPORT_METHOD(unlink:(NSString *)path callback:(RCTResponseSenderBlock) callback)
454
+ {
455
+ NSError * error = nil;
456
+ [[NSFileManager defaultManager] removeItemAtPath:path error:&error];
457
+ if(error == nil || [[NSFileManager defaultManager] fileExistsAtPath:path] == NO)
458
+ callback(@[[NSNull null]]);
459
+ else
460
+ callback(@[[NSString stringWithFormat:@"failed to unlink file or path at %@", path]]);
461
+ }
462
+
463
+ #pragma mark - fs.removeSession
464
+ RCT_EXPORT_METHOD(removeSession:(NSArray *)paths callback:(RCTResponseSenderBlock) callback)
465
+ {
466
+ NSError * error = nil;
467
+
468
+ for(NSString * path in paths) {
469
+ [[NSFileManager defaultManager] removeItemAtPath:path error:&error];
470
+ if(error != nil) {
471
+ callback(@[[NSString stringWithFormat:@"failed to remove session path at %@", path]]);
472
+ return;
473
+ }
474
+ }
475
+ callback(@[[NSNull null]]);
476
+
477
+ }
478
+
479
+ #pragma mark - fs.ls
480
+ // Signature for the Old Architecture
481
+ RCT_EXPORT_METHOD(ls:(NSString *)path resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
482
+ {
483
+ [self ls:path resolve:resolve reject:reject];
484
+ }
485
+
486
+ // Signature for the New Architecture. Codegen can't change the resolve/reject param names and
487
+ // If we change the RCT_EXPORT_METHOD we are going to introduce braking changes we may avoid.
488
+ - (void)ls:(NSString *)path
489
+ resolve:(RCTPromiseResolveBlock)resolve
490
+ reject:(RCTPromiseRejectBlock)reject
491
+ {
492
+ NSFileManager* fm = [NSFileManager defaultManager];
493
+ BOOL exist = NO;
494
+ BOOL isDir = NO;
495
+ exist = [fm fileExistsAtPath:path isDirectory:&isDir];
496
+ if(exist == NO) {
497
+ return reject(@"ENOENT", [NSString stringWithFormat:@"No such file '%@'", path], nil);
498
+ }
499
+ if(isDir == NO) {
500
+ return reject(@"ENOTDIR", [NSString stringWithFormat:@"Not a directory '%@'", path], nil);
501
+ }
502
+ NSError * error = nil;
503
+ NSArray * result = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:path error:&error];
504
+
505
+ if(error == nil)
506
+ resolve(result);
507
+ else
508
+ reject(@"EUNSPECIFIED", [error description], nil);
509
+ }
510
+
511
+ #pragma mark - fs.stat
512
+ RCT_EXPORT_METHOD(stat:(NSString *)target callback:(RCTResponseSenderBlock) callback)
513
+ {
514
+
515
+ [ReactNativeBlobUtilFS getPathFromUri:target completionHandler:^(NSString *path, ALAssetRepresentation *asset) {
516
+ __block NSMutableDictionary * result;
517
+ if(path != nil)
518
+ {
519
+ NSFileManager* fm = [NSFileManager defaultManager];
520
+ BOOL exist = NO;
521
+ BOOL isDir = NO;
522
+ NSError * error = nil;
523
+
524
+ exist = [fm fileExistsAtPath:path isDirectory:&isDir];
525
+ if(exist == NO) {
526
+ callback(@[[NSString stringWithFormat:@"failed to stat path `%@` because it does not exist or it is not a folder", path]]);
527
+ return ;
528
+ }
529
+ result = [ReactNativeBlobUtilFS stat:path error:&error].mutableCopy;
530
+
531
+ if(error == nil)
532
+ callback(@[[NSNull null], result]);
533
+ else
534
+ callback(@[[error localizedDescription], [NSNull null]]);
535
+
536
+ }
537
+ else if(asset != nil)
538
+ {
539
+ __block NSNumber * size = [NSNumber numberWithLong:[asset size]];
540
+ result = [asset metadata];
541
+ [result setValue:size forKey:@"size"];
542
+ callback(@[[NSNull null], result]);
543
+ }
544
+ else
545
+ {
546
+ callback(@[@"failed to stat path, could not resolve URI", [NSNull null]]);
547
+ }
548
+ }];
549
+ }
550
+
551
+ #pragma mark - fs.lstat
552
+ RCT_EXPORT_METHOD(lstat:(NSString *)path callback:(RCTResponseSenderBlock) callback)
553
+ {
554
+ NSFileManager* fm = [NSFileManager defaultManager];
555
+ BOOL exist = NO;
556
+ BOOL isDir = NO;
557
+
558
+ path = [ReactNativeBlobUtilFS getPathOfAsset:path];
559
+
560
+ exist = [fm fileExistsAtPath:path isDirectory:&isDir];
561
+ if(exist == NO) {
562
+ callback(@[[NSString stringWithFormat:@"failed to lstat path `%@` because it does not exist or it is not a folder", path]]);
563
+ return ;
564
+ }
565
+ NSError * error = nil;
566
+ NSArray * files = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:path error:&error];
567
+
568
+ NSMutableArray * res = [[NSMutableArray alloc] init];
569
+ if(isDir == YES) {
570
+ for(NSString * p in files) {
571
+ NSString * filePath = [NSString stringWithFormat:@"%@/%@", path, p];
572
+ [res addObject:[ReactNativeBlobUtilFS stat:filePath error:&error]];
573
+ }
574
+ }
575
+ else {
576
+ [res addObject:[ReactNativeBlobUtilFS stat:path error:&error]];
577
+ }
578
+
579
+ if(error == nil)
580
+ callback(@[[NSNull null], res == nil ? [NSNull null] :res ]);
581
+ else
582
+ callback(@[[error localizedDescription], [NSNull null]]);
583
+
584
+ }
585
+
586
+ #pragma mark - fs.cp
587
+ // Signature for the Old Architecture
588
+ RCT_EXPORT_METHOD(cp:(NSString*)src toPath:(NSString *)dest callback:(RCTResponseSenderBlock) callback)
589
+ {
590
+ [self cp:src dest:dest callback:callback];
591
+ }
592
+
593
+ // Signature for the New Architecture. Codegen can't change the resolve/reject param names and
594
+ // If we change the RCT_EXPORT_METHOD we are going to introduce braking changes we may avoid.
595
+ - (void)cp:(NSString *)src
596
+ dest:(NSString *)dest
597
+ callback:(RCTResponseSenderBlock)callback
598
+ {
599
+ // path = [ReactNativeBlobUtilFS getPathOfAsset:path];
600
+ [ReactNativeBlobUtilFS getPathFromUri:src completionHandler:^(NSString *path, ALAssetRepresentation *asset) {
601
+ NSError * error = nil;
602
+ if(path == nil)
603
+ {
604
+ [ReactNativeBlobUtilFS writeAssetToPath:asset dest:dest];
605
+ callback(@[[NSNull null], @YES]);
606
+ }
607
+ else
608
+ {
609
+ // If the destination exists there will be an error
610
+ BOOL result = [[NSFileManager defaultManager] copyItemAtURL:[NSURL fileURLWithPath:path] toURL:[NSURL fileURLWithPath:dest] error:&error];
611
+
612
+ if(error == nil)
613
+ callback(@[[NSNull null], @YES]);
614
+ else
615
+ callback(@[[error localizedDescription], @NO]);
616
+ }
617
+ }];
618
+ }
619
+
620
+ #pragma mark - fs.mv
621
+ // Signature for the Old Architecture
622
+ RCT_EXPORT_METHOD(mv:(NSString *)path toPath:(NSString *)dest callback:(RCTResponseSenderBlock) callback)
623
+ {
624
+ [self mv:path dest:dest callback:callback];
625
+ }
626
+
627
+ // Signature for the New Architecture. Codegen can't change the resolve/reject param names and
628
+ // If we change the RCT_EXPORT_METHOD we are going to introduce braking changes we may avoid.
629
+ - (void)mv:(NSString *)path
630
+ dest:(NSString *)dest
631
+ callback:(RCTResponseSenderBlock)callback
632
+ {
633
+ NSError * error = nil;
634
+ BOOL result = [[NSFileManager defaultManager] moveItemAtURL:[NSURL fileURLWithPath:path] toURL:[NSURL fileURLWithPath:dest] error:&error];
635
+
636
+ if(error == nil)
637
+ callback(@[[NSNull null], @YES]);
638
+ else
639
+ callback(@[[error localizedDescription], @NO]);
640
+
641
+ }
642
+
643
+ #pragma mark - fs.mkdir
644
+ RCT_EXPORT_METHOD(mkdir:(NSString *)path resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
645
+ {
646
+ [self mkdir:path resolve:resolve reject:reject];
647
+ }
648
+
649
+ - (void)mkdir:(NSString *)path
650
+ resolve:(RCTPromiseResolveBlock)resolve
651
+ reject:(RCTPromiseRejectBlock)reject
652
+ {
653
+ [ReactNativeBlobUtilFS mkdir:path resolver:resolve rejecter:reject];
654
+ }
655
+
656
+ #pragma mark - fs.readFile
657
+ // Signature for the Old Architecture
658
+ RCT_EXPORT_METHOD(readFile:(NSString *)path
659
+ encoding:(NSString *)encoding
660
+ transformFile:(BOOL) transformFile
661
+ resolver:(RCTPromiseResolveBlock)resolve
662
+ rejecter:(RCTPromiseRejectBlock)reject)
663
+ {
664
+ [self readFile:path encoding:encoding transformFile:transformFile resolve:resolve reject:reject];
665
+ }
666
+
667
+ // Signature for the New Architecture. Codegen can't change the resolve/reject param names and
668
+ // If we change the RCT_EXPORT_METHOD we are going to introduce braking changes we may avoid.
669
+ - (void)readFile:(NSString *)path
670
+ encoding:(NSString *)encoding
671
+ transformFile:(BOOL)transformFile
672
+ resolve:(RCTPromiseResolveBlock)resolve
673
+ reject:(RCTPromiseRejectBlock)reject
674
+ {
675
+
676
+ [ReactNativeBlobUtilFS readFile:path encoding:encoding transformFile:transformFile onComplete:^(NSData * content, NSString * code, NSString * err) {
677
+ if(err != nil) {
678
+ reject(code, err, nil);
679
+ return;
680
+ }
681
+ if([encoding isEqualToString:@"ascii"]) {
682
+ resolve((NSMutableArray *)content);
683
+ } else if([encoding isEqualToString:@"base64"]) {
684
+ resolve([content base64EncodedStringWithOptions:0]);
685
+ } else {
686
+ resolve([[NSString alloc] initWithData:content encoding:NSUTF8StringEncoding]);
687
+ }
688
+ }];
689
+ }
690
+
691
+ #pragma mark - fs.hash
692
+ // Signature for the Old Architecture
693
+ RCT_EXPORT_METHOD(hash:(NSString *)path
694
+ algorithm:(NSString *)algorithm
695
+ resolver:(RCTPromiseResolveBlock)resolve
696
+ rejecter:(RCTPromiseRejectBlock)reject)
697
+ {
698
+ [self hash:path algorithm:algorithm resolve:resolve reject:reject];
699
+ }
700
+
701
+ // Signature for the New Architecture. Codegen can't change the resolve/reject param names and
702
+ // If we change the RCT_EXPORT_METHOD we are going to introduce braking changes we may avoid.
703
+ - (void)hash:(NSString *)path
704
+ algorithm:(NSString *)algorithm
705
+ resolve:(RCTPromiseResolveBlock)resolve
706
+ reject:(RCTPromiseRejectBlock)reject
707
+ {
708
+ [ReactNativeBlobUtilFS hash:path algorithm:[NSString stringWithString:algorithm] resolver:resolve rejecter:reject];
709
+ }
710
+
711
+ #pragma mark - fs.readStream
712
+ RCT_EXPORT_METHOD(readStream:(NSString *)path encoding:(NSString *)encoding bufferSize:(int)bufferSize tick:(int)tick streamId:(NSString *)streamId)
713
+ {
714
+ if(bufferSize == 0) {
715
+ if([[encoding lowercaseString] isEqualToString:@"base64"])
716
+ bufferSize = 4095;
717
+ else
718
+ bufferSize = 4096;
719
+ }
720
+
721
+ dispatch_async(fsQueue, ^{
722
+ [ReactNativeBlobUtilFS readStream:path encoding:encoding bufferSize:bufferSize tick:tick streamId:streamId baseModule:self];
723
+ });
724
+ }
725
+
726
+ #pragma mark - fs.getEnvironmentDirs
727
+ RCT_EXPORT_METHOD(getEnvironmentDirs:(RCTResponseSenderBlock) callback)
728
+ {
729
+
730
+ callback(@[
731
+ [ReactNativeBlobUtilFS getDocumentDir],
732
+ [ReactNativeBlobUtilFS getCacheDir],
733
+ ]);
734
+ }
735
+
736
+ #pragma mark - net.cancelRequest
737
+ RCT_EXPORT_METHOD(cancelRequest:(NSString *)taskId callback:(RCTResponseSenderBlock)callback) {
738
+ [[ReactNativeBlobUtilNetwork sharedInstance] cancelRequest:taskId];
739
+ callback(@[[NSNull null], taskId]);
740
+
741
+ }
742
+
743
+ #pragma mark - net.enableProgressReport
744
+ RCT_EXPORT_METHOD(enableProgressReport:(NSString *)taskId interval:(nonnull NSNumber*)interval count:(nonnull NSNumber*)count)
745
+ {
746
+
747
+ ReactNativeBlobUtilProgress * cfg = [[ReactNativeBlobUtilProgress alloc] initWithType:Download interval:interval count:count];
748
+ [[ReactNativeBlobUtilNetwork sharedInstance] enableProgressReport:taskId config:cfg];
749
+ }
750
+
751
+ #pragma mark - net.enableUploadProgressReport
752
+ RCT_EXPORT_METHOD(enableUploadProgressReport:(NSString *)taskId interval:(nonnull NSNumber*)interval count:(nonnull NSNumber*)count)
753
+ {
754
+ ReactNativeBlobUtilProgress * cfg = [[ReactNativeBlobUtilProgress alloc] initWithType:Upload interval:interval count:count];
755
+ [[ReactNativeBlobUtilNetwork sharedInstance] enableUploadProgress:taskId config:cfg];
756
+ }
757
+
758
+ #pragma mark - fs.slice
759
+ // Signature for the Old Architecture
760
+ RCT_EXPORT_METHOD(slice:(NSString *)src dest:(NSString *)dest start:(nonnull NSNumber *)start end:(nonnull NSNumber *)end resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
761
+ {
762
+ [self slice:src dest:dest start:start.doubleValue end:end.doubleValue resolve:resolve reject:reject];
763
+ }
764
+
765
+ // Signature for the New Architecture. Codegen can't change the resolve/reject param names and
766
+ // If we change the RCT_EXPORT_METHOD we are going to introduce braking changes we may avoid.
767
+ - (void)slice:(NSString *)src
768
+ dest:(NSString *)dest
769
+ start:(double)start
770
+ end:(double)end
771
+ resolve:(RCTPromiseResolveBlock)resolve
772
+ reject:(RCTPromiseRejectBlock)reject
773
+ {
774
+ [ReactNativeBlobUtilFS slice:src dest:dest start:@(start) end:@(end) encode:@"" resolver:resolve rejecter:reject];
775
+ }
776
+
777
+ // Signature for the Old Architecture
778
+ RCT_EXPORT_METHOD(presentOptionsMenu:(NSString*)uri scheme:(NSString *)scheme resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
779
+ {
780
+ [self presentOptionsMenu:uri scheme:scheme resolve:resolve reject:reject];
781
+ }
782
+
783
+ // Signature for the New Architecture. Codegen can't change the resolve/reject param names and
784
+ // If we change the RCT_EXPORT_METHOD we are going to introduce braking changes we may avoid.
785
+ - (void)presentOptionsMenu:(NSString *)uri
786
+ scheme:(NSString *)scheme
787
+ resolve:(RCTPromiseResolveBlock)resolve
788
+ reject:(RCTPromiseRejectBlock)reject
789
+ {
790
+ NSString * utf8uri = [uri stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
791
+ NSURL * url = [[NSURL alloc] initWithString:utf8uri];
792
+ // NSURL * url = [[NSURL alloc] initWithString:uri];
793
+ documentController = [UIDocumentInteractionController interactionControllerWithURL:url];
794
+ UIViewController *rootCtrl = [[[[UIApplication sharedApplication] delegate] window] rootViewController];
795
+ documentController.delegate = self;
796
+ if(scheme == nil || [[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:scheme]]) {
797
+ CGRect rect = CGRectMake(0.0, 0.0, 0.0, 0.0);
798
+ dispatch_sync(dispatch_get_main_queue(), ^{
799
+ [documentController presentOptionsMenuFromRect:rect inView:rootCtrl.view animated:YES];
800
+ });
801
+ resolve(@[[NSNull null]]);
802
+ } else {
803
+ reject(@"EINVAL", @"scheme is not supported", nil);
804
+ }
805
+ }
806
+
807
+ // Signature for the Old Architecture
808
+ RCT_EXPORT_METHOD(presentOpenInMenu:(NSString*)uri scheme:(NSString *)scheme resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
809
+ {
810
+ [self presentOpenInMenu:uri scheme:scheme resolve:resolve reject:reject];
811
+ }
812
+
813
+ // Signature for the New Architecture. Codegen can't change the resolve/reject param names and
814
+ // If we change the RCT_EXPORT_METHOD we are going to introduce braking changes we may avoid.
815
+ - (void)presentOpenInMenu:(NSString *)uri
816
+ scheme:(NSString *)scheme
817
+ resolve:(RCTPromiseResolveBlock)resolve
818
+ reject:(RCTPromiseRejectBlock)reject
819
+ {
820
+ NSString * utf8uri = [uri stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
821
+ NSURL * url = [[NSURL alloc] initWithString:utf8uri];
822
+ documentController = [UIDocumentInteractionController interactionControllerWithURL:url];
823
+ UIViewController *rootCtrl = [[[[UIApplication sharedApplication] delegate] window] rootViewController];
824
+ documentController.delegate = self;
825
+ if(scheme == nil || [[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:scheme]]) {
826
+ CGRect rect = CGRectMake(0.0, 0.0, 0.0, 0.0);
827
+ dispatch_sync(dispatch_get_main_queue(), ^{
828
+ [documentController presentOpenInMenuFromRect:rect inView:rootCtrl.view animated:YES];
829
+ });
830
+ resolve(@[[NSNull null]]);
831
+ } else {
832
+ reject(@"EINVAL", @"scheme is not supported", nil);
833
+ }
834
+ }
835
+
836
+ # pragma mark - open file with UIDocumentInteractionController and delegate
837
+ // Signature for the Old Architecture
838
+ RCT_EXPORT_METHOD(presentPreview:(NSString*)uri scheme:(NSString *)scheme resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
839
+ {
840
+ [self presentPreview:uri scheme:scheme resolve:resolve reject:reject];
841
+ }
842
+
843
+ // Signature for the New Architecture. Codegen can't change the resolve/reject param names and
844
+ // If we change the RCT_EXPORT_METHOD we are going to introduce braking changes we may avoid.
845
+ - (void)presentPreview:(NSString *)uri
846
+ scheme:(NSString *)scheme
847
+ resolve:(RCTPromiseResolveBlock)resolve
848
+ reject:(RCTPromiseRejectBlock)reject
849
+ {
850
+ NSString * utf8uri = [uri stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
851
+ NSURL * url = [[NSURL alloc] initWithString:utf8uri];
852
+ // NSURL * url = [[NSURL alloc] initWithString:uri];
853
+ documentController = [UIDocumentInteractionController interactionControllerWithURL:url];
854
+ documentController.delegate = self;
855
+
856
+ if(scheme == nil || [[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:scheme]]) {
857
+ dispatch_sync(dispatch_get_main_queue(), ^{
858
+ if([documentController presentPreviewAnimated:YES]) {
859
+ resolve(@[[NSNull null]]);
860
+ } else {
861
+ reject(@"EINVAL", @"document is not supported", nil);
862
+ }
863
+ });
864
+ } else {
865
+ reject(@"EINVAL", @"scheme is not supported", nil);
866
+ }
867
+ }
868
+
869
+ # pragma mark - exclude from backup key
870
+
871
+ RCT_EXPORT_METHOD(excludeFromBackupKey:(NSString *)url resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
872
+ {
873
+ [self excludeFromBackupKey:url resolve:resolve reject:reject];
874
+ }
875
+
876
+ - (void)excludeFromBackupKey:(NSString *)url
877
+ resolve:(RCTPromiseResolveBlock)resolve
878
+ reject:(RCTPromiseRejectBlock)reject
879
+ {
880
+ NSError *error = nil;
881
+ [ [NSURL URLWithString:url] setResourceValue:[NSNumber numberWithBool:YES] forKey:NSURLIsExcludedFromBackupKey error:&error];
882
+ if(!error)
883
+ {
884
+ resolve(@[[NSNull null]]);
885
+ } else {
886
+ reject(@"EUNSPECIFIED", [error description], nil);
887
+ }
888
+
889
+ }
890
+
891
+
892
+ RCT_EXPORT_METHOD(df:(RCTResponseSenderBlock)callback)
893
+ {
894
+ [ReactNativeBlobUtilFS df:callback];
895
+ }
896
+
897
+ - (UIViewController *)documentInteractionControllerViewControllerForPreview: (UIDocumentInteractionController *) controller
898
+ {
899
+ UIWindow *window = [UIApplication sharedApplication].keyWindow;
900
+ return window.rootViewController;
901
+ }
902
+
903
+ # pragma mark - Android Only methods
904
+ // These methods are required because in the New Arch we have a single spec for both platforms
905
+ - (void)actionViewIntent:(NSString *) path
906
+ mime:(NSString *) mime
907
+ chooserTitle:(NSString *) chooserTitle
908
+ resolve:(RCTPromiseResolveBlock)resolve
909
+ reject:(RCTPromiseRejectBlock)reject
910
+ {
911
+ reject(@"ENOT_SUPPORTED", @"This method is not supported on iOS", nil);
912
+ }
913
+
914
+ - (void)addCompleteDownload:(NSDictionary *)config
915
+ resolve:(RCTPromiseResolveBlock)resolve
916
+ reject:(RCTPromiseRejectBlock)reject
917
+ {
918
+ reject(@"ENOT_SUPPORTED", @"This method is not supported on iOS", nil);
919
+ }
920
+
921
+ - (void)copyToInternal:(NSString *)contentUri
922
+ destpath:(NSString *) destpath
923
+ resolve:(RCTPromiseResolveBlock)resolve
924
+ reject:(RCTPromiseRejectBlock)reject
925
+ {
926
+ reject(@"ENOT_SUPPORTED", @"This method is not supported on iOS", nil);
927
+ }
928
+ - (void)copyToMediaStore:(NSDictionary *)filedata
929
+ mt:(NSString *) mt
930
+ path:(NSString *) path
931
+ resolve:(RCTPromiseResolveBlock)resolve
932
+ reject:(RCTPromiseRejectBlock)reject
933
+ {
934
+ reject(@"ENOT_SUPPORTED", @"This method is not supported on iOS", nil);
935
+ }
936
+
937
+ - (void)createMediaFile:(NSDictionary *)filedata
938
+ mt:(NSString *) mt
939
+ resolve:(RCTPromiseResolveBlock)resolve
940
+ reject:(RCTPromiseRejectBlock)reject
941
+ {
942
+ reject(@"ENOT_SUPPORTED", @"This method is not supported on iOS", nil);
943
+ }
944
+
945
+ - (void)getBlob:(NSString *)contentUri
946
+ encoding:(NSString *)encoding
947
+ resolve:(RCTPromiseResolveBlock)resolve
948
+ reject:(RCTPromiseRejectBlock)reject
949
+ {
950
+ reject(@"ENOT_SUPPORTED", @"This method is not supported on iOS", nil);
951
+ }
952
+
953
+ - (void)getContentIntent:(NSString *)mime
954
+ resolve:(RCTPromiseResolveBlock)resolve
955
+ reject:(RCTPromiseRejectBlock)reject
956
+ {
957
+ reject(@"ENOT_SUPPORTED", @"This method is not supported on iOS", nil);
958
+ }
959
+ - (void)getSDCardDir:(RCTPromiseResolveBlock)resolve
960
+ reject:(RCTPromiseRejectBlock)reject
961
+ {
962
+ reject(@"ENOT_SUPPORTED", @"This method is not supported on iOS", nil);
963
+ }
964
+ - (void)getSDCardApplicationDir:(RCTPromiseResolveBlock)resolve
965
+ reject:(RCTPromiseRejectBlock)reject
966
+ {
967
+ reject(@"ENOT_SUPPORTED", @"This method is not supported on iOS", nil);
968
+ }
969
+ - (void)scanFile:(NSArray *)pairs
970
+ callback:(RCTResponseSenderBlock)callback
971
+ {
972
+ callback(@[@"Scan file method not supported in iOS"]);
973
+ }
974
+ - (void)writeToMediaFile:(NSString *)fileUri
975
+ path:(NSString *)path
976
+ transformFile:(BOOL)transformFile
977
+ resolve:(RCTPromiseResolveBlock)resolve
978
+ reject:(RCTPromiseRejectBlock)reject
979
+ {
980
+ reject(@"ENOT_SUPPORTED", @"This method is not supported on iOS", nil);
981
+ }
982
+
983
+ # pragma mark - New Architecture
984
+ #if RCT_NEW_ARCH_ENABLED
985
+ - (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:
986
+ (const facebook::react::ObjCTurboModule::InitParams &)params
987
+ {
988
+ return std::make_shared<facebook::react::NativeBlobUtilsSpecJSI>(params);
989
+ }
990
+ #endif
991
+
992
+ @end