Bez popisu

RNFetchBlob.m 21KB

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