react-native-blob-util 0.19.0 → 0.19.2
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.
- package/.eslintrc.js +56 -56
- package/LICENSE +21 -21
- package/Migration.md +41 -41
- package/README.md +1071 -1071
- package/android/gradle.properties +1 -1
- package/android/proguard-rules.pro +17 -17
- package/android/src/main/AndroidManifest.xml +39 -40
- package/android/src/main/java/com/ReactNativeBlobUtil/ReactNativeBlobUtilConfig.java +57 -57
- package/android/src/main/java/com/ReactNativeBlobUtil/ReactNativeBlobUtilConst.java +20 -20
- package/android/src/main/java/com/ReactNativeBlobUtil/ReactNativeBlobUtilFS.java +2 -2
- package/android/src/main/java/com/ReactNativeBlobUtil/ReactNativeBlobUtilFileTransformer.java +9 -9
- package/android/src/main/java/com/ReactNativeBlobUtil/ReactNativeBlobUtilImpl.java +431 -431
- package/android/src/main/java/com/ReactNativeBlobUtil/ReactNativeBlobUtilProgressConfig.java +39 -39
- package/android/src/main/java/com/ReactNativeBlobUtil/ReactNativeBlobUtilReq.java +972 -968
- package/android/src/main/java/com/ReactNativeBlobUtil/Response/ReactNativeBlobUtilDefaultResp.java +98 -98
- package/android/src/main/java/com/ReactNativeBlobUtil/Response/ReactNativeBlobUtilFileResp.java +157 -157
- package/android/src/main/java/com/ReactNativeBlobUtil/Utils/FileDescription.java +19 -19
- package/android/src/main/java/com/ReactNativeBlobUtil/Utils/FileProvider.java +4 -4
- package/android/src/main/java/com/ReactNativeBlobUtil/Utils/MimeType.java +70 -70
- package/android/src/main/java/com/ReactNativeBlobUtil/Utils/PathResolver.java +223 -223
- package/android/src/main/java/com/ReactNativeBlobUtil/Utils/Tls12SocketFactory.java +68 -68
- package/android/src/main/res/values/strings.xml +3 -3
- package/android/src/main/res/xml/provider_paths.xml +12 -12
- package/android/src/newarch/java/com/ReactNativeBlobUtil/ReactNativeBlobUtil.java +1 -1
- package/android.js +58 -58
- package/class/ReactNativeBlobUtilCanceledFetchError.js +9 -9
- package/class/ReactNativeBlobUtilFile.js +5 -5
- package/class/ReactNativeBlobUtilReadStream.js +84 -84
- package/class/ReactNativeBlobUtilSession.js +68 -68
- package/class/ReactNativeBlobUtilWriteStream.js +50 -50
- package/class/StatefulPromise.js +7 -7
- package/codegenSpecs/NativeBlobUtils.js +86 -82
- package/components/Fetch.onPress.js +10 -10
- package/components/Fetch.when.js +15 -15
- package/fetch.js +344 -344
- package/fs.js +480 -480
- package/index.d.ts +871 -871
- package/index.js +64 -64
- package/index.js.flow +191 -191
- package/index.web.js +1 -1
- package/ios/ReactNativeBlobUtil/ReactNativeBlobUtil.h +55 -55
- package/ios/ReactNativeBlobUtil/ReactNativeBlobUtil.mm +993 -993
- package/ios/ReactNativeBlobUtil.xcodeproj/project.pbxproj +403 -403
- package/ios/ReactNativeBlobUtilConst.h +58 -58
- package/ios/ReactNativeBlobUtilConst.mm +47 -47
- package/ios/ReactNativeBlobUtilFS.h +108 -108
- package/ios/ReactNativeBlobUtilFS.mm +977 -977
- package/ios/ReactNativeBlobUtilFileTransformer.h +23 -23
- package/ios/ReactNativeBlobUtilFileTransformer.mm +20 -20
- package/ios/ReactNativeBlobUtilNetwork.h +49 -49
- package/ios/ReactNativeBlobUtilNetwork.mm +159 -159
- package/ios/ReactNativeBlobUtilProgress.h +32 -32
- package/ios/ReactNativeBlobUtilProgress.mm +57 -57
- package/ios/ReactNativeBlobUtilReqBuilder.h +37 -37
- package/ios/ReactNativeBlobUtilReqBuilder.mm +292 -292
- package/ios/ReactNativeBlobUtilRequest.h +48 -48
- package/ios/ReactNativeBlobUtilRequest.mm +535 -535
- package/ios.js +61 -61
- package/json-stream.js +42 -42
- package/lib/oboe-browser.js +2703 -2703
- package/mediacollection.js +36 -36
- package/package.json +55 -55
- package/polyfill/Blob.js +362 -362
- package/polyfill/Event.js +11 -11
- package/polyfill/EventTarget.js +78 -78
- package/polyfill/Fetch.js +219 -219
- package/polyfill/File.js +27 -27
- package/polyfill/FileReader.js +91 -91
- package/polyfill/ProgressEvent.js +32 -32
- package/polyfill/XMLHttpRequest.js +466 -466
- package/polyfill/XMLHttpRequestEventTarget.js +126 -126
- package/polyfill/index.js +11 -11
- package/react-native-blob-util.podspec +45 -45
- package/types.js +69 -69
- package/utils/log.js +40 -40
- package/utils/unicode.js +7 -7
- package/utils/uri.js +33 -33
- package/utils/uuid.js +4 -4
- package/windows/README.md +2 -2
- package/windows/ReactNativeBlobUtil/PropertySheet.props +15 -15
- package/windows/ReactNativeBlobUtil/ReactNativeBlobUtil.cpp +1701 -1693
- package/windows/ReactNativeBlobUtil/ReactNativeBlobUtil.def +3 -3
- package/windows/ReactNativeBlobUtil/ReactNativeBlobUtil.h +379 -366
- package/windows/ReactNativeBlobUtil/ReactNativeBlobUtil.vcxproj +181 -181
- package/windows/ReactNativeBlobUtil/ReactNativeBlobUtil.vcxproj.filters +31 -31
- package/windows/ReactNativeBlobUtil/ReactPackageProvider.cpp +15 -15
- package/windows/ReactNativeBlobUtil/ReactPackageProvider.h +20 -20
- package/windows/ReactNativeBlobUtil/ReactPackageProvider.idl +9 -9
- package/windows/ReactNativeBlobUtil/packages.config +3 -3
- package/windows/ReactNativeBlobUtil/pch.cpp +1 -1
- package/windows/ReactNativeBlobUtil/pch.h +3 -3
|
@@ -1,993 +1,993 @@
|
|
|
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
|
-
}
|
|
684
|
-
if([encoding isEqualToString:@"base64"]) {
|
|
685
|
-
resolve([content base64EncodedStringWithOptions:0]);
|
|
686
|
-
} else {
|
|
687
|
-
resolve([[NSString alloc] initWithData:content encoding:NSUTF8StringEncoding]);
|
|
688
|
-
}
|
|
689
|
-
}];
|
|
690
|
-
}
|
|
691
|
-
|
|
692
|
-
#pragma mark - fs.hash
|
|
693
|
-
// Signature for the Old Architecture
|
|
694
|
-
RCT_EXPORT_METHOD(hash:(NSString *)path
|
|
695
|
-
algorithm:(NSString *)algorithm
|
|
696
|
-
resolver:(RCTPromiseResolveBlock)resolve
|
|
697
|
-
rejecter:(RCTPromiseRejectBlock)reject)
|
|
698
|
-
{
|
|
699
|
-
[self hash:path algorithm:algorithm resolve:resolve reject:reject];
|
|
700
|
-
}
|
|
701
|
-
|
|
702
|
-
// Signature for the New Architecture. Codegen can't change the resolve/reject param names and
|
|
703
|
-
// If we change the RCT_EXPORT_METHOD we are going to introduce braking changes we may avoid.
|
|
704
|
-
- (void)hash:(NSString *)path
|
|
705
|
-
algorithm:(NSString *)algorithm
|
|
706
|
-
resolve:(RCTPromiseResolveBlock)resolve
|
|
707
|
-
reject:(RCTPromiseRejectBlock)reject
|
|
708
|
-
{
|
|
709
|
-
[ReactNativeBlobUtilFS hash:path algorithm:[NSString stringWithString:algorithm] resolver:resolve rejecter:reject];
|
|
710
|
-
}
|
|
711
|
-
|
|
712
|
-
#pragma mark - fs.readStream
|
|
713
|
-
RCT_EXPORT_METHOD(readStream:(NSString *)path encoding:(NSString *)encoding bufferSize:(int)bufferSize tick:(int)tick streamId:(NSString *)streamId)
|
|
714
|
-
{
|
|
715
|
-
if(bufferSize == 0) {
|
|
716
|
-
if([[encoding lowercaseString] isEqualToString:@"base64"])
|
|
717
|
-
bufferSize = 4095;
|
|
718
|
-
else
|
|
719
|
-
bufferSize = 4096;
|
|
720
|
-
}
|
|
721
|
-
|
|
722
|
-
dispatch_async(fsQueue, ^{
|
|
723
|
-
[ReactNativeBlobUtilFS readStream:path encoding:encoding bufferSize:bufferSize tick:tick streamId:streamId baseModule:self];
|
|
724
|
-
});
|
|
725
|
-
}
|
|
726
|
-
|
|
727
|
-
#pragma mark - fs.getEnvironmentDirs
|
|
728
|
-
RCT_EXPORT_METHOD(getEnvironmentDirs:(RCTResponseSenderBlock) callback)
|
|
729
|
-
{
|
|
730
|
-
|
|
731
|
-
callback(@[
|
|
732
|
-
[ReactNativeBlobUtilFS getDocumentDir],
|
|
733
|
-
[ReactNativeBlobUtilFS getCacheDir],
|
|
734
|
-
]);
|
|
735
|
-
}
|
|
736
|
-
|
|
737
|
-
#pragma mark - net.cancelRequest
|
|
738
|
-
RCT_EXPORT_METHOD(cancelRequest:(NSString *)taskId callback:(RCTResponseSenderBlock)callback) {
|
|
739
|
-
[[ReactNativeBlobUtilNetwork sharedInstance] cancelRequest:taskId];
|
|
740
|
-
callback(@[[NSNull null], taskId]);
|
|
741
|
-
|
|
742
|
-
}
|
|
743
|
-
|
|
744
|
-
#pragma mark - net.enableProgressReport
|
|
745
|
-
RCT_EXPORT_METHOD(enableProgressReport:(NSString *)taskId interval:(nonnull NSNumber*)interval count:(nonnull NSNumber*)count)
|
|
746
|
-
{
|
|
747
|
-
|
|
748
|
-
ReactNativeBlobUtilProgress * cfg = [[ReactNativeBlobUtilProgress alloc] initWithType:Download interval:interval count:count];
|
|
749
|
-
[[ReactNativeBlobUtilNetwork sharedInstance] enableProgressReport:taskId config:cfg];
|
|
750
|
-
}
|
|
751
|
-
|
|
752
|
-
#pragma mark - net.enableUploadProgressReport
|
|
753
|
-
RCT_EXPORT_METHOD(enableUploadProgressReport:(NSString *)taskId interval:(nonnull NSNumber*)interval count:(nonnull NSNumber*)count)
|
|
754
|
-
{
|
|
755
|
-
ReactNativeBlobUtilProgress * cfg = [[ReactNativeBlobUtilProgress alloc] initWithType:Upload interval:interval count:count];
|
|
756
|
-
[[ReactNativeBlobUtilNetwork sharedInstance] enableUploadProgress:taskId config:cfg];
|
|
757
|
-
}
|
|
758
|
-
|
|
759
|
-
#pragma mark - fs.slice
|
|
760
|
-
// Signature for the Old Architecture
|
|
761
|
-
RCT_EXPORT_METHOD(slice:(NSString *)src dest:(NSString *)dest start:(nonnull NSNumber *)start end:(nonnull NSNumber *)end resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
|
|
762
|
-
{
|
|
763
|
-
[self slice:src dest:dest start:start.doubleValue end:end.doubleValue resolve:resolve reject:reject];
|
|
764
|
-
}
|
|
765
|
-
|
|
766
|
-
// Signature for the New Architecture. Codegen can't change the resolve/reject param names and
|
|
767
|
-
// If we change the RCT_EXPORT_METHOD we are going to introduce braking changes we may avoid.
|
|
768
|
-
- (void)slice:(NSString *)src
|
|
769
|
-
dest:(NSString *)dest
|
|
770
|
-
start:(double)start
|
|
771
|
-
end:(double)end
|
|
772
|
-
resolve:(RCTPromiseResolveBlock)resolve
|
|
773
|
-
reject:(RCTPromiseRejectBlock)reject
|
|
774
|
-
{
|
|
775
|
-
[ReactNativeBlobUtilFS slice:src dest:dest start:@(start) end:@(end) encode:@"" resolver:resolve rejecter:reject];
|
|
776
|
-
}
|
|
777
|
-
|
|
778
|
-
// Signature for the Old Architecture
|
|
779
|
-
RCT_EXPORT_METHOD(presentOptionsMenu:(NSString*)uri scheme:(NSString *)scheme resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
|
|
780
|
-
{
|
|
781
|
-
[self presentOptionsMenu:uri scheme:scheme resolve:resolve reject:reject];
|
|
782
|
-
}
|
|
783
|
-
|
|
784
|
-
// Signature for the New Architecture. Codegen can't change the resolve/reject param names and
|
|
785
|
-
// If we change the RCT_EXPORT_METHOD we are going to introduce braking changes we may avoid.
|
|
786
|
-
- (void)presentOptionsMenu:(NSString *)uri
|
|
787
|
-
scheme:(NSString *)scheme
|
|
788
|
-
resolve:(RCTPromiseResolveBlock)resolve
|
|
789
|
-
reject:(RCTPromiseRejectBlock)reject
|
|
790
|
-
{
|
|
791
|
-
NSString * utf8uri = [uri stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
|
|
792
|
-
NSURL * url = [[NSURL alloc] initWithString:utf8uri];
|
|
793
|
-
// NSURL * url = [[NSURL alloc] initWithString:uri];
|
|
794
|
-
documentController = [UIDocumentInteractionController interactionControllerWithURL:url];
|
|
795
|
-
UIViewController *rootCtrl = [[[[UIApplication sharedApplication] delegate] window] rootViewController];
|
|
796
|
-
documentController.delegate = self;
|
|
797
|
-
if(scheme == nil || [[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:scheme]]) {
|
|
798
|
-
CGRect rect = CGRectMake(0.0, 0.0, 0.0, 0.0);
|
|
799
|
-
dispatch_sync(dispatch_get_main_queue(), ^{
|
|
800
|
-
[documentController presentOptionsMenuFromRect:rect inView:rootCtrl.view animated:YES];
|
|
801
|
-
});
|
|
802
|
-
resolve(@[[NSNull null]]);
|
|
803
|
-
} else {
|
|
804
|
-
reject(@"EINVAL", @"scheme is not supported", nil);
|
|
805
|
-
}
|
|
806
|
-
}
|
|
807
|
-
|
|
808
|
-
// Signature for the Old Architecture
|
|
809
|
-
RCT_EXPORT_METHOD(presentOpenInMenu:(NSString*)uri scheme:(NSString *)scheme resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
|
|
810
|
-
{
|
|
811
|
-
[self presentOpenInMenu:uri scheme:scheme resolve:resolve reject:reject];
|
|
812
|
-
}
|
|
813
|
-
|
|
814
|
-
// Signature for the New Architecture. Codegen can't change the resolve/reject param names and
|
|
815
|
-
// If we change the RCT_EXPORT_METHOD we are going to introduce braking changes we may avoid.
|
|
816
|
-
- (void)presentOpenInMenu:(NSString *)uri
|
|
817
|
-
scheme:(NSString *)scheme
|
|
818
|
-
resolve:(RCTPromiseResolveBlock)resolve
|
|
819
|
-
reject:(RCTPromiseRejectBlock)reject
|
|
820
|
-
{
|
|
821
|
-
NSString * utf8uri = [uri stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
|
|
822
|
-
NSURL * url = [[NSURL alloc] initWithString:utf8uri];
|
|
823
|
-
documentController = [UIDocumentInteractionController interactionControllerWithURL:url];
|
|
824
|
-
UIViewController *rootCtrl = [[[[UIApplication sharedApplication] delegate] window] rootViewController];
|
|
825
|
-
documentController.delegate = self;
|
|
826
|
-
if(scheme == nil || [[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:scheme]]) {
|
|
827
|
-
CGRect rect = CGRectMake(0.0, 0.0, 0.0, 0.0);
|
|
828
|
-
dispatch_sync(dispatch_get_main_queue(), ^{
|
|
829
|
-
[documentController presentOpenInMenuFromRect:rect inView:rootCtrl.view animated:YES];
|
|
830
|
-
});
|
|
831
|
-
resolve(@[[NSNull null]]);
|
|
832
|
-
} else {
|
|
833
|
-
reject(@"EINVAL", @"scheme is not supported", nil);
|
|
834
|
-
}
|
|
835
|
-
}
|
|
836
|
-
|
|
837
|
-
# pragma mark - open file with UIDocumentInteractionController and delegate
|
|
838
|
-
// Signature for the Old Architecture
|
|
839
|
-
RCT_EXPORT_METHOD(presentPreview:(NSString*)uri scheme:(NSString *)scheme resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
|
|
840
|
-
{
|
|
841
|
-
[self presentPreview:uri scheme:scheme resolve:resolve reject:reject];
|
|
842
|
-
}
|
|
843
|
-
|
|
844
|
-
// Signature for the New Architecture. Codegen can't change the resolve/reject param names and
|
|
845
|
-
// If we change the RCT_EXPORT_METHOD we are going to introduce braking changes we may avoid.
|
|
846
|
-
- (void)presentPreview:(NSString *)uri
|
|
847
|
-
scheme:(NSString *)scheme
|
|
848
|
-
resolve:(RCTPromiseResolveBlock)resolve
|
|
849
|
-
reject:(RCTPromiseRejectBlock)reject
|
|
850
|
-
{
|
|
851
|
-
NSString * utf8uri = [uri stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
|
|
852
|
-
NSURL * url = [[NSURL alloc] initWithString:utf8uri];
|
|
853
|
-
// NSURL * url = [[NSURL alloc] initWithString:uri];
|
|
854
|
-
documentController = [UIDocumentInteractionController interactionControllerWithURL:url];
|
|
855
|
-
documentController.delegate = self;
|
|
856
|
-
|
|
857
|
-
if(scheme == nil || [[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:scheme]]) {
|
|
858
|
-
dispatch_sync(dispatch_get_main_queue(), ^{
|
|
859
|
-
if([documentController presentPreviewAnimated:YES]) {
|
|
860
|
-
resolve(@[[NSNull null]]);
|
|
861
|
-
} else {
|
|
862
|
-
reject(@"EINVAL", @"document is not supported", nil);
|
|
863
|
-
}
|
|
864
|
-
});
|
|
865
|
-
} else {
|
|
866
|
-
reject(@"EINVAL", @"scheme is not supported", nil);
|
|
867
|
-
}
|
|
868
|
-
}
|
|
869
|
-
|
|
870
|
-
# pragma mark - exclude from backup key
|
|
871
|
-
|
|
872
|
-
RCT_EXPORT_METHOD(excludeFromBackupKey:(NSString *)url resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
|
|
873
|
-
{
|
|
874
|
-
[self excludeFromBackupKey:url resolve:resolve reject:reject];
|
|
875
|
-
}
|
|
876
|
-
|
|
877
|
-
- (void)excludeFromBackupKey:(NSString *)url
|
|
878
|
-
resolve:(RCTPromiseResolveBlock)resolve
|
|
879
|
-
reject:(RCTPromiseRejectBlock)reject
|
|
880
|
-
{
|
|
881
|
-
NSError *error = nil;
|
|
882
|
-
[ [NSURL URLWithString:url] setResourceValue:[NSNumber numberWithBool:YES] forKey:NSURLIsExcludedFromBackupKey error:&error];
|
|
883
|
-
if(!error)
|
|
884
|
-
{
|
|
885
|
-
resolve(@[[NSNull null]]);
|
|
886
|
-
} else {
|
|
887
|
-
reject(@"EUNSPECIFIED", [error description], nil);
|
|
888
|
-
}
|
|
889
|
-
|
|
890
|
-
}
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
RCT_EXPORT_METHOD(df:(RCTResponseSenderBlock)callback)
|
|
894
|
-
{
|
|
895
|
-
[ReactNativeBlobUtilFS df:callback];
|
|
896
|
-
}
|
|
897
|
-
|
|
898
|
-
- (UIViewController *)documentInteractionControllerViewControllerForPreview: (UIDocumentInteractionController *) controller
|
|
899
|
-
{
|
|
900
|
-
UIWindow *window = [UIApplication sharedApplication].keyWindow;
|
|
901
|
-
return window.rootViewController;
|
|
902
|
-
}
|
|
903
|
-
|
|
904
|
-
# pragma mark - Android Only methods
|
|
905
|
-
// These methods are required because in the New Arch we have a single spec for both platforms
|
|
906
|
-
- (void)actionViewIntent:(NSString *) path
|
|
907
|
-
mime:(NSString *) mime
|
|
908
|
-
chooserTitle:(NSString *) chooserTitle
|
|
909
|
-
resolve:(RCTPromiseResolveBlock)resolve
|
|
910
|
-
reject:(RCTPromiseRejectBlock)reject
|
|
911
|
-
{
|
|
912
|
-
reject(@"ENOT_SUPPORTED", @"This method is not supported on iOS", nil);
|
|
913
|
-
}
|
|
914
|
-
|
|
915
|
-
- (void)addCompleteDownload:(NSDictionary *)config
|
|
916
|
-
resolve:(RCTPromiseResolveBlock)resolve
|
|
917
|
-
reject:(RCTPromiseRejectBlock)reject
|
|
918
|
-
{
|
|
919
|
-
reject(@"ENOT_SUPPORTED", @"This method is not supported on iOS", nil);
|
|
920
|
-
}
|
|
921
|
-
|
|
922
|
-
- (void)copyToInternal:(NSString *)contentUri
|
|
923
|
-
destpath:(NSString *) destpath
|
|
924
|
-
resolve:(RCTPromiseResolveBlock)resolve
|
|
925
|
-
reject:(RCTPromiseRejectBlock)reject
|
|
926
|
-
{
|
|
927
|
-
reject(@"ENOT_SUPPORTED", @"This method is not supported on iOS", nil);
|
|
928
|
-
}
|
|
929
|
-
- (void)copyToMediaStore:(NSDictionary *)filedata
|
|
930
|
-
mt:(NSString *) mt
|
|
931
|
-
path:(NSString *) path
|
|
932
|
-
resolve:(RCTPromiseResolveBlock)resolve
|
|
933
|
-
reject:(RCTPromiseRejectBlock)reject
|
|
934
|
-
{
|
|
935
|
-
reject(@"ENOT_SUPPORTED", @"This method is not supported on iOS", nil);
|
|
936
|
-
}
|
|
937
|
-
|
|
938
|
-
- (void)createMediaFile:(NSDictionary *)filedata
|
|
939
|
-
mt:(NSString *) mt
|
|
940
|
-
resolve:(RCTPromiseResolveBlock)resolve
|
|
941
|
-
reject:(RCTPromiseRejectBlock)reject
|
|
942
|
-
{
|
|
943
|
-
reject(@"ENOT_SUPPORTED", @"This method is not supported on iOS", nil);
|
|
944
|
-
}
|
|
945
|
-
|
|
946
|
-
- (void)getBlob:(NSString *)contentUri
|
|
947
|
-
encoding:(NSString *)encoding
|
|
948
|
-
resolve:(RCTPromiseResolveBlock)resolve
|
|
949
|
-
reject:(RCTPromiseRejectBlock)reject
|
|
950
|
-
{
|
|
951
|
-
reject(@"ENOT_SUPPORTED", @"This method is not supported on iOS", nil);
|
|
952
|
-
}
|
|
953
|
-
|
|
954
|
-
- (void)getContentIntent:(NSString *)mime
|
|
955
|
-
resolve:(RCTPromiseResolveBlock)resolve
|
|
956
|
-
reject:(RCTPromiseRejectBlock)reject
|
|
957
|
-
{
|
|
958
|
-
reject(@"ENOT_SUPPORTED", @"This method is not supported on iOS", nil);
|
|
959
|
-
}
|
|
960
|
-
- (void)getSDCardDir:(RCTPromiseResolveBlock)resolve
|
|
961
|
-
reject:(RCTPromiseRejectBlock)reject
|
|
962
|
-
{
|
|
963
|
-
reject(@"ENOT_SUPPORTED", @"This method is not supported on iOS", nil);
|
|
964
|
-
}
|
|
965
|
-
- (void)getSDCardApplicationDir:(RCTPromiseResolveBlock)resolve
|
|
966
|
-
reject:(RCTPromiseRejectBlock)reject
|
|
967
|
-
{
|
|
968
|
-
reject(@"ENOT_SUPPORTED", @"This method is not supported on iOS", nil);
|
|
969
|
-
}
|
|
970
|
-
- (void)scanFile:(NSArray *)pairs
|
|
971
|
-
callback:(RCTResponseSenderBlock)callback
|
|
972
|
-
{
|
|
973
|
-
callback(@[@"Scan file method not supported in iOS"]);
|
|
974
|
-
}
|
|
975
|
-
- (void)writeToMediaFile:(NSString *)fileUri
|
|
976
|
-
path:(NSString *)path
|
|
977
|
-
transformFile:(BOOL)transformFile
|
|
978
|
-
resolve:(RCTPromiseResolveBlock)resolve
|
|
979
|
-
reject:(RCTPromiseRejectBlock)reject
|
|
980
|
-
{
|
|
981
|
-
reject(@"ENOT_SUPPORTED", @"This method is not supported on iOS", nil);
|
|
982
|
-
}
|
|
983
|
-
|
|
984
|
-
# pragma mark - New Architecture
|
|
985
|
-
#if RCT_NEW_ARCH_ENABLED
|
|
986
|
-
- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:
|
|
987
|
-
(const facebook::react::ObjCTurboModule::InitParams &)params
|
|
988
|
-
{
|
|
989
|
-
return std::make_shared<facebook::react::NativeBlobUtilsSpecJSI>(params);
|
|
990
|
-
}
|
|
991
|
-
#endif
|
|
992
|
-
|
|
993
|
-
@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
|
+
}
|
|
684
|
+
if([encoding isEqualToString:@"base64"]) {
|
|
685
|
+
resolve([content base64EncodedStringWithOptions:0]);
|
|
686
|
+
} else {
|
|
687
|
+
resolve([[NSString alloc] initWithData:content encoding:NSUTF8StringEncoding]);
|
|
688
|
+
}
|
|
689
|
+
}];
|
|
690
|
+
}
|
|
691
|
+
|
|
692
|
+
#pragma mark - fs.hash
|
|
693
|
+
// Signature for the Old Architecture
|
|
694
|
+
RCT_EXPORT_METHOD(hash:(NSString *)path
|
|
695
|
+
algorithm:(NSString *)algorithm
|
|
696
|
+
resolver:(RCTPromiseResolveBlock)resolve
|
|
697
|
+
rejecter:(RCTPromiseRejectBlock)reject)
|
|
698
|
+
{
|
|
699
|
+
[self hash:path algorithm:algorithm resolve:resolve reject:reject];
|
|
700
|
+
}
|
|
701
|
+
|
|
702
|
+
// Signature for the New Architecture. Codegen can't change the resolve/reject param names and
|
|
703
|
+
// If we change the RCT_EXPORT_METHOD we are going to introduce braking changes we may avoid.
|
|
704
|
+
- (void)hash:(NSString *)path
|
|
705
|
+
algorithm:(NSString *)algorithm
|
|
706
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
707
|
+
reject:(RCTPromiseRejectBlock)reject
|
|
708
|
+
{
|
|
709
|
+
[ReactNativeBlobUtilFS hash:path algorithm:[NSString stringWithString:algorithm] resolver:resolve rejecter:reject];
|
|
710
|
+
}
|
|
711
|
+
|
|
712
|
+
#pragma mark - fs.readStream
|
|
713
|
+
RCT_EXPORT_METHOD(readStream:(NSString *)path encoding:(NSString *)encoding bufferSize:(int)bufferSize tick:(int)tick streamId:(NSString *)streamId)
|
|
714
|
+
{
|
|
715
|
+
if(bufferSize == 0) {
|
|
716
|
+
if([[encoding lowercaseString] isEqualToString:@"base64"])
|
|
717
|
+
bufferSize = 4095;
|
|
718
|
+
else
|
|
719
|
+
bufferSize = 4096;
|
|
720
|
+
}
|
|
721
|
+
|
|
722
|
+
dispatch_async(fsQueue, ^{
|
|
723
|
+
[ReactNativeBlobUtilFS readStream:path encoding:encoding bufferSize:bufferSize tick:tick streamId:streamId baseModule:self];
|
|
724
|
+
});
|
|
725
|
+
}
|
|
726
|
+
|
|
727
|
+
#pragma mark - fs.getEnvironmentDirs
|
|
728
|
+
RCT_EXPORT_METHOD(getEnvironmentDirs:(RCTResponseSenderBlock) callback)
|
|
729
|
+
{
|
|
730
|
+
|
|
731
|
+
callback(@[
|
|
732
|
+
[ReactNativeBlobUtilFS getDocumentDir],
|
|
733
|
+
[ReactNativeBlobUtilFS getCacheDir],
|
|
734
|
+
]);
|
|
735
|
+
}
|
|
736
|
+
|
|
737
|
+
#pragma mark - net.cancelRequest
|
|
738
|
+
RCT_EXPORT_METHOD(cancelRequest:(NSString *)taskId callback:(RCTResponseSenderBlock)callback) {
|
|
739
|
+
[[ReactNativeBlobUtilNetwork sharedInstance] cancelRequest:taskId];
|
|
740
|
+
callback(@[[NSNull null], taskId]);
|
|
741
|
+
|
|
742
|
+
}
|
|
743
|
+
|
|
744
|
+
#pragma mark - net.enableProgressReport
|
|
745
|
+
RCT_EXPORT_METHOD(enableProgressReport:(NSString *)taskId interval:(nonnull NSNumber*)interval count:(nonnull NSNumber*)count)
|
|
746
|
+
{
|
|
747
|
+
|
|
748
|
+
ReactNativeBlobUtilProgress * cfg = [[ReactNativeBlobUtilProgress alloc] initWithType:Download interval:interval count:count];
|
|
749
|
+
[[ReactNativeBlobUtilNetwork sharedInstance] enableProgressReport:taskId config:cfg];
|
|
750
|
+
}
|
|
751
|
+
|
|
752
|
+
#pragma mark - net.enableUploadProgressReport
|
|
753
|
+
RCT_EXPORT_METHOD(enableUploadProgressReport:(NSString *)taskId interval:(nonnull NSNumber*)interval count:(nonnull NSNumber*)count)
|
|
754
|
+
{
|
|
755
|
+
ReactNativeBlobUtilProgress * cfg = [[ReactNativeBlobUtilProgress alloc] initWithType:Upload interval:interval count:count];
|
|
756
|
+
[[ReactNativeBlobUtilNetwork sharedInstance] enableUploadProgress:taskId config:cfg];
|
|
757
|
+
}
|
|
758
|
+
|
|
759
|
+
#pragma mark - fs.slice
|
|
760
|
+
// Signature for the Old Architecture
|
|
761
|
+
RCT_EXPORT_METHOD(slice:(NSString *)src dest:(NSString *)dest start:(nonnull NSNumber *)start end:(nonnull NSNumber *)end resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
|
|
762
|
+
{
|
|
763
|
+
[self slice:src dest:dest start:start.doubleValue end:end.doubleValue resolve:resolve reject:reject];
|
|
764
|
+
}
|
|
765
|
+
|
|
766
|
+
// Signature for the New Architecture. Codegen can't change the resolve/reject param names and
|
|
767
|
+
// If we change the RCT_EXPORT_METHOD we are going to introduce braking changes we may avoid.
|
|
768
|
+
- (void)slice:(NSString *)src
|
|
769
|
+
dest:(NSString *)dest
|
|
770
|
+
start:(double)start
|
|
771
|
+
end:(double)end
|
|
772
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
773
|
+
reject:(RCTPromiseRejectBlock)reject
|
|
774
|
+
{
|
|
775
|
+
[ReactNativeBlobUtilFS slice:src dest:dest start:@(start) end:@(end) encode:@"" resolver:resolve rejecter:reject];
|
|
776
|
+
}
|
|
777
|
+
|
|
778
|
+
// Signature for the Old Architecture
|
|
779
|
+
RCT_EXPORT_METHOD(presentOptionsMenu:(NSString*)uri scheme:(NSString *)scheme resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
|
|
780
|
+
{
|
|
781
|
+
[self presentOptionsMenu:uri scheme:scheme resolve:resolve reject:reject];
|
|
782
|
+
}
|
|
783
|
+
|
|
784
|
+
// Signature for the New Architecture. Codegen can't change the resolve/reject param names and
|
|
785
|
+
// If we change the RCT_EXPORT_METHOD we are going to introduce braking changes we may avoid.
|
|
786
|
+
- (void)presentOptionsMenu:(NSString *)uri
|
|
787
|
+
scheme:(NSString *)scheme
|
|
788
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
789
|
+
reject:(RCTPromiseRejectBlock)reject
|
|
790
|
+
{
|
|
791
|
+
NSString * utf8uri = [uri stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
|
|
792
|
+
NSURL * url = [[NSURL alloc] initWithString:utf8uri];
|
|
793
|
+
// NSURL * url = [[NSURL alloc] initWithString:uri];
|
|
794
|
+
documentController = [UIDocumentInteractionController interactionControllerWithURL:url];
|
|
795
|
+
UIViewController *rootCtrl = [[[[UIApplication sharedApplication] delegate] window] rootViewController];
|
|
796
|
+
documentController.delegate = self;
|
|
797
|
+
if(scheme == nil || [[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:scheme]]) {
|
|
798
|
+
CGRect rect = CGRectMake(0.0, 0.0, 0.0, 0.0);
|
|
799
|
+
dispatch_sync(dispatch_get_main_queue(), ^{
|
|
800
|
+
[documentController presentOptionsMenuFromRect:rect inView:rootCtrl.view animated:YES];
|
|
801
|
+
});
|
|
802
|
+
resolve(@[[NSNull null]]);
|
|
803
|
+
} else {
|
|
804
|
+
reject(@"EINVAL", @"scheme is not supported", nil);
|
|
805
|
+
}
|
|
806
|
+
}
|
|
807
|
+
|
|
808
|
+
// Signature for the Old Architecture
|
|
809
|
+
RCT_EXPORT_METHOD(presentOpenInMenu:(NSString*)uri scheme:(NSString *)scheme resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
|
|
810
|
+
{
|
|
811
|
+
[self presentOpenInMenu:uri scheme:scheme resolve:resolve reject:reject];
|
|
812
|
+
}
|
|
813
|
+
|
|
814
|
+
// Signature for the New Architecture. Codegen can't change the resolve/reject param names and
|
|
815
|
+
// If we change the RCT_EXPORT_METHOD we are going to introduce braking changes we may avoid.
|
|
816
|
+
- (void)presentOpenInMenu:(NSString *)uri
|
|
817
|
+
scheme:(NSString *)scheme
|
|
818
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
819
|
+
reject:(RCTPromiseRejectBlock)reject
|
|
820
|
+
{
|
|
821
|
+
NSString * utf8uri = [uri stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
|
|
822
|
+
NSURL * url = [[NSURL alloc] initWithString:utf8uri];
|
|
823
|
+
documentController = [UIDocumentInteractionController interactionControllerWithURL:url];
|
|
824
|
+
UIViewController *rootCtrl = [[[[UIApplication sharedApplication] delegate] window] rootViewController];
|
|
825
|
+
documentController.delegate = self;
|
|
826
|
+
if(scheme == nil || [[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:scheme]]) {
|
|
827
|
+
CGRect rect = CGRectMake(0.0, 0.0, 0.0, 0.0);
|
|
828
|
+
dispatch_sync(dispatch_get_main_queue(), ^{
|
|
829
|
+
[documentController presentOpenInMenuFromRect:rect inView:rootCtrl.view animated:YES];
|
|
830
|
+
});
|
|
831
|
+
resolve(@[[NSNull null]]);
|
|
832
|
+
} else {
|
|
833
|
+
reject(@"EINVAL", @"scheme is not supported", nil);
|
|
834
|
+
}
|
|
835
|
+
}
|
|
836
|
+
|
|
837
|
+
# pragma mark - open file with UIDocumentInteractionController and delegate
|
|
838
|
+
// Signature for the Old Architecture
|
|
839
|
+
RCT_EXPORT_METHOD(presentPreview:(NSString*)uri scheme:(NSString *)scheme resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
|
|
840
|
+
{
|
|
841
|
+
[self presentPreview:uri scheme:scheme resolve:resolve reject:reject];
|
|
842
|
+
}
|
|
843
|
+
|
|
844
|
+
// Signature for the New Architecture. Codegen can't change the resolve/reject param names and
|
|
845
|
+
// If we change the RCT_EXPORT_METHOD we are going to introduce braking changes we may avoid.
|
|
846
|
+
- (void)presentPreview:(NSString *)uri
|
|
847
|
+
scheme:(NSString *)scheme
|
|
848
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
849
|
+
reject:(RCTPromiseRejectBlock)reject
|
|
850
|
+
{
|
|
851
|
+
NSString * utf8uri = [uri stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
|
|
852
|
+
NSURL * url = [[NSURL alloc] initWithString:utf8uri];
|
|
853
|
+
// NSURL * url = [[NSURL alloc] initWithString:uri];
|
|
854
|
+
documentController = [UIDocumentInteractionController interactionControllerWithURL:url];
|
|
855
|
+
documentController.delegate = self;
|
|
856
|
+
|
|
857
|
+
if(scheme == nil || [[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:scheme]]) {
|
|
858
|
+
dispatch_sync(dispatch_get_main_queue(), ^{
|
|
859
|
+
if([documentController presentPreviewAnimated:YES]) {
|
|
860
|
+
resolve(@[[NSNull null]]);
|
|
861
|
+
} else {
|
|
862
|
+
reject(@"EINVAL", @"document is not supported", nil);
|
|
863
|
+
}
|
|
864
|
+
});
|
|
865
|
+
} else {
|
|
866
|
+
reject(@"EINVAL", @"scheme is not supported", nil);
|
|
867
|
+
}
|
|
868
|
+
}
|
|
869
|
+
|
|
870
|
+
# pragma mark - exclude from backup key
|
|
871
|
+
|
|
872
|
+
RCT_EXPORT_METHOD(excludeFromBackupKey:(NSString *)url resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
|
|
873
|
+
{
|
|
874
|
+
[self excludeFromBackupKey:url resolve:resolve reject:reject];
|
|
875
|
+
}
|
|
876
|
+
|
|
877
|
+
- (void)excludeFromBackupKey:(NSString *)url
|
|
878
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
879
|
+
reject:(RCTPromiseRejectBlock)reject
|
|
880
|
+
{
|
|
881
|
+
NSError *error = nil;
|
|
882
|
+
[ [NSURL URLWithString:url] setResourceValue:[NSNumber numberWithBool:YES] forKey:NSURLIsExcludedFromBackupKey error:&error];
|
|
883
|
+
if(!error)
|
|
884
|
+
{
|
|
885
|
+
resolve(@[[NSNull null]]);
|
|
886
|
+
} else {
|
|
887
|
+
reject(@"EUNSPECIFIED", [error description], nil);
|
|
888
|
+
}
|
|
889
|
+
|
|
890
|
+
}
|
|
891
|
+
|
|
892
|
+
|
|
893
|
+
RCT_EXPORT_METHOD(df:(RCTResponseSenderBlock)callback)
|
|
894
|
+
{
|
|
895
|
+
[ReactNativeBlobUtilFS df:callback];
|
|
896
|
+
}
|
|
897
|
+
|
|
898
|
+
- (UIViewController *)documentInteractionControllerViewControllerForPreview: (UIDocumentInteractionController *) controller
|
|
899
|
+
{
|
|
900
|
+
UIWindow *window = [UIApplication sharedApplication].keyWindow;
|
|
901
|
+
return window.rootViewController;
|
|
902
|
+
}
|
|
903
|
+
|
|
904
|
+
# pragma mark - Android Only methods
|
|
905
|
+
// These methods are required because in the New Arch we have a single spec for both platforms
|
|
906
|
+
- (void)actionViewIntent:(NSString *) path
|
|
907
|
+
mime:(NSString *) mime
|
|
908
|
+
chooserTitle:(NSString *) chooserTitle
|
|
909
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
910
|
+
reject:(RCTPromiseRejectBlock)reject
|
|
911
|
+
{
|
|
912
|
+
reject(@"ENOT_SUPPORTED", @"This method is not supported on iOS", nil);
|
|
913
|
+
}
|
|
914
|
+
|
|
915
|
+
- (void)addCompleteDownload:(NSDictionary *)config
|
|
916
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
917
|
+
reject:(RCTPromiseRejectBlock)reject
|
|
918
|
+
{
|
|
919
|
+
reject(@"ENOT_SUPPORTED", @"This method is not supported on iOS", nil);
|
|
920
|
+
}
|
|
921
|
+
|
|
922
|
+
- (void)copyToInternal:(NSString *)contentUri
|
|
923
|
+
destpath:(NSString *) destpath
|
|
924
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
925
|
+
reject:(RCTPromiseRejectBlock)reject
|
|
926
|
+
{
|
|
927
|
+
reject(@"ENOT_SUPPORTED", @"This method is not supported on iOS", nil);
|
|
928
|
+
}
|
|
929
|
+
- (void)copyToMediaStore:(NSDictionary *)filedata
|
|
930
|
+
mt:(NSString *) mt
|
|
931
|
+
path:(NSString *) path
|
|
932
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
933
|
+
reject:(RCTPromiseRejectBlock)reject
|
|
934
|
+
{
|
|
935
|
+
reject(@"ENOT_SUPPORTED", @"This method is not supported on iOS", nil);
|
|
936
|
+
}
|
|
937
|
+
|
|
938
|
+
- (void)createMediaFile:(NSDictionary *)filedata
|
|
939
|
+
mt:(NSString *) mt
|
|
940
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
941
|
+
reject:(RCTPromiseRejectBlock)reject
|
|
942
|
+
{
|
|
943
|
+
reject(@"ENOT_SUPPORTED", @"This method is not supported on iOS", nil);
|
|
944
|
+
}
|
|
945
|
+
|
|
946
|
+
- (void)getBlob:(NSString *)contentUri
|
|
947
|
+
encoding:(NSString *)encoding
|
|
948
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
949
|
+
reject:(RCTPromiseRejectBlock)reject
|
|
950
|
+
{
|
|
951
|
+
reject(@"ENOT_SUPPORTED", @"This method is not supported on iOS", nil);
|
|
952
|
+
}
|
|
953
|
+
|
|
954
|
+
- (void)getContentIntent:(NSString *)mime
|
|
955
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
956
|
+
reject:(RCTPromiseRejectBlock)reject
|
|
957
|
+
{
|
|
958
|
+
reject(@"ENOT_SUPPORTED", @"This method is not supported on iOS", nil);
|
|
959
|
+
}
|
|
960
|
+
- (void)getSDCardDir:(RCTPromiseResolveBlock)resolve
|
|
961
|
+
reject:(RCTPromiseRejectBlock)reject
|
|
962
|
+
{
|
|
963
|
+
reject(@"ENOT_SUPPORTED", @"This method is not supported on iOS", nil);
|
|
964
|
+
}
|
|
965
|
+
- (void)getSDCardApplicationDir:(RCTPromiseResolveBlock)resolve
|
|
966
|
+
reject:(RCTPromiseRejectBlock)reject
|
|
967
|
+
{
|
|
968
|
+
reject(@"ENOT_SUPPORTED", @"This method is not supported on iOS", nil);
|
|
969
|
+
}
|
|
970
|
+
- (void)scanFile:(NSArray *)pairs
|
|
971
|
+
callback:(RCTResponseSenderBlock)callback
|
|
972
|
+
{
|
|
973
|
+
callback(@[@"Scan file method not supported in iOS"]);
|
|
974
|
+
}
|
|
975
|
+
- (void)writeToMediaFile:(NSString *)fileUri
|
|
976
|
+
path:(NSString *)path
|
|
977
|
+
transformFile:(BOOL)transformFile
|
|
978
|
+
resolve:(RCTPromiseResolveBlock)resolve
|
|
979
|
+
reject:(RCTPromiseRejectBlock)reject
|
|
980
|
+
{
|
|
981
|
+
reject(@"ENOT_SUPPORTED", @"This method is not supported on iOS", nil);
|
|
982
|
+
}
|
|
983
|
+
|
|
984
|
+
# pragma mark - New Architecture
|
|
985
|
+
#if RCT_NEW_ARCH_ENABLED
|
|
986
|
+
- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:
|
|
987
|
+
(const facebook::react::ObjCTurboModule::InitParams &)params
|
|
988
|
+
{
|
|
989
|
+
return std::make_shared<facebook::react::NativeBlobUtilsSpecJSI>(params);
|
|
990
|
+
}
|
|
991
|
+
#endif
|
|
992
|
+
|
|
993
|
+
@end
|