2015-05-08 17:05:37 +00:00
|
|
|
//
|
|
|
|
// RNFSManager.m
|
|
|
|
// RNFSManager
|
|
|
|
//
|
|
|
|
// Created by Johannes Lumpe on 08/05/15.
|
|
|
|
// Copyright (c) 2015 Johannes Lumpe. All rights reserved.
|
|
|
|
//
|
|
|
|
|
|
|
|
#import "RNFSManager.h"
|
|
|
|
#import "RCTBridge.h"
|
|
|
|
#import "NSArray+Map.h"
|
|
|
|
|
|
|
|
@implementation RNFSManager
|
|
|
|
|
|
|
|
static int MainBundleDirectory = 999;
|
|
|
|
|
|
|
|
RCT_EXPORT_MODULE();
|
|
|
|
|
2015-08-18 15:12:44 +00:00
|
|
|
- (dispatch_queue_t)methodQueue
|
|
|
|
{
|
2015-05-10 18:13:13 +00:00
|
|
|
return dispatch_queue_create("pe.lum.rnfs", DISPATCH_QUEUE_SERIAL);
|
|
|
|
}
|
2015-05-08 17:05:37 +00:00
|
|
|
|
2015-08-18 15:12:44 +00:00
|
|
|
RCT_EXPORT_METHOD(readDir:(NSString *)directory
|
|
|
|
inFolder:(nonnull NSNumber *)folder
|
|
|
|
callback:(RCTResponseSenderBlock)callback)
|
|
|
|
{
|
2015-05-08 17:05:37 +00:00
|
|
|
NSString *path;
|
2015-08-18 15:12:44 +00:00
|
|
|
NSInteger folderInt = [folder integerValue];
|
2015-05-08 21:18:55 +00:00
|
|
|
|
2015-05-08 17:05:37 +00:00
|
|
|
if (folderInt == MainBundleDirectory) {
|
|
|
|
path = [[NSBundle mainBundle] bundlePath];
|
|
|
|
} else {
|
|
|
|
NSArray *paths = NSSearchPathForDirectoriesInDomains(folderInt, NSUserDomainMask, YES);
|
2015-08-18 15:12:44 +00:00
|
|
|
path = [paths firstObject];
|
2015-05-08 17:05:37 +00:00
|
|
|
}
|
2015-05-08 20:47:54 +00:00
|
|
|
|
2015-05-08 17:05:37 +00:00
|
|
|
NSFileManager *fileManager = [NSFileManager defaultManager];
|
2015-05-10 18:13:13 +00:00
|
|
|
NSError *error = nil;
|
2015-08-18 15:12:44 +00:00
|
|
|
NSString *dirPath = [path stringByAppendingPathComponent:directory];
|
2015-05-08 17:05:37 +00:00
|
|
|
NSArray *contents = [fileManager contentsOfDirectoryAtPath:dirPath error:&error];
|
2015-05-08 20:47:54 +00:00
|
|
|
|
2015-08-18 15:12:44 +00:00
|
|
|
contents = [contents rnfs_mapObjectsUsingBlock:^id(NSString *obj, NSUInteger idx) {
|
2015-10-20 22:31:29 +00:00
|
|
|
NSString *path = [dirPath stringByAppendingPathComponent:obj];
|
|
|
|
NSDictionary *attributes = [fileManager attributesOfItemAtPath:path error:nil];
|
|
|
|
|
2015-05-08 17:05:37 +00:00
|
|
|
return @{
|
2015-08-18 15:12:44 +00:00
|
|
|
@"name": obj,
|
2015-10-20 22:31:29 +00:00
|
|
|
@"path": path,
|
|
|
|
@"size": [attributes objectForKey:NSFileSize],
|
|
|
|
@"type": [attributes objectForKey:NSFileType]
|
2015-05-08 17:05:37 +00:00
|
|
|
};
|
|
|
|
}];
|
2015-05-08 20:47:54 +00:00
|
|
|
|
2015-05-08 17:05:37 +00:00
|
|
|
if (error) {
|
|
|
|
return callback([self makeErrorPayload:error]);
|
|
|
|
}
|
2015-05-08 20:47:54 +00:00
|
|
|
|
2015-05-08 17:05:37 +00:00
|
|
|
callback(@[[NSNull null], contents]);
|
|
|
|
}
|
|
|
|
|
2015-08-18 15:12:44 +00:00
|
|
|
RCT_EXPORT_METHOD(stat:(NSString *)filepath
|
|
|
|
callback:(RCTResponseSenderBlock)callback)
|
|
|
|
{
|
2015-05-10 18:13:13 +00:00
|
|
|
NSError *error = nil;
|
2015-05-08 17:05:37 +00:00
|
|
|
NSDictionary *attributes = [[NSFileManager defaultManager] attributesOfItemAtPath:filepath error:&error];
|
2015-05-08 20:47:54 +00:00
|
|
|
|
2015-05-08 17:05:37 +00:00
|
|
|
if (error) {
|
|
|
|
return callback([self makeErrorPayload:error]);
|
|
|
|
}
|
2015-05-08 20:47:54 +00:00
|
|
|
|
2015-05-08 17:05:37 +00:00
|
|
|
attributes = @{
|
2015-08-18 15:12:44 +00:00
|
|
|
@"ctime": [self dateToTimeIntervalNumber:(NSDate *)[attributes objectForKey:NSFileCreationDate]],
|
|
|
|
@"mtime": [self dateToTimeIntervalNumber:(NSDate *)[attributes objectForKey:NSFileModificationDate]],
|
2015-05-08 20:47:54 +00:00
|
|
|
@"size": [attributes objectForKey:NSFileSize],
|
|
|
|
@"type": [attributes objectForKey:NSFileType],
|
2015-08-18 15:12:44 +00:00
|
|
|
@"mode": @([[NSString stringWithFormat:@"%ld", (long)[(NSNumber *)[attributes objectForKey:NSFilePosixPermissions] integerValue]] integerValue])
|
2015-05-08 20:47:54 +00:00
|
|
|
};
|
|
|
|
|
2015-05-08 17:05:37 +00:00
|
|
|
callback(@[[NSNull null], attributes]);
|
|
|
|
}
|
|
|
|
|
2015-08-18 15:12:44 +00:00
|
|
|
RCT_EXPORT_METHOD(writeFile:(NSString *)filepath
|
|
|
|
contents:(NSString *)base64Content
|
|
|
|
attributes:(NSDictionary *)attributes
|
|
|
|
callback:(RCTResponseSenderBlock)callback)
|
|
|
|
{
|
2015-05-08 20:47:54 +00:00
|
|
|
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]]);
|
|
|
|
}
|
|
|
|
|
|
|
|
callback(@[[NSNull null], [NSNumber numberWithBool:success]]);
|
|
|
|
}
|
|
|
|
|
2015-08-18 15:12:44 +00:00
|
|
|
RCT_EXPORT_METHOD(unlink:(NSString*)filepath
|
|
|
|
callback:(RCTResponseSenderBlock)callback)
|
|
|
|
{
|
2015-05-08 21:17:10 +00:00
|
|
|
NSFileManager *manager = [NSFileManager defaultManager];
|
|
|
|
BOOL exists = [manager fileExistsAtPath:filepath isDirectory:false];
|
|
|
|
|
|
|
|
if (!exists) {
|
|
|
|
return callback(@[[NSString stringWithFormat:@"File at path %@ does not exist", filepath]]);
|
|
|
|
}
|
2015-05-10 18:13:13 +00:00
|
|
|
NSError *error = nil;
|
2015-05-08 21:17:10 +00:00
|
|
|
BOOL success = [manager removeItemAtPath:filepath error:&error];
|
|
|
|
|
|
|
|
if (!success) {
|
|
|
|
return callback([self makeErrorPayload:error]);
|
|
|
|
}
|
|
|
|
|
|
|
|
callback(@[[NSNull null], [NSNumber numberWithBool:success], filepath]);
|
|
|
|
}
|
|
|
|
|
2015-10-20 22:31:29 +00:00
|
|
|
RCT_EXPORT_METHOD(mkdir:(NSString*)filepath
|
|
|
|
callback:(RCTResponseSenderBlock)callback)
|
|
|
|
{
|
|
|
|
NSFileManager *manager = [NSFileManager defaultManager];
|
|
|
|
|
|
|
|
NSError *error = nil;
|
|
|
|
BOOL success = [manager createDirectoryAtPath:filepath withIntermediateDirectories:YES attributes:nil error:&error];
|
|
|
|
|
|
|
|
if (!success) {
|
|
|
|
return callback([self makeErrorPayload:error]);
|
|
|
|
}
|
|
|
|
|
|
|
|
callback(@[[NSNull null], [NSNumber numberWithBool:success], filepath]);
|
|
|
|
}
|
|
|
|
|
2015-08-18 15:12:44 +00:00
|
|
|
RCT_EXPORT_METHOD(readFile:(NSString *)filepath
|
|
|
|
callback:(RCTResponseSenderBlock)callback)
|
|
|
|
{
|
2015-05-08 17:05:37 +00:00
|
|
|
NSData *content = [[NSFileManager defaultManager] contentsAtPath:filepath];
|
|
|
|
NSString *base64Content = [content base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed];
|
2015-05-08 21:17:10 +00:00
|
|
|
|
2015-05-08 17:05:37 +00:00
|
|
|
if (!base64Content) {
|
|
|
|
return callback(@[[NSString stringWithFormat:@"Could not read file at path %@", filepath]]);
|
|
|
|
}
|
2015-05-08 20:47:54 +00:00
|
|
|
|
2015-05-08 17:05:37 +00:00
|
|
|
callback(@[[NSNull null], base64Content]);
|
|
|
|
}
|
|
|
|
|
2015-10-20 23:17:03 +00:00
|
|
|
RCT_EXPORT_METHOD(downloadFile:(NSString *)urlStr
|
|
|
|
filepath:(NSString *)filepath
|
|
|
|
callback:(RCTResponseSenderBlock)callback)
|
|
|
|
{
|
|
|
|
NSURL *url = [NSURL URLWithString:urlStr];
|
|
|
|
NSData *urlData = [NSData dataWithContentsOfURL:url];
|
|
|
|
|
|
|
|
BOOL success = NO;
|
|
|
|
|
|
|
|
if (urlData) {
|
|
|
|
success = [urlData writeToFile:filepath atomically:YES];
|
|
|
|
}
|
|
|
|
|
|
|
|
callback(@[[NSNull null], [NSNumber numberWithBool:success], filepath]);
|
|
|
|
}
|
|
|
|
|
2015-08-18 15:12:44 +00:00
|
|
|
RCT_EXPORT_METHOD(pathForBundle:(NSString *)bundleNamed
|
|
|
|
callback:(RCTResponseSenderBlock)callback)
|
|
|
|
{
|
|
|
|
NSString *path = [[NSBundle mainBundle].bundlePath stringByAppendingFormat:@"/%@.bundle", bundleNamed];
|
|
|
|
NSBundle *bundle = [NSBundle bundleWithPath:path];
|
2015-08-27 17:30:57 +00:00
|
|
|
|
|
|
|
if (!bundle) {
|
|
|
|
bundle = [NSBundle bundleForClass:NSClassFromString(bundleNamed)];
|
2015-08-27 17:36:03 +00:00
|
|
|
path = bundle.bundlePath;
|
2015-08-27 17:30:57 +00:00
|
|
|
}
|
2015-10-20 22:31:29 +00:00
|
|
|
|
2015-08-18 15:12:44 +00:00
|
|
|
if (!bundle.isLoaded) {
|
|
|
|
[bundle load];
|
|
|
|
}
|
|
|
|
|
2015-08-27 17:42:16 +00:00
|
|
|
if (path) {
|
|
|
|
callback(@[[NSNull null], path]);
|
|
|
|
} else {
|
|
|
|
callback(@[[NSError errorWithDomain:NSPOSIXErrorDomain
|
|
|
|
code:NSFileNoSuchFileError
|
|
|
|
userInfo:nil].localizedDescription,
|
|
|
|
[NSNull null]]);
|
|
|
|
}
|
2015-08-18 15:12:44 +00:00
|
|
|
}
|
|
|
|
|
2015-08-27 17:30:57 +00:00
|
|
|
- (NSNumber *)dateToTimeIntervalNumber:(NSDate *)date
|
2015-08-18 15:12:44 +00:00
|
|
|
{
|
|
|
|
return @([date timeIntervalSince1970]);
|
2015-05-08 17:05:37 +00:00
|
|
|
}
|
|
|
|
|
2015-08-18 15:12:44 +00:00
|
|
|
- (NSArray *)makeErrorPayload:(NSError *)error
|
|
|
|
{
|
2015-05-08 17:05:37 +00:00
|
|
|
return @[@{
|
|
|
|
@"description": error.localizedDescription,
|
2015-08-18 15:12:44 +00:00
|
|
|
@"code": @(error.code)
|
2015-05-08 17:05:37 +00:00
|
|
|
}];
|
|
|
|
}
|
|
|
|
|
2015-08-18 15:12:44 +00:00
|
|
|
- (NSString *)getPathForDirectory:(int)directory
|
|
|
|
{
|
2015-05-08 17:17:59 +00:00
|
|
|
NSArray *paths = NSSearchPathForDirectoriesInDomains(directory, NSUserDomainMask, YES);
|
2015-08-18 15:12:44 +00:00
|
|
|
return [paths firstObject];
|
2015-05-08 17:17:59 +00:00
|
|
|
}
|
|
|
|
|
2015-05-08 17:05:37 +00:00
|
|
|
- (NSDictionary *)constantsToExport
|
|
|
|
{
|
|
|
|
return @{
|
2015-05-08 17:17:59 +00:00
|
|
|
@"NSCachesDirectoryPath": [self getPathForDirectory:NSCachesDirectory],
|
|
|
|
@"NSDocumentDirectoryPath": [self getPathForDirectory:NSDocumentDirectory],
|
2015-05-08 17:05:37 +00:00
|
|
|
@"NSCachesDirectory": [NSNumber numberWithInteger:NSCachesDirectory],
|
|
|
|
@"NSDocumentDirectory": [NSNumber numberWithInteger:NSDocumentDirectory],
|
|
|
|
@"MainBundleDirectory": [NSNumber numberWithInteger:MainBundleDirectory],
|
|
|
|
@"NSFileTypeRegular": NSFileTypeRegular,
|
|
|
|
@"NSFileTypeDirectory": NSFileTypeDirectory
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
@end
|