Geen omschrijving

RNFetchBlob.m 21KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598
  1. //
  2. // RNFetchBlob.m
  3. //
  4. // Created by wkh237 on 2016/4/28.
  5. //
  6. #import "RNFetchBlob.h"
  7. #import "RNFetchBlobFS.h"
  8. #import "RNFetchBlobNetwork.h"
  9. #import "RNFetchBlobConst.h"
  10. #import "RNFetchBlobReqBuilder.h"
  11. #import "RNFetchBlobProgress.h"
  12. __strong RCTBridge * bridgeRef;
  13. dispatch_queue_t commonTaskQueue;
  14. dispatch_queue_t fsQueue;
  15. ////////////////////////////////////////
  16. //
  17. // Exported native methods
  18. //
  19. ////////////////////////////////////////
  20. #pragma mark RNFetchBlob exported methods
  21. @implementation RNFetchBlob
  22. @synthesize filePathPrefix;
  23. @synthesize documentController;
  24. @synthesize bridge = _bridge;
  25. - (dispatch_queue_t) methodQueue {
  26. if(commonTaskQueue == nil)
  27. commonTaskQueue = dispatch_queue_create("RNFetchBlob.queue", DISPATCH_QUEUE_SERIAL);
  28. return commonTaskQueue;
  29. }
  30. + (RCTBridge *)getRCTBridge
  31. {
  32. RCTRootView * rootView = [[UIApplication sharedApplication] keyWindow].rootViewController.view;
  33. return rootView.bridge;
  34. }
  35. + (BOOL)requiresMainQueueSetup {
  36. return NO;
  37. }
  38. RCT_EXPORT_MODULE();
  39. - (id) init {
  40. self = [super init];
  41. self.filePathPrefix = FILE_PREFIX;
  42. if(commonTaskQueue == nil)
  43. commonTaskQueue = dispatch_queue_create("RNFetchBlob.queue", DISPATCH_QUEUE_SERIAL);
  44. if(fsQueue == nil)
  45. fsQueue = dispatch_queue_create("RNFetchBlob.fs.queue", DISPATCH_QUEUE_SERIAL);
  46. BOOL isDir;
  47. // if temp folder not exists, create one
  48. if(![[NSFileManager defaultManager] fileExistsAtPath: [RNFetchBlobFS getTempPath] isDirectory:&isDir]) {
  49. [[NSFileManager defaultManager] createDirectoryAtPath:[RNFetchBlobFS getTempPath] withIntermediateDirectories:YES attributes:nil error:NULL];
  50. }
  51. bridgeRef = _bridge;
  52. [RNFetchBlobNetwork emitExpiredTasks];
  53. return self;
  54. }
  55. - (NSDictionary *)constantsToExport
  56. {
  57. return @{
  58. @"MainBundleDir" : [RNFetchBlobFS getMainBundleDir],
  59. @"DocumentDir": [RNFetchBlobFS getDocumentDir],
  60. @"CacheDir" : [RNFetchBlobFS getCacheDir]
  61. };
  62. }
  63. // Fetch blob data request
  64. RCT_EXPORT_METHOD(fetchBlobForm:(NSDictionary *)options
  65. taskId:(NSString *)taskId
  66. method:(NSString *)method
  67. url:(NSString *)url
  68. headers:(NSDictionary *)headers
  69. form:(NSArray *)form
  70. callback:(RCTResponseSenderBlock)callback)
  71. {
  72. [RNFetchBlobReqBuilder buildMultipartRequest:options
  73. taskId:taskId
  74. method:method
  75. url:url
  76. headers:headers
  77. form:form
  78. onComplete:^(__weak NSURLRequest *req, long bodyLength)
  79. {
  80. // something went wrong when building the request body
  81. if(req == nil)
  82. {
  83. callback(@[@"RNFetchBlob.fetchBlobForm failed to create request body"]);
  84. }
  85. // send HTTP request
  86. else
  87. {
  88. RNFetchBlobNetwork * utils = [[RNFetchBlobNetwork alloc] init];
  89. [utils sendRequest:options contentLength:bodyLength bridge:self.bridge taskId:taskId withRequest:req callback:callback];
  90. }
  91. }];
  92. }
  93. // Fetch blob data request
  94. RCT_EXPORT_METHOD(fetchBlob:(NSDictionary *)options
  95. taskId:(NSString *)taskId
  96. method:(NSString *)method
  97. url:(NSString *)url
  98. headers:(NSDictionary *)headers
  99. body:(NSString *)body callback:(RCTResponseSenderBlock)callback)
  100. {
  101. [RNFetchBlobReqBuilder buildOctetRequest:options
  102. taskId:taskId
  103. method:method
  104. url:url
  105. headers:headers
  106. body:body
  107. onComplete:^(NSURLRequest *req, long bodyLength)
  108. {
  109. // something went wrong when building the request body
  110. if(req == nil)
  111. {
  112. callback(@[@"RNFetchBlob.fetchBlob failed to create request body"]);
  113. }
  114. // send HTTP request
  115. else
  116. {
  117. __block RNFetchBlobNetwork * utils = [[RNFetchBlobNetwork alloc] init];
  118. [utils sendRequest:options contentLength:bodyLength bridge:self.bridge taskId:taskId withRequest:req callback:callback];
  119. }
  120. }];
  121. }
  122. #pragma mark - fs.createFile
  123. RCT_EXPORT_METHOD(createFile:(NSString *)path data:(NSString *)data encoding:(NSString *)encoding callback:(RCTResponseSenderBlock)callback) {
  124. NSFileManager * fm = [NSFileManager defaultManager];
  125. NSData * fileContent = nil;
  126. if([[encoding lowercaseString] isEqualToString:@"utf8"]) {
  127. fileContent = [[NSData alloc] initWithData:[data dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES]];
  128. }
  129. else if([[encoding lowercaseString] isEqualToString:@"base64"]) {
  130. fileContent = [[NSData alloc] initWithBase64EncodedData:data options:0];
  131. }
  132. else if([[encoding lowercaseString] isEqualToString:@"uri"]) {
  133. NSString * orgPath = [data stringByReplacingOccurrencesOfString:FILE_PREFIX withString:@""];
  134. fileContent = [[NSData alloc] initWithContentsOfFile:orgPath];
  135. }
  136. else {
  137. fileContent = [[NSData alloc] initWithData:[data dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES]];
  138. }
  139. BOOL success = [fm createFileAtPath:path contents:fileContent attributes:NULL];
  140. if(success == YES)
  141. callback(@[[NSNull null]]);
  142. else
  143. callback(@[[NSString stringWithFormat:@"failed to create new file at path %@ please ensure the folder exists"]]);
  144. }
  145. #pragma mark - fs.createFileASCII
  146. // method for create file with ASCII content
  147. RCT_EXPORT_METHOD(createFileASCII:(NSString *)path data:(NSArray *)dataArray callback:(RCTResponseSenderBlock)callback) {
  148. NSFileManager * fm = [NSFileManager defaultManager];
  149. NSMutableData * fileContent = [NSMutableData alloc];
  150. // prevent stack overflow, alloc on heap
  151. char * bytes = (char*) malloc([dataArray count]);
  152. for(int i = 0; i < dataArray.count; i++) {
  153. bytes[i] = [[dataArray objectAtIndex:i] charValue];
  154. }
  155. [fileContent appendBytes:bytes length:dataArray.count];
  156. BOOL success = [fm createFileAtPath:path contents:fileContent attributes:NULL];
  157. free(bytes);
  158. if(success == YES)
  159. callback(@[[NSNull null]]);
  160. else
  161. callback(@[[NSString stringWithFormat:@"failed to create new file at path %@ please ensure the folder exists"]]);
  162. }
  163. #pragma mark - fs.pathForAppGroup
  164. RCT_EXPORT_METHOD(pathForAppGroup:(NSString *)groupName
  165. resolver:(RCTPromiseResolveBlock)resolve
  166. rejecter:(RCTPromiseRejectBlock)reject)
  167. {
  168. NSString * path = [RNFetchBlobFS getPathForAppGroup:groupName];
  169. if(path) {
  170. resolve(path);
  171. } else {
  172. reject(@"RNFetchBlob file not found", @"could not find path for app group", nil);
  173. }
  174. }
  175. #pragma mark - fs.exists
  176. RCT_EXPORT_METHOD(exists:(NSString *)path callback:(RCTResponseSenderBlock)callback) {
  177. [RNFetchBlobFS exists:path callback:callback];
  178. }
  179. #pragma mark - fs.writeFile
  180. RCT_EXPORT_METHOD(writeFile:(NSString *)path encoding:(NSString *)encoding data:(NSString *)data append:(BOOL)append resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
  181. {
  182. [RNFetchBlobFS writeFile:path encoding:[NSString stringWithString:encoding] data:data append:append resolver:resolve rejecter:reject];
  183. }
  184. #pragma mark - fs.writeArray
  185. RCT_EXPORT_METHOD(writeFileArray:(NSString *)path data:(NSArray *)data append:(BOOL)append resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
  186. {
  187. [RNFetchBlobFS writeFileArray:path data:data append:append resolver:resolve rejecter:reject];
  188. }
  189. #pragma mark - fs.writeStream
  190. RCT_EXPORT_METHOD(writeStream:(NSString *)path withEncoding:(NSString *)encoding appendData:(BOOL)append callback:(RCTResponseSenderBlock)callback)
  191. {
  192. RNFetchBlobFS * fileStream = [[RNFetchBlobFS alloc] initWithBridgeRef:self.bridge];
  193. NSFileManager * fm = [NSFileManager defaultManager];
  194. BOOL isDir = nil;
  195. BOOL exist = [fm fileExistsAtPath:path isDirectory:&isDir];
  196. if( exist == NO || isDir == YES) {
  197. callback(@[[NSString stringWithFormat:@"target path `%@` may not exists or it's a folder", path]]);
  198. return;
  199. }
  200. NSString * streamId = [fileStream openWithPath:path encode:encoding appendData:append];
  201. callback(@[[NSNull null], streamId]);
  202. }
  203. #pragma mark - fs.writeArrayChunk
  204. RCT_EXPORT_METHOD(writeArrayChunk:(NSString *)streamId withArray:(NSArray *)dataArray callback:(RCTResponseSenderBlock) callback)
  205. {
  206. RNFetchBlobFS *fs = [[RNFetchBlobFS getFileStreams] valueForKey:streamId];
  207. char * bytes = (char *) malloc([dataArray count]);
  208. for(int i = 0; i < dataArray.count; i++) {
  209. bytes[i] = [[dataArray objectAtIndex:i] charValue];
  210. }
  211. NSMutableData * data = [NSMutableData alloc];
  212. [data appendBytes:bytes length:dataArray.count];
  213. [fs write:data];
  214. free(bytes);
  215. callback(@[[NSNull null]]);
  216. }
  217. #pragma mark - fs.writeChunk
  218. RCT_EXPORT_METHOD(writeChunk:(NSString *)streamId withData:(NSString *)data callback:(RCTResponseSenderBlock) callback)
  219. {
  220. RNFetchBlobFS *fs = [[RNFetchBlobFS getFileStreams] valueForKey:streamId];
  221. [fs writeEncodeChunk:data];
  222. callback(@[[NSNull null]]);
  223. }
  224. #pragma mark - fs.closeStream
  225. RCT_EXPORT_METHOD(closeStream:(NSString *)streamId callback:(RCTResponseSenderBlock) callback)
  226. {
  227. RNFetchBlobFS *fs = [[RNFetchBlobFS getFileStreams] valueForKey:streamId];
  228. [fs closeOutStream];
  229. callback(@[[NSNull null], @YES]);
  230. }
  231. #pragma mark - unlink
  232. RCT_EXPORT_METHOD(unlink:(NSString *)path callback:(RCTResponseSenderBlock) callback)
  233. {
  234. NSError * error = nil;
  235. NSString * tmpPath = nil;
  236. [[NSFileManager defaultManager] removeItemAtPath:path error:&error];
  237. if(error == nil || [[NSFileManager defaultManager] fileExistsAtPath:path] == NO)
  238. callback(@[[NSNull null]]);
  239. else
  240. callback(@[[NSString stringWithFormat:@"failed to unlink file or path at %@", path]]);
  241. }
  242. #pragma mark - fs.removeSession
  243. RCT_EXPORT_METHOD(removeSession:(NSArray *)paths callback:(RCTResponseSenderBlock) callback)
  244. {
  245. NSError * error = nil;
  246. NSString * tmpPath = nil;
  247. for(NSString * path in paths) {
  248. [[NSFileManager defaultManager] removeItemAtPath:path error:&error];
  249. if(error != nil) {
  250. callback(@[[NSString stringWithFormat:@"failed to remove session path at %@", path]]);
  251. return;
  252. }
  253. }
  254. callback(@[[NSNull null]]);
  255. }
  256. #pragma mark - fs.ls
  257. RCT_EXPORT_METHOD(ls:(NSString *)path callback:(RCTResponseSenderBlock) callback)
  258. {
  259. NSFileManager* fm = [NSFileManager defaultManager];
  260. BOOL exist = nil;
  261. BOOL isDir = nil;
  262. exist = [fm fileExistsAtPath:path isDirectory:&isDir];
  263. if(exist == NO || isDir == NO) {
  264. callback(@[[NSString stringWithFormat:@"failed to list path `%@` for it is not exist or it is not a folder", path]]);
  265. return ;
  266. }
  267. NSError * error = nil;
  268. NSArray * result = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:path error:&error];
  269. if(error == nil)
  270. callback(@[[NSNull null], result == nil ? [NSNull null] :result ]);
  271. else
  272. callback(@[[error localizedDescription], [NSNull null]]);
  273. }
  274. #pragma mark - fs.stat
  275. RCT_EXPORT_METHOD(stat:(NSString *)target callback:(RCTResponseSenderBlock) callback)
  276. {
  277. [RNFetchBlobFS getPathFromUri:target completionHandler:^(NSString *path, ALAssetRepresentation *asset) {
  278. __block NSMutableArray * result;
  279. if(path != nil)
  280. {
  281. NSFileManager* fm = [NSFileManager defaultManager];
  282. BOOL exist = nil;
  283. BOOL isDir = nil;
  284. NSError * error = nil;
  285. exist = [fm fileExistsAtPath:path isDirectory:&isDir];
  286. if(exist == NO) {
  287. callback(@[[NSString stringWithFormat:@"failed to stat path `%@` for it is not exist or it is not exist", path]]);
  288. return ;
  289. }
  290. result = [RNFetchBlobFS stat:path error:&error];
  291. if(error == nil)
  292. callback(@[[NSNull null], result]);
  293. else
  294. callback(@[[error localizedDescription], [NSNull null]]);
  295. }
  296. else if(asset != nil)
  297. {
  298. __block NSNumber * size = [NSNumber numberWithLong:[asset size]];
  299. result = [asset metadata];
  300. [result setValue:size forKey:@"size"];
  301. callback(@[[NSNull null], result]);
  302. }
  303. else
  304. {
  305. callback(@[@"failed to stat path, could not resolve URI", [NSNull null]]);
  306. }
  307. }];
  308. }
  309. #pragma mark - fs.lstat
  310. RCT_EXPORT_METHOD(lstat:(NSString *)path callback:(RCTResponseSenderBlock) callback)
  311. {
  312. NSFileManager* fm = [NSFileManager defaultManager];
  313. BOOL exist = nil;
  314. BOOL isDir = nil;
  315. path = [RNFetchBlobFS getPathOfAsset:path];
  316. exist = [fm fileExistsAtPath:path isDirectory:&isDir];
  317. if(exist == NO) {
  318. callback(@[[NSString stringWithFormat:@"failed to list path `%@` for it is not exist or it is not exist", path]]);
  319. return ;
  320. }
  321. NSError * error = nil;
  322. NSArray * files = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:path error:&error];
  323. NSMutableArray * res = [[NSMutableArray alloc] init];
  324. if(isDir == YES) {
  325. for(NSString * p in files) {
  326. NSString * filePath = [NSString stringWithFormat:@"%@/%@", path, p];
  327. [res addObject:[RNFetchBlobFS stat:filePath error:&error]];
  328. }
  329. }
  330. else {
  331. [res addObject:[RNFetchBlobFS stat:path error:&error]];
  332. }
  333. if(error == nil)
  334. callback(@[[NSNull null], res == nil ? [NSNull null] :res ]);
  335. else
  336. callback(@[[error localizedDescription], [NSNull null]]);
  337. }
  338. #pragma mark - fs.cp
  339. RCT_EXPORT_METHOD(cp:(NSString*)src toPath:(NSString *)dest callback:(RCTResponseSenderBlock) callback)
  340. {
  341. // path = [RNFetchBlobFS getPathOfAsset:path];
  342. [RNFetchBlobFS getPathFromUri:src completionHandler:^(NSString *path, ALAssetRepresentation *asset) {
  343. NSError * error = nil;
  344. if(path == nil)
  345. {
  346. [RNFetchBlobFS writeAssetToPath:asset dest:dest];
  347. callback(@[[NSNull null], @YES]);
  348. }
  349. else
  350. {
  351. BOOL result = [[NSFileManager defaultManager] copyItemAtURL:[NSURL fileURLWithPath:path] toURL:[NSURL fileURLWithPath:dest] error:&error];
  352. if(error == nil)
  353. callback(@[[NSNull null], @YES]);
  354. else
  355. callback(@[[error localizedDescription], @NO]);
  356. }
  357. }];
  358. }
  359. #pragma mark - fs.mv
  360. RCT_EXPORT_METHOD(mv:(NSString *)path toPath:(NSString *)dest callback:(RCTResponseSenderBlock) callback)
  361. {
  362. NSError * error = nil;
  363. BOOL result = [[NSFileManager defaultManager] moveItemAtURL:[NSURL fileURLWithPath:path] toURL:[NSURL fileURLWithPath:dest] error:&error];
  364. if(error == nil)
  365. callback(@[[NSNull null], @YES]);
  366. else
  367. callback(@[[error localizedDescription], @NO]);
  368. }
  369. #pragma mark - fs.mkdir
  370. RCT_EXPORT_METHOD(mkdir:(NSString *)path callback:(RCTResponseSenderBlock) callback)
  371. {
  372. if([[NSFileManager defaultManager] fileExistsAtPath:path]) {
  373. callback(@[@"mkdir failed, folder already exists"]);
  374. return;
  375. }
  376. else
  377. [RNFetchBlobFS mkdir:path];
  378. callback(@[[NSNull null]]);
  379. }
  380. #pragma mark - fs.readFile
  381. RCT_EXPORT_METHOD(readFile:(NSString *)path
  382. encoding:(NSString *)encoding
  383. resolver:(RCTPromiseResolveBlock)resolve
  384. rejecter:(RCTPromiseRejectBlock)reject)
  385. {
  386. [RNFetchBlobFS readFile:path encoding:encoding onComplete:^(id content, NSString * err) {
  387. if(err != nil)
  388. {
  389. reject(@"RNFetchBlob failed to read file", err, nil);
  390. return;
  391. }
  392. if(encoding == @"ascii")
  393. {
  394. resolve((NSMutableArray *)content);
  395. }
  396. else
  397. {
  398. resolve((NSString *)content);
  399. }
  400. }];
  401. }
  402. #pragma mark - fs.readStream
  403. RCT_EXPORT_METHOD(readStream:(NSString *)path withEncoding:(NSString *)encoding bufferSize:(int)bufferSize tick:(int)tick streamId:(NSString *)streamId)
  404. {
  405. if(bufferSize == nil) {
  406. if([[encoding lowercaseString] isEqualToString:@"base64"])
  407. bufferSize = 4095;
  408. else
  409. bufferSize = 4096;
  410. }
  411. dispatch_async(fsQueue, ^{
  412. [RNFetchBlobFS readStream:path encoding:encoding bufferSize:bufferSize tick:tick streamId:streamId bridgeRef:_bridge];
  413. });
  414. }
  415. #pragma mark - fs.getEnvionmentDirs
  416. RCT_EXPORT_METHOD(getEnvironmentDirs:(RCTResponseSenderBlock) callback)
  417. {
  418. callback(@[
  419. [RNFetchBlobFS getDocumentDir],
  420. [RNFetchBlobFS getCacheDir],
  421. ]);
  422. }
  423. #pragma mark - net.cancelRequest
  424. RCT_EXPORT_METHOD(cancelRequest:(NSString *)taskId callback:(RCTResponseSenderBlock)callback) {
  425. [RNFetchBlobNetwork cancelRequest:taskId];
  426. callback(@[[NSNull null], taskId]);
  427. }
  428. #pragma mark - net.enableProgressReport
  429. RCT_EXPORT_METHOD(enableProgressReport:(NSString *)taskId interval:(nonnull NSNumber*)interval count:(nonnull NSNumber*)count)
  430. {
  431. RNFetchBlobProgress * cfg = [[RNFetchBlobProgress alloc] initWithType:Download interval:interval count:count];
  432. [RNFetchBlobNetwork enableProgressReport:taskId config:cfg];
  433. }
  434. #pragma mark - net.enableUploadProgressReport
  435. RCT_EXPORT_METHOD(enableUploadProgressReport:(NSString *)taskId interval:(nonnull NSNumber*)interval count:(nonnull NSNumber*)count)
  436. {
  437. RNFetchBlobProgress * cfg = [[RNFetchBlobProgress alloc] initWithType:Upload interval:interval count:count];
  438. [RNFetchBlobNetwork enableUploadProgress:taskId config:cfg];
  439. }
  440. #pragma mark - fs.slice
  441. RCT_EXPORT_METHOD(slice:(NSString *)src dest:(NSString *)dest start:(nonnull NSNumber *)start end:(nonnull NSNumber *)end resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
  442. {
  443. [RNFetchBlobFS slice:src dest:dest start:start end:end encode:@"" resolver:resolve rejecter:reject];
  444. }
  445. RCT_EXPORT_METHOD(previewDocument:(NSString*)uri scheme:(NSString *)scheme resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
  446. {
  447. NSString * utf8uri = [uri stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
  448. NSURL * url = [[NSURL alloc] initWithString:utf8uri];
  449. // NSURL * url = [[NSURL alloc] initWithString:uri];
  450. documentController = [UIDocumentInteractionController interactionControllerWithURL:url];
  451. UIViewController *rootCtrl = [[[[UIApplication sharedApplication] delegate] window] rootViewController];
  452. documentController.delegate = self;
  453. if(scheme == nil || [[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:scheme]]) {
  454. CGRect rect = CGRectMake(0.0, 0.0, 0.0, 0.0);
  455. dispatch_sync(dispatch_get_main_queue(), ^{
  456. [documentController presentOptionsMenuFromRect:rect inView:rootCtrl.view animated:YES];
  457. });
  458. resolve(@[[NSNull null]]);
  459. } else {
  460. reject(@"RNFetchBlob could not open document", @"scheme is not supported", nil);
  461. }
  462. }
  463. # pragma mark - open file with UIDocumentInteractionController and delegate
  464. RCT_EXPORT_METHOD(openDocument:(NSString*)uri scheme:(NSString *)scheme resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
  465. {
  466. NSString * utf8uri = [uri stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
  467. NSURL * url = [[NSURL alloc] initWithString:utf8uri];
  468. // NSURL * url = [[NSURL alloc] initWithString:uri];
  469. documentController = [UIDocumentInteractionController interactionControllerWithURL:url];
  470. documentController.delegate = self;
  471. if(scheme == nil || [[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:scheme]]) {
  472. dispatch_sync(dispatch_get_main_queue(), ^{
  473. [documentController presentPreviewAnimated:YES];
  474. });
  475. resolve(@[[NSNull null]]);
  476. } else {
  477. reject(@"RNFetchBlob could not open document", @"scheme is not supported", nil);
  478. }
  479. }
  480. # pragma mark - exclude from backup key
  481. RCT_EXPORT_METHOD(excludeFromBackupKey:(NSString *)url resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
  482. {
  483. NSError *error = nil;
  484. [ [NSURL URLWithString:url] setResourceValue:[NSNumber numberWithBool:YES] forKey:NSURLIsExcludedFromBackupKey error:&error];
  485. if(!error)
  486. {
  487. resolve(@[[NSNull null]]);
  488. } else {
  489. reject(@"RNFetchBlob could not open document", [error description], nil);
  490. }
  491. }
  492. RCT_EXPORT_METHOD(df:(RCTResponseSenderBlock)callback)
  493. {
  494. [RNFetchBlobFS df:callback];
  495. }
  496. - (UIViewController *) documentInteractionControllerViewControllerForPreview: (UIDocumentInteractionController *) controller
  497. {
  498. UIWindow *window = [UIApplication sharedApplication].keyWindow;
  499. return window.rootViewController;
  500. }
  501. # pragma mark - check expired network events
  502. RCT_EXPORT_METHOD(emitExpiredEvent:(RCTResponseSenderBlock)callback)
  503. {
  504. [RNFetchBlobNetwork emitExpiredTasks];
  505. }
  506. @end