diff --git a/FS.common.js b/FS.common.js index b68804d..77de0df 100644 --- a/FS.common.js +++ b/FS.common.js @@ -2,40 +2,12 @@ // This file supports both iOS and Android -// Stop bluebird going nuts because it can't find "self" -if (typeof self === 'undefined') { - global.self = global; -} - var RNFSManager = require('react-native').NativeModules.RNFSManager; var NativeAppEventEmitter = require('react-native').NativeAppEventEmitter; // iOS var DeviceEventEmitter = require('react-native').DeviceEventEmitter; // Android -var Promise = require('bluebird'); var base64 = require('base-64'); var utf8 = require('utf8'); -var _readDir = Promise.promisify(RNFSManager.readDir); -var _exists = Promise.promisify(RNFSManager.exists); -var _stat = Promise.promisify(RNFSManager.stat); -var _readFile = Promise.promisify(RNFSManager.readFile); -var _writeFile = Promise.promisify(RNFSManager.writeFile); -var _moveFile = Promise.promisify(RNFSManager.moveFile); -var _unlink = Promise.promisify(RNFSManager.unlink); -var _mkdir = Promise.promisify(RNFSManager.mkdir); -var _downloadFile = Promise.promisify(RNFSManager.downloadFile); -var _pathForBundle = Promise.promisify(RNFSManager.pathForBundle); -var _getFSInfo = Promise.promisify(RNFSManager.getFSInfo); - -var convertError = (err) => { - if (err.isOperational && err.cause) { - err = err.cause; - } - - var error = new Error(err.description || err.message); - error.code = err.code; - throw error; -}; - var NSFileTypeRegular = RNFSManager.NSFileTypeRegular; var NSFileTypeDirectory = RNFSManager.NSFileTypeDirectory; @@ -49,7 +21,7 @@ var getJobId = () => { var RNFS = { readDir(dirpath) { - return _readDir(dirpath) + return RNFSManager.readDir(dirpath) .then(files => { return files.map(file => ({ name: file.name, @@ -58,20 +30,17 @@ var RNFS = { isFile: () => file.type === NSFileTypeRegular, isDirectory: () => file.type === NSFileTypeDirectory, })); - }) - .catch(convertError); + }); }, // Node style version (lowercase d). Returns just the names readdir(dirpath) { - return RNFS.readDir(dirpath) - .then(files => { - return files.map(file => file.name); - }); + return RNFSManager.readDir(dirpath) + .then(files => files.map(file => file.name)); }, stat(filepath) { - return _stat(filepath) + return RNFSManager.stat(filepath) .then((result) => { return { 'ctime': new Date(result.ctime*1000), @@ -85,15 +54,10 @@ var RNFS = { .catch(convertError); }, - exists(filepath) { - return _exists(filepath) - .catch(convertError); - }, - readFile(filepath, encoding) { if (!encoding) encoding = 'utf8'; - return _readFile(filepath) + return RNFSManager.readFile(filepath) .then((b64) => { var contents; @@ -108,8 +72,7 @@ var RNFS = { } return contents; - }) - .catch(convertError); + }); }, writeFile(filepath, contents, encoding, options) { @@ -127,33 +90,12 @@ var RNFS = { throw new Error('Invalid encoding type "' + encoding + '"'); } - return _writeFile(filepath, b64, options) - .catch(convertError); - }, - - moveFile(filepath, destPath) { - return _moveFile(filepath, destPath) - .catch(convertError); - }, - - pathForBundle(bundleName) { - return _pathForBundle(bundleName); - }, - - getFSInfo() { - return _getFSInfo() - .catch(convertError); - }, - - unlink(filepath) { - return _unlink(filepath) - .catch(convertError); + return RNFSManager.writeFile(filepath, b64, options); }, mkdir(filepath, excludeFromBackup) { excludeFromBackup = !!excludeFromBackup; - return _mkdir(filepath, excludeFromBackup) - .catch(convertError); + return RNFSManager.mkdir(filepath, excludeFromBackup); }, downloadFile(fromUrl, toFile, begin, progress) { @@ -179,18 +121,20 @@ var RNFS = { subscriptionAndroid = DeviceEventEmitter.addListener('DownloadProgress-' + jobId, progress); } - return _downloadFile(fromUrl, toFile, jobId) + return RNFSManager.downloadFile(fromUrl, toFile, jobId) .then(res => { if (subscriptionIos) subscriptionIos.remove(); if (subscriptionAndroid) subscriptionAndroid.remove(); return res; - }) - .catch(convertError); + }); }, - stopDownload(jobId) { - RNFSManager.stopDownload(jobId); - }, + stopDownload: RNFSManager.stopDownload, + moveFile: RNFSManager.moveFile, + pathForBundle: RNFSManager.pathForBundle, + getFSInfo: RNFSManager.getFSInfo, + unlink: RNFSManager.unlink, + exists: RNFSManager.exists, MainBundlePath: RNFSManager.MainBundlePath, CachesDirectoryPath: RNFSManager.NSCachesDirectoryPath, diff --git a/RNFSManager.m b/RNFSManager.m index 35780b1..5c02660 100644 --- a/RNFSManager.m +++ b/RNFSManager.m @@ -30,7 +30,8 @@ RCT_EXPORT_MODULE(); } RCT_EXPORT_METHOD(readDir:(NSString *)dirPath - callback:(RCTResponseSenderBlock)callback) + resolver:(RCTPromiseResolveBlock)resolve + rejecter:(RCTPromiseRejectBlock)reject) { NSFileManager *fileManager = [NSFileManager defaultManager]; NSError *error = nil; @@ -50,28 +51,30 @@ RCT_EXPORT_METHOD(readDir:(NSString *)dirPath }]; if (error) { - return callback([self makeErrorPayload:error]); + return [self reject:reject withError:error]; } - callback(@[[NSNull null], contents]); + resolve(contents); } RCT_EXPORT_METHOD(exists:(NSString *)filepath - callback:(RCTResponseSenderBlock)callback) + resolver:(RCTPromiseResolveBlock)resolve + rejecter:(__unused RCTPromiseRejectBlock)reject) { BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:filepath]; - callback(@[[NSNull null], [NSNumber numberWithBool:fileExists]]); + resolve([NSNumber numberWithBool:fileExists]); } RCT_EXPORT_METHOD(stat:(NSString *)filepath - callback:(RCTResponseSenderBlock)callback) + resolver:(RCTPromiseResolveBlock)resolve + rejecter:(RCTPromiseRejectBlock)reject) { NSError *error = nil; NSDictionary *attributes = [[NSFileManager defaultManager] attributesOfItemAtPath:filepath error:&error]; if (error) { - return callback([self makeErrorPayload:error]); + return [self reject:reject withError:error]; } attributes = @{ @@ -82,46 +85,49 @@ RCT_EXPORT_METHOD(stat:(NSString *)filepath @"mode": @([[NSString stringWithFormat:@"%ld", (long)[(NSNumber *)[attributes objectForKey:NSFilePosixPermissions] integerValue]] integerValue]) }; - callback(@[[NSNull null], attributes]); + resolve(attributes); } RCT_EXPORT_METHOD(writeFile:(NSString *)filepath contents:(NSString *)base64Content attributes:(NSDictionary *)attributes - callback:(RCTResponseSenderBlock)callback) + resolver:(RCTPromiseResolveBlock)resolve + rejecter:(RCTPromiseRejectBlock)reject) { NSData *data = [[NSData alloc] initWithBase64EncodedString:base64Content options:NSDataBase64DecodingIgnoreUnknownCharacters]; BOOL success = [[NSFileManager defaultManager] createFileAtPath:filepath contents:data attributes:attributes]; if (!success) { - return callback(@[[NSString stringWithFormat:@"Could not write file at path %@", filepath]]); + return reject([NSString stringWithFormat:@"Could not write file at path %@", filepath], nil, nil); } - callback(@[[NSNull null], [NSNumber numberWithBool:success], filepath]); + resolve([NSNumber numberWithBool:success]); } RCT_EXPORT_METHOD(unlink:(NSString*)filepath - callback:(RCTResponseSenderBlock)callback) + resolver:(RCTPromiseResolveBlock)resolve + rejecter:(RCTPromiseRejectBlock)reject) { NSFileManager *manager = [NSFileManager defaultManager]; BOOL exists = [manager fileExistsAtPath:filepath isDirectory:false]; if (!exists) { - return callback(@[[NSString stringWithFormat:@"File at path %@ does not exist", filepath]]); + return reject([NSString stringWithFormat:@"File at path %@ does not exist", filepath], nil, nil); } NSError *error = nil; BOOL success = [manager removeItemAtPath:filepath error:&error]; if (!success) { - return callback([self makeErrorPayload:error]); + return [self reject:reject withError:error]; } - callback(@[[NSNull null], [NSNumber numberWithBool:success], filepath]); + resolve([NSNumber numberWithBool:success]); } RCT_EXPORT_METHOD(mkdir:(NSString*)filepath excludeFromBackup:(BOOL)excludeFromBackup - callback:(RCTResponseSenderBlock)callback) + resolver:(RCTPromiseResolveBlock)resolve + rejecter:(RCTPromiseRejectBlock)reject) { NSFileManager *manager = [NSFileManager defaultManager]; @@ -129,7 +135,7 @@ RCT_EXPORT_METHOD(mkdir:(NSString*)filepath BOOL success = [manager createDirectoryAtPath:filepath withIntermediateDirectories:YES attributes:nil error:&error]; if (!success) { - return callback([self makeErrorPayload:error]); + return [self reject:reject withError:error]; } NSURL *url = [NSURL fileURLWithPath:filepath]; @@ -137,28 +143,30 @@ RCT_EXPORT_METHOD(mkdir:(NSString*)filepath success = [url setResourceValue: [NSNumber numberWithBool: excludeFromBackup] forKey: NSURLIsExcludedFromBackupKey error: &error]; if (!success) { - return callback([self makeErrorPayload:error]); + return [self reject:reject withError:error]; } - callback(@[[NSNull null], [NSNumber numberWithBool:success], filepath]); + resolve([NSNumber numberWithBool:success]); } RCT_EXPORT_METHOD(readFile:(NSString *)filepath - callback:(RCTResponseSenderBlock)callback) + resolver:(RCTPromiseResolveBlock)resolve + rejecter:(RCTPromiseRejectBlock)reject) { NSData *content = [[NSFileManager defaultManager] contentsAtPath:filepath]; NSString *base64Content = [content base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed]; if (!base64Content) { - return callback(@[[NSString stringWithFormat:@"Could not read file at path %@", filepath]]); + return reject([NSString stringWithFormat:@"Could not read file at path %@", filepath], nil, nil); } - callback(@[[NSNull null], base64Content]); + resolve(base64Content); } RCT_EXPORT_METHOD(moveFile:(NSString *)filepath destPath:(NSString *)destPath - callback:(RCTResponseSenderBlock)callback) + resolver:(RCTPromiseResolveBlock)resolve + rejecter:(RCTPromiseRejectBlock)reject) { NSFileManager *manager = [NSFileManager defaultManager]; @@ -166,16 +174,17 @@ RCT_EXPORT_METHOD(moveFile:(NSString *)filepath BOOL success = [manager moveItemAtPath:filepath toPath:destPath error:&error]; if (!success) { - return callback([self makeErrorPayload:error]); + return [self reject:reject withError:error]; } - callback(@[[NSNull null], [NSNumber numberWithBool:success], destPath]); + resolve([NSNumber numberWithBool:success]); } RCT_EXPORT_METHOD(downloadFile:(NSString *)urlStr filepath:(NSString *)filepath jobId:(nonnull NSNumber *)jobId - callback:(RCTResponseSenderBlock)callback) + resolver:(RCTPromiseResolveBlock)resolve + rejecter:(RCTPromiseRejectBlock)reject) { DownloadParams* params = [DownloadParams alloc]; @@ -189,11 +198,11 @@ RCT_EXPORT_METHOD(downloadFile:(NSString *)urlStr if (bytesWritten) { [result setObject:bytesWritten forKey: @"bytesWritten"]; } - return callback(@[[NSNull null], result]); + return resolve(result); }; params.errorCallback = ^(NSError* error) { - return callback([self makeErrorPayload:error]); + return [self reject:reject withError:error]; }; params.beginCallback = ^(NSNumber* statusCode, NSNumber* contentLength, NSDictionary* headers) { @@ -230,7 +239,8 @@ RCT_EXPORT_METHOD(stopDownload:(nonnull NSNumber *)jobId) } RCT_EXPORT_METHOD(pathForBundle:(NSString *)bundleNamed - callback:(RCTResponseSenderBlock)callback) + resolver:(RCTPromiseResolveBlock)resolve + rejecter:(RCTPromiseRejectBlock)reject) { NSString *path = [[NSBundle mainBundle].bundlePath stringByAppendingFormat:@"/%@.bundle", bundleNamed]; NSBundle *bundle = [NSBundle bundleWithPath:path]; @@ -245,38 +255,37 @@ RCT_EXPORT_METHOD(pathForBundle:(NSString *)bundleNamed } if (path) { - callback(@[[NSNull null], path]); + resolve(path); } else { - callback(@[[NSError errorWithDomain:NSPOSIXErrorDomain - code:NSFileNoSuchFileError - userInfo:nil].localizedDescription, - [NSNull null]]); + NSError *error = [NSError errorWithDomain:NSPOSIXErrorDomain + code:NSFileNoSuchFileError + userInfo:nil]; + + [self reject:reject withError:error]; } } -RCT_EXPORT_METHOD(getFSInfo:(RCTResponseSenderBlock)callback) +RCT_EXPORT_METHOD(getFSInfo:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject) { unsigned long long totalSpace = 0; unsigned long long totalFreeSpace = 0; - + __autoreleasing NSError *error = nil; NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); - NSDictionary *dictionary = [[NSFileManager defaultManager] attributesOfFileSystemForPath:[paths lastObject] error: &error]; - + NSDictionary *dictionary = [[NSFileManager defaultManager] attributesOfFileSystemForPath:[paths lastObject] error:&error]; + if (dictionary) { NSNumber *fileSystemSizeInBytes = [dictionary objectForKey: NSFileSystemSize]; NSNumber *freeFileSystemSizeInBytes = [dictionary objectForKey:NSFileSystemFreeSize]; totalSpace = [fileSystemSizeInBytes unsignedLongLongValue]; totalFreeSpace = [freeFileSystemSizeInBytes unsignedLongLongValue]; - - callback(@[[NSNull null], - @{ - @"totalSpace": [NSNumber numberWithUnsignedLongLong:totalSpace], - @"freeSpace": [NSNumber numberWithUnsignedLongLong:totalFreeSpace] - } - ]); + + resolve(@{ + @"totalSpace": [NSNumber numberWithUnsignedLongLong:totalSpace], + @"freeSpace": [NSNumber numberWithUnsignedLongLong:totalFreeSpace] + }); } else { - callback(@[error, [NSNull null]]); + [self reject:reject withError:error]; } } @@ -285,12 +294,10 @@ RCT_EXPORT_METHOD(getFSInfo:(RCTResponseSenderBlock)callback) return @([date timeIntervalSince1970]); } -- (NSArray *)makeErrorPayload:(NSError *)error +- (void)reject:(RCTPromiseRejectBlock)reject withError:(NSError *)error { - return @[@{ - @"description": error.localizedDescription, - @"code": @(error.code) - }]; + NSString *codeWithDomain = [NSString stringWithFormat:@"E%@%zd", error.domain.uppercaseString, error.code]; + reject(codeWithDomain, error.localizedDescription, error); } - (NSString *)getPathForDirectory:(int)directory diff --git a/package.json b/package.json index 6065be9..cbb2244 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,6 @@ "license": "MIT", "dependencies": { "base-64": "^0.1.0", - "bluebird": "^2.9.25", "utf8": "^2.1.1" }, "devDependencies": {