Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Alexey Puchkov 2017-05-11 08:32:08 +03:00
commit b157767157
11 changed files with 4300 additions and 16 deletions

View File

@ -88,6 +88,10 @@
- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location
{
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)downloadTask.response;
if (!_statusCode) {
_statusCode = [NSNumber numberWithLong:httpResponse.statusCode];
}
NSURL *destURL = [NSURL fileURLWithPath:_params.toFile];
NSFileManager *fm = [NSFileManager defaultManager];
NSError *error = nil;
@ -102,7 +106,9 @@
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
{
return error ? _params.errorCallback(error) : nil;
if (error && error.code != -999) {
_params.errorCallback(error);
}
}
- (void)stopDownload

View File

@ -31,6 +31,8 @@ type MkdirOptions = {
};
type ReadDirItem = {
ctime: ?Date; // The creation date of the file (iOS only)
mtime: Date; // The last modified date of the file
name: string; // The name of the item
path: string; // The absolute path to the item
size: string; // Size in bytes
@ -159,6 +161,8 @@ function readFileGeneric(filepath: string, encodingOrOptions:?string, command: F
function readDirGeneric(dirpath: string, command: Function) {
return command(normalizeFilePath(dirpath)).then(files => {
return files.map(file => ({
ctime: file.ctime && new Date(file.ctime * 1000) || null,
mtime: new Date(file.mtime * 1000),
name: file.name,
path: file.path,
size: file.size,
@ -274,6 +278,15 @@ var RNFS = {
return RNFSManager.copyFileAssets(normalizeFilePath(filepath), normalizeFilePath(destPath)).then(() => void 0);
},
// iOS only
// Copies fotos from asset-library (camera-roll) to a specific location
// with a given width or height
// @see: https://developer.apple.com/reference/photos/phimagemanager/1616964-requestimageforasset
copyAssetsFileIOS(imageUri: string, destPath: string, width: number, height: number,
scale : number = 1.0, compression : number = 1.0, resizeMode : string = 'contain' ): Promise<string> {
return RNFSManager.copyAssetsFileIOS(imageUri, destPath, width, height, scale, compression, resizeMode );
},
writeFile(filepath: string, contents: string, encodingOrOptions?: any): Promise<void> {
var b64;
@ -330,6 +343,38 @@ var RNFS = {
return RNFSManager.appendFile(normalizeFilePath(filepath), b64);
},
write(filepath: string, contents: string, position?: number, encodingOrOptions?: any): Promise<void> {
var b64;
var options = {
encoding: 'utf8'
};
if (encodingOrOptions) {
if (typeof encodingOrOptions === 'string') {
options.encoding = encodingOrOptions;
} else if (typeof encodingOrOptions === 'object') {
options = encodingOrOptions;
}
}
if (options.encoding === 'utf8') {
b64 = base64.encode(utf8.encode(contents));
} else if (options.encoding === 'ascii') {
b64 = base64.encode(contents);
} else if (options.encoding === 'base64') {
b64 = contents;
} else {
throw new Error('Invalid encoding type "' + options.encoding + '"');
}
if (position === undefined) {
position = -1;
}
return RNFSManager.write(normalizeFilePath(filepath), b64, position).then(() => void 0);
},
downloadFile(options: DownloadFileOptions): { jobId: number, promise: Promise<DownloadResult> } {
if (typeof options !== 'object') throw new Error('downloadFile: Invalid value for argument `options`');
if (typeof options.fromUrl !== 'string') throw new Error('downloadFile: Invalid value for property `fromUrl`');

View File

@ -9,7 +9,11 @@
#import "AppDelegate.h"
#if __has_include("RCTRootView.h")
#import "RCTRootView.h"
#else
#import <React/RCTRootView.h>
#endif
@implementation AppDelegate

View File

@ -2,7 +2,13 @@
Native filesystem access for react-native
## Breaking change in v2.x
## Changes for v2.3
- React-Native 0.40 is minimum required for compiling on iOS (otherwise install an older release, see below)
- Access to iOS-based "assets-library" is now supported with `copyAssetsFileIOS`
- `readDir` will return now creation- and modification-time of files as with `stat()` (thanks @Ignigena)
## Breaking change in v2.0
- Removed attributes from `writeFile` and `appendFile` for iOS / Android consistency
- `downloadFile` takes `options` object rather than parameters
@ -26,6 +32,9 @@ npm install react-native-fs --save
npm install react-native-fs@2.0.1-rc.2 --save
```
As @a-koka pointed out, you should then update your package.json to
`"react-native-fs": "2.0.1-rc.2"` (without the tilde)
### Adding automatically with react-native link
At the command line, in your project folder, type:
@ -284,6 +293,7 @@ The following constants are available on the `RNFS` export:
- `CachesDirectoryPath` (`String`) The absolute path to the caches directory
- `DocumentDirectoryPath` (`String`) The absolute path to the document directory
- `TemporaryDirectoryPath` (`String`) The absolute path to the temporary directory (iOS only)
- `LibraryDirectoryPath` (`String`) The absolute path to the NSLibraryDirectory (iOS only)
- `ExternalDirectoryPath` (`String`) The absolute path to the external files, shared directory (android only)
- `ExternalStorageDirectoryPath` (`String`) The absolute path to the external storage, shared directory (android only)
@ -295,6 +305,8 @@ The returned promise resolves with an array of objects with the following proper
```
type ReadDirItem = {
ctime: date; // The creation date of the file (iOS only)
mtime: date; // The last modified date of the file
name: string; // The name of the item
path: string; // The absolute path to the item
size: string; // Size in bytes
@ -335,8 +347,8 @@ The promise resolves with an object with the following properties:
```
type StatResult = {
name: string; // The name of the item
path: string; // The absolute path to the item
ctime: date; // The creation date of the file
mtime: date; // The last modified date of the file
size: string; // Size in bytes
mode: number; // UNIX file mode
isFile: () => boolean; // Is the file just a file?
@ -366,6 +378,10 @@ Write the `contents` to `filepath`. `encoding` can be one of `utf8` (default), `
Append the `contents` to `filepath`. `encoding` can be one of `utf8` (default), `ascii`, `base64`.
### `write(filepath: string, contents: string, position?: number, encoding?: string): Promise<void>`
Write the `contents` to `filepath` at the given random access position. When `position` is `undefined` or `-1` the contents is appended to the end of the file. `encoding` can be one of `utf8` (default), `ascii`, `base64`.
### `moveFile(filepath: string, destPath: string): Promise<void>`
Moves the file located at `filepath` to `destPath`. This is more performant than reading and then re-writing the file data because the move is done natively and the data doesn't have to be copied or cross the bridge.
@ -378,10 +394,20 @@ Note: On Android copyFile will overwrite `destPath` if it already exists. On iOS
### `copyFileAssets(filepath: string, destPath: string): Promise<void>`
Copies the file at `filepath ` in the Android app's assets folder and copies it to the given `destPath ` path.
Copies the file at `filepath` in the Android app's assets folder and copies it to the given `destPath ` path.
Note: Android only. Will overwrite destPath if it already exists
### `copyAssetsFileIOS(imageUri: string, destPath: string, width: number, height: number, scale : number = 1.0, compression : number = 1.0, resizeMode : string = 'contain' ): Promise<string>`
iOS-ony: copies a file from camera-roll, that is prefixed with "assets-library://asset/asset.JPG?..."
to a specific destination. It will download the original from iCloud if necessary.
If width and height is > 0, the image will be resized to a specific size and a specific compression rate.
If scale is below 1, the image will be scaled according to the scale-factor (between 0.0 and 1.0)
The resizeMode is also considered.
Further information: https://developer.apple.com/reference/photos/phimagemanager/1616964-requestimageforasset
The promise will on success return the final destination of the file, as it was defined in the destPath-parameter.
### `unlink(filepath: string): Promise<void>`
Unlinks the item at `filepath`. If the item does not exist, an error will be thrown.
@ -465,10 +491,12 @@ If `progressDivider` = 0, you will receive all `progressCallback` calls, default
(IOS only): `options.background` (`Boolean`) - Whether to continue downloads when the app is not focused (default: `false`)
This option is currently only available for iOS, and you must [enable
background fetch](https://www.objc.io/issues/5-ios7/multitasking/#background-fetch<Paste>)
for your project in XCode.
for your project in XCode. You only need to enable background fetch in `Info.plist` and set
the fetch interval in `didFinishLaunchingWithOptions`. The `performFetchWithCompletionHandler`
callback is handled by RNFS.
### `stopDownload(jobId: number): Promise<void>`
### `stopDownload(jobId: number): void`
Abort the current download job with this ID. The partial file will remain on the filesystem.

View File

@ -5,12 +5,13 @@ Pod::Spec.new do |s|
s.name = "RNFS"
s.version = pjson["version"]
s.homepage = "https://github.com/johanneslumpe/react-native-fs"
s.homepage = "https://github.com/itinance/react-native-fs"
s.summary = pjson["description"]
s.license = pjson["license"]
s.author = { "Johannes Lumpe" => "johannes@lum.pe" }
s.platform = :ios, "7.0"
s.source = { :git => "https://github.com/johanneslumpe/react-native-fs", :tag => "#{s.version}" }
s.ios.deployment_target = '8.0'
s.tvos.deployment_target = '9.0'
s.source = { :git => "https://github.com/itinance/react-native-fs", :tag => "v#{s.version}" }
s.source_files = '*.{h,m}'
s.preserve_paths = "**/*.js"

View File

@ -7,6 +7,10 @@
objects = {
/* Begin PBXBuildFile section */
645644281EB8DAA100672408 /* NSArray+Map.m in Sources */ = {isa = PBXBuildFile; fileRef = F1EB08BA1AFD0E6A008F8F2B /* NSArray+Map.m */; };
645644291EB8DAA100672408 /* RNFSManager.m in Sources */ = {isa = PBXBuildFile; fileRef = F1E59BDE1ADD662800ACA28A /* RNFSManager.m */; };
6456442A1EB8DAA100672408 /* Downloader.m in Sources */ = {isa = PBXBuildFile; fileRef = 8BF740761C033A2E0057A1E7 /* Downloader.m */; };
6456442B1EB8DAA100672408 /* Uploader.m in Sources */ = {isa = PBXBuildFile; fileRef = 8BB364CB1CDA130000435A01 /* Uploader.m */; };
8BB364CC1CDA130000435A01 /* Uploader.m in Sources */ = {isa = PBXBuildFile; fileRef = 8BB364CB1CDA130000435A01 /* Uploader.m */; };
8BF740771C033A2E0057A1E7 /* Downloader.m in Sources */ = {isa = PBXBuildFile; fileRef = 8BF740761C033A2E0057A1E7 /* Downloader.m */; };
F1E59BDF1ADD662800ACA28A /* RNFSManager.m in Sources */ = {isa = PBXBuildFile; fileRef = F1E59BDE1ADD662800ACA28A /* RNFSManager.m */; };
@ -14,6 +18,15 @@
/* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */
6456441D1EB8DA9100672408 /* CopyFiles */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "include/$(PRODUCT_NAME)";
dstSubfolderSpec = 16;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
F12AFB991ADAF8F800E0535D /* CopyFiles */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
@ -26,6 +39,7 @@
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
6456441F1EB8DA9100672408 /* libRNFS.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libRNFS.a; sourceTree = BUILT_PRODUCTS_DIR; };
8BB364CA1CDA130000435A01 /* Uploader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Uploader.h; sourceTree = "<group>"; };
8BB364CB1CDA130000435A01 /* Uploader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Uploader.m; sourceTree = "<group>"; };
8BF740751C033A2E0057A1E7 /* Downloader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Downloader.h; sourceTree = "<group>"; };
@ -38,6 +52,13 @@
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
6456441C1EB8DA9100672408 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
F12AFB981ADAF8F800E0535D /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
@ -67,6 +88,7 @@
isa = PBXGroup;
children = (
F12AFB9B1ADAF8F800E0535D /* libRNFS.a */,
6456441F1EB8DA9100672408 /* libRNFS.a */,
);
name = Products;
sourceTree = "<group>";
@ -74,6 +96,23 @@
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
6456441E1EB8DA9100672408 /* RNFS-tvOS */ = {
isa = PBXNativeTarget;
buildConfigurationList = 645644271EB8DA9100672408 /* Build configuration list for PBXNativeTarget "RNFS-tvOS" */;
buildPhases = (
6456441B1EB8DA9100672408 /* Sources */,
6456441C1EB8DA9100672408 /* Frameworks */,
6456441D1EB8DA9100672408 /* CopyFiles */,
);
buildRules = (
);
dependencies = (
);
name = "RNFS-tvOS";
productName = "RNFS-tvOS";
productReference = 6456441F1EB8DA9100672408 /* libRNFS.a */;
productType = "com.apple.product-type.library.static";
};
F12AFB9A1ADAF8F800E0535D /* RNFS */ = {
isa = PBXNativeTarget;
buildConfigurationList = F12AFBAF1ADAF8F800E0535D /* Build configuration list for PBXNativeTarget "RNFS" */;
@ -100,6 +139,10 @@
LastUpgradeCheck = 0630;
ORGANIZATIONNAME = "Johannes Lumpe";
TargetAttributes = {
6456441E1EB8DA9100672408 = {
CreatedOnToolsVersion = 8.3.2;
ProvisioningStyle = Automatic;
};
F12AFB9A1ADAF8F800E0535D = {
CreatedOnToolsVersion = 6.3;
};
@ -118,11 +161,23 @@
projectRoot = "";
targets = (
F12AFB9A1ADAF8F800E0535D /* RNFS */,
6456441E1EB8DA9100672408 /* RNFS-tvOS */,
);
};
/* End PBXProject section */
/* Begin PBXSourcesBuildPhase section */
6456441B1EB8DA9100672408 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
645644281EB8DAA100672408 /* NSArray+Map.m in Sources */,
645644291EB8DAA100672408 /* RNFSManager.m in Sources */,
6456442A1EB8DAA100672408 /* Downloader.m in Sources */,
6456442B1EB8DAA100672408 /* Uploader.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
F12AFB971ADAF8F800E0535D /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
@ -137,6 +192,40 @@
/* End PBXSourcesBuildPhase section */
/* Begin XCBuildConfiguration section */
645644251EB8DA9100672408 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_TESTABILITY = YES;
OTHER_LDFLAGS = "-ObjC";
PRODUCT_NAME = RNFS;
SDKROOT = appletvos;
SKIP_INSTALL = YES;
TVOS_DEPLOYMENT_TARGET = 10.2;
};
name = Debug;
};
645644261EB8DA9100672408 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
OTHER_LDFLAGS = "-ObjC";
PRODUCT_NAME = RNFS;
SDKROOT = appletvos;
SKIP_INSTALL = YES;
TVOS_DEPLOYMENT_TARGET = 10.2;
};
name = Release;
};
F12AFBAD1ADAF8F800E0535D /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
@ -250,6 +339,14 @@
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
645644271EB8DA9100672408 /* Build configuration list for PBXNativeTarget "RNFS-tvOS" */ = {
isa = XCConfigurationList;
buildConfigurations = (
645644251EB8DA9100672408 /* Debug */,
645644261EB8DA9100672408 /* Release */,
);
defaultConfigurationIsVisible = 0;
};
F12AFB961ADAF8F800E0535D /* Build configuration list for PBXProject "RNFS" */ = {
isa = XCConfigurationList;
buildConfigurations = (

View File

@ -7,12 +7,18 @@
//
#import "RNFSManager.h"
#import <React/RCTBridge.h>
#import "NSArray+Map.h"
#import "Downloader.h"
#import "Uploader.h"
#import <React/RCTEventDispatcher.h>
#import <React/RCTUtils.h>
#import <React/RCTImageLoader.h>
#import <CommonCrypto/CommonDigest.h>
#import <Photos/Photos.h>
@interface RNFSManager()
@ -46,6 +52,8 @@ RCT_EXPORT_METHOD(readDir:(NSString *)dirPath
NSDictionary *attributes = [fileManager attributesOfItemAtPath:path error:nil];
return @{
@"ctime": [self dateToTimeIntervalNumber:(NSDate *)[attributes objectForKey:NSFileCreationDate]],
@"mtime": [self dateToTimeIntervalNumber:(NSDate *)[attributes objectForKey:NSFileModificationDate]],
@"name": obj,
@"path": path,
@"size": [attributes objectForKey:NSFileSize],
@ -139,6 +147,43 @@ RCT_EXPORT_METHOD(appendFile:(NSString *)filepath
}
}
RCT_EXPORT_METHOD(write:(NSString *)filepath
contents:(NSString *)base64Content
position:(NSInteger)position
resolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject)
{
NSData *data = [[NSData alloc] initWithBase64EncodedString:base64Content options:NSDataBase64DecodingIgnoreUnknownCharacters];
NSFileManager *fM = [NSFileManager defaultManager];
if (![fM fileExistsAtPath:filepath])
{
BOOL success = [[NSFileManager defaultManager] createFileAtPath:filepath contents:data attributes:nil];
if (!success) {
return reject(@"ENOENT", [NSString stringWithFormat:@"ENOENT: no such file or directory, open '%@'", filepath], nil);
} else {
return resolve(nil);
}
}
@try {
NSFileHandle *fH = [NSFileHandle fileHandleForUpdatingAtPath:filepath];
if (position >= 0) {
[fH seekToFileOffset:position];
} else {
[fH seekToEndOfFile];
}
[fH writeData:data];
return resolve(nil);
} @catch (NSException *e) {
return reject(@"ENOENT", [NSString stringWithFormat:@"ENOENT: error writing file: '%@'", filepath], nil);
}
}
RCT_EXPORT_METHOD(unlink:(NSString*)filepath
resolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject)
@ -508,6 +553,90 @@ RCT_EXPORT_METHOD(getFSInfo:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromise
}
}
/**
* iOS Only: copy images from the assets-library (camera-roll) to a specific path, asuming
* JPEG-Images. Video-Support will follow up, not implemented yet.
*
* It is also supported to scale the image via scale-factor (0.0-1.0) or with a specific
* width and height. Also the resizeMode will be considered.
*/
RCT_EXPORT_METHOD(copyAssetsFileIOS: (NSString *) imageUri
toFilepath: (NSString *) destination
width: (NSInteger) width
height: (NSInteger) height
scale: (CGFloat) scale
compression: (CGFloat) compression
resizeMode: (RCTResizeMode) resizeMode
resolver: (RCTPromiseResolveBlock) resolve
rejecter: (RCTPromiseRejectBlock) reject)
{
CGSize size = CGSizeMake(width, height);
NSURL* url = [NSURL URLWithString:imageUri];
PHFetchResult *results = [PHAsset fetchAssetsWithALAssetURLs:@[url] options:nil];
if (results.count == 0) {
NSString *errorText = [NSString stringWithFormat:@"Failed to fetch PHAsset with local identifier %@ with no error message.", imageUri];
NSMutableDictionary* details = [NSMutableDictionary dictionary];
[details setValue:errorText forKey:NSLocalizedDescriptionKey];
NSError *error = [NSError errorWithDomain:@"RNFS" code:500 userInfo:details];
[self reject: reject withError:error];
return;
}
PHAsset *asset = [results firstObject];
PHImageRequestOptions *imageOptions = [PHImageRequestOptions new];
// Allow us to fetch images from iCloud
imageOptions.networkAccessAllowed = YES;
// Note: PhotoKit defaults to a deliveryMode of PHImageRequestOptionsDeliveryModeOpportunistic
// which means it may call back multiple times - we probably don't want that
imageOptions.deliveryMode = PHImageRequestOptionsDeliveryModeHighQualityFormat;
BOOL useMaximumSize = CGSizeEqualToSize(size, CGSizeZero);
CGSize targetSize;
if (useMaximumSize) {
targetSize = PHImageManagerMaximumSize;
imageOptions.resizeMode = PHImageRequestOptionsResizeModeNone;
} else {
targetSize = CGSizeApplyAffineTransform(size, CGAffineTransformMakeScale(scale, scale));
imageOptions.resizeMode = PHImageRequestOptionsResizeModeFast;
}
PHImageContentMode contentMode = PHImageContentModeAspectFill;
if (resizeMode == RCTResizeModeContain) {
contentMode = PHImageContentModeAspectFit;
}
// PHImageRequestID requestID =
[[PHImageManager defaultManager] requestImageForAsset:asset
targetSize:targetSize
contentMode:contentMode
options:imageOptions
resultHandler:^(UIImage *result, NSDictionary<NSString *, id> *info) {
if (result) {
NSData *imageData = UIImageJPEGRepresentation(result, compression );
[imageData writeToFile:destination atomically:YES];
resolve(destination);
} else {
NSMutableDictionary* details = [NSMutableDictionary dictionary];
[details setValue:info[PHImageErrorKey] forKey:NSLocalizedDescriptionKey];
NSError *error = [NSError errorWithDomain:@"RNFS" code:501 userInfo:details];
[self reject: reject withError:error];
}
}];
}
- (NSNumber *)dateToTimeIntervalNumber:(NSDate *)date
{
return @([date timeIntervalSince1970]);

View File

@ -67,7 +67,9 @@ public class Downloader extends AsyncTask<DownloadParams, int[], DownloadResult>
statusCode != HttpURLConnection.HTTP_OK &&
(
statusCode == HttpURLConnection.HTTP_MOVED_PERM ||
statusCode == HttpURLConnection.HTTP_MOVED_TEMP
statusCode == HttpURLConnection.HTTP_MOVED_TEMP ||
statusCode == 307 ||
statusCode == 308
)
);

View File

@ -26,6 +26,7 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.RandomAccessFile;
import java.net.URL;
import java.security.MessageDigest;
import java.util.HashMap;
@ -87,6 +88,29 @@ public class RNFSManager extends ReactContextBaseJavaModule {
}
}
@ReactMethod
public void write(String filepath, String base64Content, int position, Promise promise) {
try {
byte[] bytes = Base64.decode(base64Content, Base64.DEFAULT);
if (position < 0) {
FileOutputStream outputStream = new FileOutputStream(filepath, true);
outputStream.write(bytes);
outputStream.close();
} else {
RandomAccessFile file = new RandomAccessFile(filepath, "rw");
file.seek(position);
file.write(bytes);
file.close();
}
promise.resolve(null);
} catch (Exception ex) {
ex.printStackTrace();
reject(promise, filepath, ex);
}
}
@ReactMethod
public void exists(String filepath, Promise promise) {
try {
@ -259,6 +283,7 @@ public class RNFSManager extends ReactContextBaseJavaModule {
for (File childFile : files) {
WritableMap fileMap = Arguments.createMap();
fileMap.putInt("mtime", (int)childFile.lastModified());
fileMap.putString("name", childFile.getName());
fileMap.putString("path", childFile.getAbsolutePath());
fileMap.putInt("size", (int)childFile.length());

View File

@ -1,14 +1,15 @@
{
"name": "react-native-fs",
"version": "v2.1.0-rc.1",
"version": "2.3.2",
"description": "Native filesystem access for react-native",
"main": "FS.common.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
"test": "echo \"Error: no test specified\" && exit 1",
"flow": "flow; test $? -eq 0 -o $? -eq 2"
},
"repository": {
"type": "git",
"url": "git@github.com:johanneslumpe/react-native-fs.git"
"url": "git@github.com:itinance/react-native-fs.git"
},
"keywords": [
"react-component",
@ -28,7 +29,7 @@
"utf8": "^2.1.1"
},
"devDependencies": {
"flow-bin": "0.27.0",
"flow-bin": "0.28.0",
"react": "^15.4.2",
"react-native": "^0.40.0"
}

3946
yarn.lock Normal file

File diff suppressed because it is too large Load Diff