iOS and JS

This commit is contained in:
Mike Grabowski 2016-05-14 22:25:04 +02:00
parent 01d43a011a
commit 4977508b36
3 changed files with 75 additions and 125 deletions

View File

@ -2,40 +2,12 @@
// This file supports both iOS and Android // 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 RNFSManager = require('react-native').NativeModules.RNFSManager;
var NativeAppEventEmitter = require('react-native').NativeAppEventEmitter; // iOS var NativeAppEventEmitter = require('react-native').NativeAppEventEmitter; // iOS
var DeviceEventEmitter = require('react-native').DeviceEventEmitter; // Android var DeviceEventEmitter = require('react-native').DeviceEventEmitter; // Android
var Promise = require('bluebird');
var base64 = require('base-64'); var base64 = require('base-64');
var utf8 = require('utf8'); 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 NSFileTypeRegular = RNFSManager.NSFileTypeRegular;
var NSFileTypeDirectory = RNFSManager.NSFileTypeDirectory; var NSFileTypeDirectory = RNFSManager.NSFileTypeDirectory;
@ -49,7 +21,7 @@ var getJobId = () => {
var RNFS = { var RNFS = {
readDir(dirpath) { readDir(dirpath) {
return _readDir(dirpath) return RNFSManager.readDir(dirpath)
.then(files => { .then(files => {
return files.map(file => ({ return files.map(file => ({
name: file.name, name: file.name,
@ -58,20 +30,17 @@ var RNFS = {
isFile: () => file.type === NSFileTypeRegular, isFile: () => file.type === NSFileTypeRegular,
isDirectory: () => file.type === NSFileTypeDirectory, isDirectory: () => file.type === NSFileTypeDirectory,
})); }));
}) });
.catch(convertError);
}, },
// Node style version (lowercase d). Returns just the names // Node style version (lowercase d). Returns just the names
readdir(dirpath) { readdir(dirpath) {
return RNFS.readDir(dirpath) return RNFSManager.readDir(dirpath)
.then(files => { .then(files => files.map(file => file.name));
return files.map(file => file.name);
});
}, },
stat(filepath) { stat(filepath) {
return _stat(filepath) return RNFSManager.stat(filepath)
.then((result) => { .then((result) => {
return { return {
'ctime': new Date(result.ctime*1000), 'ctime': new Date(result.ctime*1000),
@ -85,15 +54,10 @@ var RNFS = {
.catch(convertError); .catch(convertError);
}, },
exists(filepath) {
return _exists(filepath)
.catch(convertError);
},
readFile(filepath, encoding) { readFile(filepath, encoding) {
if (!encoding) encoding = 'utf8'; if (!encoding) encoding = 'utf8';
return _readFile(filepath) return RNFSManager.readFile(filepath)
.then((b64) => { .then((b64) => {
var contents; var contents;
@ -108,8 +72,7 @@ var RNFS = {
} }
return contents; return contents;
}) });
.catch(convertError);
}, },
writeFile(filepath, contents, encoding, options) { writeFile(filepath, contents, encoding, options) {
@ -127,33 +90,12 @@ var RNFS = {
throw new Error('Invalid encoding type "' + encoding + '"'); throw new Error('Invalid encoding type "' + encoding + '"');
} }
return _writeFile(filepath, b64, options) return RNFSManager.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);
}, },
mkdir(filepath, excludeFromBackup) { mkdir(filepath, excludeFromBackup) {
excludeFromBackup = !!excludeFromBackup; excludeFromBackup = !!excludeFromBackup;
return _mkdir(filepath, excludeFromBackup) return RNFSManager.mkdir(filepath, excludeFromBackup);
.catch(convertError);
}, },
downloadFile(fromUrl, toFile, begin, progress) { downloadFile(fromUrl, toFile, begin, progress) {
@ -179,18 +121,20 @@ var RNFS = {
subscriptionAndroid = DeviceEventEmitter.addListener('DownloadProgress-' + jobId, progress); subscriptionAndroid = DeviceEventEmitter.addListener('DownloadProgress-' + jobId, progress);
} }
return _downloadFile(fromUrl, toFile, jobId) return RNFSManager.downloadFile(fromUrl, toFile, jobId)
.then(res => { .then(res => {
if (subscriptionIos) subscriptionIos.remove(); if (subscriptionIos) subscriptionIos.remove();
if (subscriptionAndroid) subscriptionAndroid.remove(); if (subscriptionAndroid) subscriptionAndroid.remove();
return res; return res;
}) });
.catch(convertError);
}, },
stopDownload(jobId) { stopDownload: RNFSManager.stopDownload,
RNFSManager.stopDownload(jobId); moveFile: RNFSManager.moveFile,
}, pathForBundle: RNFSManager.pathForBundle,
getFSInfo: RNFSManager.getFSInfo,
unlink: RNFSManager.unlink,
exists: RNFSManager.exists,
MainBundlePath: RNFSManager.MainBundlePath, MainBundlePath: RNFSManager.MainBundlePath,
CachesDirectoryPath: RNFSManager.NSCachesDirectoryPath, CachesDirectoryPath: RNFSManager.NSCachesDirectoryPath,

View File

@ -30,7 +30,8 @@ RCT_EXPORT_MODULE();
} }
RCT_EXPORT_METHOD(readDir:(NSString *)dirPath RCT_EXPORT_METHOD(readDir:(NSString *)dirPath
callback:(RCTResponseSenderBlock)callback) resolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject)
{ {
NSFileManager *fileManager = [NSFileManager defaultManager]; NSFileManager *fileManager = [NSFileManager defaultManager];
NSError *error = nil; NSError *error = nil;
@ -50,28 +51,30 @@ RCT_EXPORT_METHOD(readDir:(NSString *)dirPath
}]; }];
if (error) { 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 RCT_EXPORT_METHOD(exists:(NSString *)filepath
callback:(RCTResponseSenderBlock)callback) resolver:(RCTPromiseResolveBlock)resolve
rejecter:(__unused RCTPromiseRejectBlock)reject)
{ {
BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:filepath]; BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:filepath];
callback(@[[NSNull null], [NSNumber numberWithBool:fileExists]]); resolve([NSNumber numberWithBool:fileExists]);
} }
RCT_EXPORT_METHOD(stat:(NSString *)filepath RCT_EXPORT_METHOD(stat:(NSString *)filepath
callback:(RCTResponseSenderBlock)callback) resolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject)
{ {
NSError *error = nil; NSError *error = nil;
NSDictionary *attributes = [[NSFileManager defaultManager] attributesOfItemAtPath:filepath error:&error]; NSDictionary *attributes = [[NSFileManager defaultManager] attributesOfItemAtPath:filepath error:&error];
if (error) { if (error) {
return callback([self makeErrorPayload:error]); return [self reject:reject withError:error];
} }
attributes = @{ attributes = @{
@ -82,46 +85,49 @@ RCT_EXPORT_METHOD(stat:(NSString *)filepath
@"mode": @([[NSString stringWithFormat:@"%ld", (long)[(NSNumber *)[attributes objectForKey:NSFilePosixPermissions] integerValue]] integerValue]) @"mode": @([[NSString stringWithFormat:@"%ld", (long)[(NSNumber *)[attributes objectForKey:NSFilePosixPermissions] integerValue]] integerValue])
}; };
callback(@[[NSNull null], attributes]); resolve(attributes);
} }
RCT_EXPORT_METHOD(writeFile:(NSString *)filepath RCT_EXPORT_METHOD(writeFile:(NSString *)filepath
contents:(NSString *)base64Content contents:(NSString *)base64Content
attributes:(NSDictionary *)attributes attributes:(NSDictionary *)attributes
callback:(RCTResponseSenderBlock)callback) resolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject)
{ {
NSData *data = [[NSData alloc] initWithBase64EncodedString:base64Content options:NSDataBase64DecodingIgnoreUnknownCharacters]; NSData *data = [[NSData alloc] initWithBase64EncodedString:base64Content options:NSDataBase64DecodingIgnoreUnknownCharacters];
BOOL success = [[NSFileManager defaultManager] createFileAtPath:filepath contents:data attributes:attributes]; BOOL success = [[NSFileManager defaultManager] createFileAtPath:filepath contents:data attributes:attributes];
if (!success) { 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 RCT_EXPORT_METHOD(unlink:(NSString*)filepath
callback:(RCTResponseSenderBlock)callback) resolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject)
{ {
NSFileManager *manager = [NSFileManager defaultManager]; NSFileManager *manager = [NSFileManager defaultManager];
BOOL exists = [manager fileExistsAtPath:filepath isDirectory:false]; BOOL exists = [manager fileExistsAtPath:filepath isDirectory:false];
if (!exists) { 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; NSError *error = nil;
BOOL success = [manager removeItemAtPath:filepath error:&error]; BOOL success = [manager removeItemAtPath:filepath error:&error];
if (!success) { 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 RCT_EXPORT_METHOD(mkdir:(NSString*)filepath
excludeFromBackup:(BOOL)excludeFromBackup excludeFromBackup:(BOOL)excludeFromBackup
callback:(RCTResponseSenderBlock)callback) resolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject)
{ {
NSFileManager *manager = [NSFileManager defaultManager]; 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]; BOOL success = [manager createDirectoryAtPath:filepath withIntermediateDirectories:YES attributes:nil error:&error];
if (!success) { if (!success) {
return callback([self makeErrorPayload:error]); return [self reject:reject withError:error];
} }
NSURL *url = [NSURL fileURLWithPath:filepath]; 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]; success = [url setResourceValue: [NSNumber numberWithBool: excludeFromBackup] forKey: NSURLIsExcludedFromBackupKey error: &error];
if (!success) { 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 RCT_EXPORT_METHOD(readFile:(NSString *)filepath
callback:(RCTResponseSenderBlock)callback) resolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject)
{ {
NSData *content = [[NSFileManager defaultManager] contentsAtPath:filepath]; NSData *content = [[NSFileManager defaultManager] contentsAtPath:filepath];
NSString *base64Content = [content base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed]; NSString *base64Content = [content base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed];
if (!base64Content) { 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 RCT_EXPORT_METHOD(moveFile:(NSString *)filepath
destPath:(NSString *)destPath destPath:(NSString *)destPath
callback:(RCTResponseSenderBlock)callback) resolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject)
{ {
NSFileManager *manager = [NSFileManager defaultManager]; NSFileManager *manager = [NSFileManager defaultManager];
@ -166,16 +174,17 @@ RCT_EXPORT_METHOD(moveFile:(NSString *)filepath
BOOL success = [manager moveItemAtPath:filepath toPath:destPath error:&error]; BOOL success = [manager moveItemAtPath:filepath toPath:destPath error:&error];
if (!success) { 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 RCT_EXPORT_METHOD(downloadFile:(NSString *)urlStr
filepath:(NSString *)filepath filepath:(NSString *)filepath
jobId:(nonnull NSNumber *)jobId jobId:(nonnull NSNumber *)jobId
callback:(RCTResponseSenderBlock)callback) resolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject)
{ {
DownloadParams* params = [DownloadParams alloc]; DownloadParams* params = [DownloadParams alloc];
@ -189,11 +198,11 @@ RCT_EXPORT_METHOD(downloadFile:(NSString *)urlStr
if (bytesWritten) { if (bytesWritten) {
[result setObject:bytesWritten forKey: @"bytesWritten"]; [result setObject:bytesWritten forKey: @"bytesWritten"];
} }
return callback(@[[NSNull null], result]); return resolve(result);
}; };
params.errorCallback = ^(NSError* error) { params.errorCallback = ^(NSError* error) {
return callback([self makeErrorPayload:error]); return [self reject:reject withError:error];
}; };
params.beginCallback = ^(NSNumber* statusCode, NSNumber* contentLength, NSDictionary* headers) { 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 RCT_EXPORT_METHOD(pathForBundle:(NSString *)bundleNamed
callback:(RCTResponseSenderBlock)callback) resolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject)
{ {
NSString *path = [[NSBundle mainBundle].bundlePath stringByAppendingFormat:@"/%@.bundle", bundleNamed]; NSString *path = [[NSBundle mainBundle].bundlePath stringByAppendingFormat:@"/%@.bundle", bundleNamed];
NSBundle *bundle = [NSBundle bundleWithPath:path]; NSBundle *bundle = [NSBundle bundleWithPath:path];
@ -245,23 +255,24 @@ RCT_EXPORT_METHOD(pathForBundle:(NSString *)bundleNamed
} }
if (path) { if (path) {
callback(@[[NSNull null], path]); resolve(path);
} else { } else {
callback(@[[NSError errorWithDomain:NSPOSIXErrorDomain NSError *error = [NSError errorWithDomain:NSPOSIXErrorDomain
code:NSFileNoSuchFileError code:NSFileNoSuchFileError
userInfo:nil].localizedDescription, userInfo:nil];
[NSNull null]]);
[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 totalSpace = 0;
unsigned long long totalFreeSpace = 0; unsigned long long totalFreeSpace = 0;
__autoreleasing NSError *error = nil; __autoreleasing NSError *error = nil;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 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) { if (dictionary) {
NSNumber *fileSystemSizeInBytes = [dictionary objectForKey: NSFileSystemSize]; NSNumber *fileSystemSizeInBytes = [dictionary objectForKey: NSFileSystemSize];
@ -269,14 +280,12 @@ RCT_EXPORT_METHOD(getFSInfo:(RCTResponseSenderBlock)callback)
totalSpace = [fileSystemSizeInBytes unsignedLongLongValue]; totalSpace = [fileSystemSizeInBytes unsignedLongLongValue];
totalFreeSpace = [freeFileSystemSizeInBytes unsignedLongLongValue]; totalFreeSpace = [freeFileSystemSizeInBytes unsignedLongLongValue];
callback(@[[NSNull null], resolve(@{
@{ @"totalSpace": [NSNumber numberWithUnsignedLongLong:totalSpace],
@"totalSpace": [NSNumber numberWithUnsignedLongLong:totalSpace], @"freeSpace": [NSNumber numberWithUnsignedLongLong:totalFreeSpace]
@"freeSpace": [NSNumber numberWithUnsignedLongLong:totalFreeSpace] });
}
]);
} else { } else {
callback(@[error, [NSNull null]]); [self reject:reject withError:error];
} }
} }
@ -285,12 +294,10 @@ RCT_EXPORT_METHOD(getFSInfo:(RCTResponseSenderBlock)callback)
return @([date timeIntervalSince1970]); return @([date timeIntervalSince1970]);
} }
- (NSArray *)makeErrorPayload:(NSError *)error - (void)reject:(RCTPromiseRejectBlock)reject withError:(NSError *)error
{ {
return @[@{ NSString *codeWithDomain = [NSString stringWithFormat:@"E%@%zd", error.domain.uppercaseString, error.code];
@"description": error.localizedDescription, reject(codeWithDomain, error.localizedDescription, error);
@"code": @(error.code)
}];
} }
- (NSString *)getPathForDirectory:(int)directory - (NSString *)getPathForDirectory:(int)directory

View File

@ -22,7 +22,6 @@
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"base-64": "^0.1.0", "base-64": "^0.1.0",
"bluebird": "^2.9.25",
"utf8": "^2.1.1" "utf8": "^2.1.1"
}, },
"devDependencies": { "devDependencies": {