React native выбор файла
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Open with Desktop
- View raw
- Copy raw contents Copy raw contents
Copy raw contents
Copy raw contents
Native filesystem access for react-native
For RN >= 0.57 and/or Gradle >= 3 you MUST install react-native-fs at version >= @2.13.2!
For RN >= 0.61 please install react-native-fs at version >= @2.16.0!
Table of Contents
View the changelog here.
First you need to install react-native-fs:
Note: If your react-native version is < 0.40 install with this tag instead:
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:
react-native link react-native-fs
Done! No need to worry about manually adding the library to your project.
Adding with CocoaPods
Add the RNFS pod to your list of application pods in your Podfile, using the path from the Podfile to the installed module:~~
Install pods as usual:
Adding Manually in XCode
In XCode, in the project navigator, right click Libraries ➜ Add Files to [your project's name] Go to node_modules ➜ react-native-fs and add the .xcodeproj file
In XCode, in the project navigator, select your project. Add the lib*.a from the RNFS project to your project's Build Phases ➜ Link Binary With Libraries. Click the .xcodeproj file you added before in the project navigator and go the Build Settings tab. Make sure 'All' is toggled on (instead of 'Basic'). Look for Header Search Paths and make sure it contains both $(SRCROOT)/../react-native/React and $(SRCROOT)/../../React - mark both as recursive.
Run your project (Cmd+R)
Android support is currently limited to only the DocumentDirectory . This maps to the app's files directory.
Make alterations to the following files:
register module (in MainActivity.java)
- For react-native below 0.19.0 (use cat ./node_modules/react-native/package.json | grep version )
- For react-native 0.29.0 and higher ( in MainApplication.java )
Adding automatically with react-native link
The link command also works for adding the native dependency on Windows:
react-native link react-native-fs
Adding Manually in Visual Studio
Follow the instructions in the 'Linking Libraries' documentation on the react-native-windows GitHub repo. For the first step of adding the project to the Visual Studio solution file, the path to the project should be ../node_modules/react-native-fs/windows/RNFS/RNFS.csproj .
File upload (Android and IOS only)
The following constants are available on the RNFS export:
- MainBundlePath ( String ) The absolute path to the main bundle directory (not available on Android)
- CachesDirectoryPath ( String ) The absolute path to the caches directory
- ExternalCachesDirectoryPath ( String ) The absolute path to the external caches directory (android only)
- DocumentDirectoryPath ( String ) The absolute path to the document directory
- DownloadDirectoryPath ( String ) The absolute path to the download directory (on android only)
- TemporaryDirectoryPath ( String ) The absolute path to the temporary directory (falls back to Caching-Directory on Android)
- 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)
IMPORTANT: when using ExternalStorageDirectoryPath it's necessary to request permissions (on Android) to read and write on the external storage, here an example: React Native Offical Doc
readDir(dirpath: string): Promise
Reads the contents of path . This must be an absolute path. Use the above path constants to form a usable file path.
The returned promise resolves with an array of objects with the following properties:
readDirAssets(dirpath: string): Promise
Reads the contents of dirpath in the Android app's assets folder. dirpath is the relative path to the file from the root of the assets folder.
The returned promise resolves with an array of objects with the following properties:
Note: Android only.
readdir(dirpath: string): Promise
Node.js style version of readDir that returns only the names. Note the lowercase d .
stat(filepath: string): Promise
Stats an item at filepath . If the filepath is linked to a virtual file, for example Android Content URI, the originalPath can be used to find the pointed file path. The promise resolves with an object with the following properties:
readFile(filepath: string, encoding?: string): Promise
Reads the file at path and return contents. encoding can be one of utf8 (default), ascii , base64 . Use base64 for reading binary files.
Note: you will take quite a performance hit if you are reading big files
read(filepath: string, length = 0, position = 0, encodingOrOptions?: any): Promise
Reads length bytes from the given position of the file at path and returns contents. encoding can be one of utf8 (default), ascii , base64 . Use base64 for reading binary files.
Note: reading big files piece by piece using this method may be useful in terms of performance.
readFileAssets(filepath:string, encoding?: string): Promise
Reads the file at path in the Android app's assets folder and return contents. encoding can be one of utf8 (default), ascii , base64 . Use base64 for reading binary files.
filepath is the relative path to the file from the root of the assets folder.
Note: Android only.
readFileRes(filename:string, encoding?: string): Promise
Reads the file named filename in the Android app's res folder and return contents. Only the file name (not folder) needs to be specified. The file type will be detected from the extension and automatically located within res/drawable (for image files) or res/raw (for everything else). encoding can be one of utf8 (default), ascii , base64 . Use base64 for reading binary files.
Note: Android only.
writeFile(filepath: string, contents: string, encoding?: string): Promise
Write the contents to filepath . encoding can be one of utf8 (default), ascii , base64 . options optionally takes an object specifying the file's properties, like mode etc.
appendFile(filepath: string, contents: string, encoding?: string): Promise
Append the contents to filepath . encoding can be one of utf8 (default), ascii , base64 .
write(filepath: string, contents: string, position?: number, encoding?: string): Promise
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
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.
copyFile(filepath: string, destPath: string): Promise
Copies the file located at filepath to destPath .
Note: On Android copyFile will overwrite destPath if it already exists. On iOS an error will be thrown if the file already exists.
copyFileAssets(filepath: string, destPath: string): Promise
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.
copyFileRes(filename: string, destPath: string): Promise
Copies the file named filename in the Android app's res folder and copies it to the given destPath path. res/drawable is used as the source parent folder for image files, res/raw for everything else.
Note: Android only. Will overwrite destPath if it already exists.
(iOS only) copyAssetsFileIOS(imageUri: string, destPath: string, width: number, height: number, scale?: number, compression?: number, resizeMode?: string): Promise
Not available on Mac Catalyst.
Reads an image file from Camera Roll and writes to destPath . This method assumes the image file to be JPEG file. This method will download the original from iCloud if necessary.
imageUri string (required)
URI of a file in Camera Roll. Can be either of the following formats:
- ph://CC95F08C-88C3-4012-9D6D-64A413D254B3/L0/001
- assets-library://asset/asset.JPG?id=CC95F08C-88C3-4012-9D6D-64A413D254B3&ext=JPG
destPath string (required)
Destination to which the copied file will be saved, e.g. RNFS.TemporaryDirectoryPath + 'example.jpg' .
width number (required)
Copied file's image width will be resized to width . If 0 is provided, width won't be resized.
height number (required)
Copied file's image height will be resized to height . If 0 is provided, height won't be resized.
scale number (optional)
Copied file's image will be scaled proportional to scale factor from width x height . If both width and height are 0, the image won't scale. Range is [0.0, 1.0] and default is 1.0.
compression number (optional)
Quality of copied file's image. The value 0.0 represents the maximum compression (or lowest quality) while the value 1.0 represents the least compression (or best quality). Range is [0.0, 1.0] and default is 1.0.
resizeMode string (optional)
If resizeMode is 'contain', copied file's image will be scaled so that its larger dimension fits width x height . If resizeMode is other value than 'contain', the image will be scaled so that it completely fills width x height . Default is 'contain'. Refer to PHImageContentMode.
Copied file's URI.
One can use this method also to create a thumbNail from a video in a specific size. Currently it is impossible to specify a concrete position, the OS will decide wich Thumbnail you'll get then. To copy a video from assets-library and save it as a mp4-file, refer to copyAssetsVideoIOS.
(iOS only) copyAssetsVideoIOS(videoUri: string, destPath: string): Promise
Not available on Mac Catalyst.
Copies a video from assets-library, that is prefixed with 'assets-library://asset/asset.MOV. ' to a specific destination.
unlink(filepath: string): Promise
Unlinks the item at filepath . If the item does not exist, an error will be thrown.
Also recursively deletes directories (works like Linux rm -rf ).
exists(filepath: string): Promise
Check if the item exists at filepath . If the item does not exist, return false.
existsAssets(filepath: string): Promise
Check in the Android assets folder if the item exists. filepath is the relative path from the root of the assets folder. If the item does not exist, return false.
Note: Android only.
existsRes(filename: string): Promise
Check in the Android res folder if the item named filename exists. res/drawable is used as the parent folder for image files, res/raw for everything else. If the item does not exist, return false.
Note: Android only.
hash(filepath: string, algorithm: string): Promise
Reads the file at path and returns its checksum as determined by algorithm , which can be one of md5 , sha1 , sha224 , sha256 , sha384 , sha512 .
touch(filepath: string, mtime?: Date, ctime?: Date): Promise
Sets the modification timestamp mtime and creation timestamp ctime of the file at filepath . Setting ctime is only supported on iOS, android always sets both timestamps to mtime .
mkdir(filepath: string, options?: MkdirOptions): Promise
Create a directory at filepath . Automatically creates parents and does not throw if already exists (works like Linux mkdir -p ).
(IOS only): The NSURLIsExcludedFromBackupKey property can be provided to set this attribute on iOS platforms. Apple will reject apps for storing offline cache data that does not have this attribute.
Download file from options.fromUrl to options.toFile . Will overwrite any previously existing file.
If options.begin is provided, it will be invoked once upon download starting when headers have been received and passed a single argument with the following properties:
If options.progress is provided, it will be invoked continuously and passed a single argument with the following properties:
If options.progressInterval is provided, it will return progress events in the maximum frequency of progressDivider . For example, if progressInterval = 100, you will not receive callbacks more often than every 100th millisecond.
If options.progressDivider is provided, it will return progress events that divided by progressDivider .
For example, if progressDivider = 10, you will receive only ten callbacks for this values of progress: 0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100 Use it for performance issues. If progressDivider = 0, you will receive all progressCallback calls, default value is 0.
(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, see the Background Downloads Tutorial (iOS) section.
(IOS only): If options.resumable is provided, it will be invoked when the download has stopped and and can be resumed using resumeDownload() .
stopDownload(jobId: number): void
Abort the current download job with this ID. The partial file will remain on the filesystem.
(iOS only) resumeDownload(jobId: number): void
Resume the current download job with this ID.
(iOS only) isResumable(jobId: number): Promise
Check if the the download job with this ID is resumable with resumeDownload() .
(iOS only) completeHandlerIOS(jobId: number): void
For use when using background downloads, tell iOS you are done handling a completed download.
Read more about background downloads in the Background Downloads Tutorial (iOS) section.
options ( Object ) - An object containing named parameters
If options.begin is provided, it will be invoked once upon upload has begun:
If options.progress is provided, it will be invoked continuously and passed a single object with the following properties:
Percentage can be computed easily by dividing totalBytesSent by totalBytesExpectedToSend .
(iOS only) stopUpload(jobId: number): Promise
Abort the current upload job with this ID.
Returns an object with the following properties:
(Android only) scanFile(path: string): Promise
Scan the file using Media Scanner.
(Android only) getAllExternalFilesDirs(): Promise
Returns an array with the absolute paths to application-specific directories on all shared/external storage devices where the application can place persistent files it owns.
(iOS only) pathForGroup(groupIdentifier: string): Promise
groupIdentifier ( string ) Any value from the com.apple.security.application-groups entitlements list.
Returns the absolute path to the directory shared for all applications with the same security group identifier. This directory can be used to to share files between application of the same developer.
Invalid group identifier will cause a rejection.
For more information read the Adding an App to an App Group section.
Background Downloads Tutorial (iOS)
Background downloads in iOS require a bit of a setup.
First, in your AppDelegate.m file add the following:
The handleEventsForBackgroundURLSession method is called when a background download is done and your app is not in the foreground.
We need to pass the completionHandler to RNFS along with its identifier .
BE AWARE! iOS will give about 30 sec. to run your code after handleEventsForBackgroundURLSession is called and until completionHandler is triggered so don't do anything that might take a long time (like unzipping), you will be able to do it after the user re-launces the app, otherwide iOS will terminate your app.
Test app to demostrate the use of the module. Useful for testing and developing the module:
Native filesystem access for react-native
For RN >= 0.57 and/or Gradle >= 3 you MUST install react-native-fs at version >= @2.13.2!
For RN >= 0.61 please install react-native-fs at version >= @2.16.0!
Table of Contents
View the changelog here.
First you need to install react-native-fs:
Note: If your react-native version is < 0.40 install with this tag instead:
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:
react-native link react-native-fs
Done! No need to worry about manually adding the library to your project.
Adding with CocoaPods
Add the RNFS pod to your list of application pods in your Podfile, using the path from the Podfile to the installed module:~~
Install pods as usual:
Adding Manually in XCode
In XCode, in the project navigator, right click Libraries ➜ Add Files to [your project's name] Go to node_modules ➜ react-native-fs and add the .xcodeproj file
In XCode, in the project navigator, select your project. Add the lib*.a from the RNFS project to your project's Build Phases ➜ Link Binary With Libraries. Click the .xcodeproj file you added before in the project navigator and go the Build Settings tab. Make sure 'All' is toggled on (instead of 'Basic'). Look for Header Search Paths and make sure it contains both $(SRCROOT)/../react-native/React and $(SRCROOT)/../../React - mark both as recursive.
Run your project (Cmd+R)
Android support is currently limited to only the DocumentDirectory . This maps to the app's files directory.
Make alterations to the following files:
register module (in MainActivity.java)
- For react-native below 0.19.0 (use cat ./node_modules/react-native/package.json | grep version )
- For react-native 0.29.0 and higher ( in MainApplication.java )
Adding automatically with react-native link
The link command also works for adding the native dependency on Windows:
react-native link react-native-fs
Adding Manually in Visual Studio
Follow the instructions in the 'Linking Libraries' documentation on the react-native-windows GitHub repo. For the first step of adding the project to the Visual Studio solution file, the path to the project should be ../node_modules/react-native-fs/windows/RNFS/RNFS.csproj .
File upload (Android and IOS only)
The following constants are available on the RNFS export:
- MainBundlePath ( String ) The absolute path to the main bundle directory (not available on Android)
- CachesDirectoryPath ( String ) The absolute path to the caches directory
- ExternalCachesDirectoryPath ( String ) The absolute path to the external caches directory (android only)
- DocumentDirectoryPath ( String ) The absolute path to the document directory
- DownloadDirectoryPath ( String ) The absolute path to the download directory (on android only)
- TemporaryDirectoryPath ( String ) The absolute path to the temporary directory (falls back to Caching-Directory on Android)
- 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)
IMPORTANT: when using ExternalStorageDirectoryPath it's necessary to request permissions (on Android) to read and write on the external storage, here an example: React Native Offical Doc
readDir(dirpath: string): Promise
Reads the contents of path . This must be an absolute path. Use the above path constants to form a usable file path.
The returned promise resolves with an array of objects with the following properties:
readDirAssets(dirpath: string): Promise
Reads the contents of dirpath in the Android app's assets folder. dirpath is the relative path to the file from the root of the assets folder.
The returned promise resolves with an array of objects with the following properties:
Note: Android only.
readdir(dirpath: string): Promise
Node.js style version of readDir that returns only the names. Note the lowercase d .
stat(filepath: string): Promise
Stats an item at filepath . If the filepath is linked to a virtual file, for example Android Content URI, the originalPath can be used to find the pointed file path. The promise resolves with an object with the following properties:
readFile(filepath: string, encoding?: string): Promise
Reads the file at path and return contents. encoding can be one of utf8 (default), ascii , base64 . Use base64 for reading binary files.
Note: you will take quite a performance hit if you are reading big files
read(filepath: string, length = 0, position = 0, encodingOrOptions?: any): Promise
Reads length bytes from the given position of the file at path and returns contents. encoding can be one of utf8 (default), ascii , base64 . Use base64 for reading binary files.
Note: reading big files piece by piece using this method may be useful in terms of performance.
readFileAssets(filepath:string, encoding?: string): Promise
Reads the file at path in the Android app's assets folder and return contents. encoding can be one of utf8 (default), ascii , base64 . Use base64 for reading binary files.
filepath is the relative path to the file from the root of the assets folder.
Note: Android only.
readFileRes(filename:string, encoding?: string): Promise
Reads the file named filename in the Android app's res folder and return contents. Only the file name (not folder) needs to be specified. The file type will be detected from the extension and automatically located within res/drawable (for image files) or res/raw (for everything else). encoding can be one of utf8 (default), ascii , base64 . Use base64 for reading binary files.
Note: Android only.
writeFile(filepath: string, contents: string, encoding?: string): Promise
Write the contents to filepath . encoding can be one of utf8 (default), ascii , base64 . options optionally takes an object specifying the file's properties, like mode etc.
appendFile(filepath: string, contents: string, encoding?: string): Promise
Append the contents to filepath . encoding can be one of utf8 (default), ascii , base64 .
write(filepath: string, contents: string, position?: number, encoding?: string): Promise
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
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.
copyFile(filepath: string, destPath: string): Promise
Copies the file located at filepath to destPath .
Note: On Android copyFile will overwrite destPath if it already exists. On iOS an error will be thrown if the file already exists.
copyFileAssets(filepath: string, destPath: string): Promise
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.
copyFileRes(filename: string, destPath: string): Promise
Copies the file named filename in the Android app's res folder and copies it to the given destPath path. res/drawable is used as the source parent folder for image files, res/raw for everything else.
Note: Android only. Will overwrite destPath if it already exists.
(iOS only) copyAssetsFileIOS(imageUri: string, destPath: string, width: number, height: number, scale?: number, compression?: number, resizeMode?: string): Promise
Not available on Mac Catalyst.
Reads an image file from Camera Roll and writes to destPath . This method assumes the image file to be JPEG file. This method will download the original from iCloud if necessary.
imageUri string (required)
URI of a file in Camera Roll. Can be either of the following formats:
- ph://CC95F08C-88C3-4012-9D6D-64A413D254B3/L0/001
- assets-library://asset/asset.JPG?id=CC95F08C-88C3-4012-9D6D-64A413D254B3&ext=JPG
destPath string (required)
Destination to which the copied file will be saved, e.g. RNFS.TemporaryDirectoryPath + 'example.jpg' .
width number (required)
Copied file's image width will be resized to width . If 0 is provided, width won't be resized.
height number (required)
Copied file's image height will be resized to height . If 0 is provided, height won't be resized.
scale number (optional)
Copied file's image will be scaled proportional to scale factor from width x height . If both width and height are 0, the image won't scale. Range is [0.0, 1.0] and default is 1.0.
compression number (optional)
Quality of copied file's image. The value 0.0 represents the maximum compression (or lowest quality) while the value 1.0 represents the least compression (or best quality). Range is [0.0, 1.0] and default is 1.0.
resizeMode string (optional)
If resizeMode is 'contain', copied file's image will be scaled so that its larger dimension fits width x height . If resizeMode is other value than 'contain', the image will be scaled so that it completely fills width x height . Default is 'contain'. Refer to PHImageContentMode.
Copied file's URI.
One can use this method also to create a thumbNail from a video in a specific size. Currently it is impossible to specify a concrete position, the OS will decide wich Thumbnail you'll get then. To copy a video from assets-library and save it as a mp4-file, refer to copyAssetsVideoIOS.
(iOS only) copyAssetsVideoIOS(videoUri: string, destPath: string): Promise
Not available on Mac Catalyst.
Copies a video from assets-library, that is prefixed with 'assets-library://asset/asset.MOV. ' to a specific destination.
unlink(filepath: string): Promise
Unlinks the item at filepath . If the item does not exist, an error will be thrown.
Also recursively deletes directories (works like Linux rm -rf ).
exists(filepath: string): Promise
Check if the item exists at filepath . If the item does not exist, return false.
existsAssets(filepath: string): Promise
Check in the Android assets folder if the item exists. filepath is the relative path from the root of the assets folder. If the item does not exist, return false.
Note: Android only.
existsRes(filename: string): Promise
Check in the Android res folder if the item named filename exists. res/drawable is used as the parent folder for image files, res/raw for everything else. If the item does not exist, return false.
Note: Android only.
hash(filepath: string, algorithm: string): Promise
Reads the file at path and returns its checksum as determined by algorithm , which can be one of md5 , sha1 , sha224 , sha256 , sha384 , sha512 .
touch(filepath: string, mtime?: Date, ctime?: Date): Promise
Sets the modification timestamp mtime and creation timestamp ctime of the file at filepath . Setting ctime is only supported on iOS, android always sets both timestamps to mtime .
mkdir(filepath: string, options?: MkdirOptions): Promise
Create a directory at filepath . Automatically creates parents and does not throw if already exists (works like Linux mkdir -p ).
(IOS only): The NSURLIsExcludedFromBackupKey property can be provided to set this attribute on iOS platforms. Apple will reject apps for storing offline cache data that does not have this attribute.
Download file from options.fromUrl to options.toFile . Will overwrite any previously existing file.
If options.begin is provided, it will be invoked once upon download starting when headers have been received and passed a single argument with the following properties:
If options.progress is provided, it will be invoked continuously and passed a single argument with the following properties:
If options.progressInterval is provided, it will return progress events in the maximum frequency of progressDivider . For example, if progressInterval = 100, you will not receive callbacks more often than every 100th millisecond.
If options.progressDivider is provided, it will return progress events that divided by progressDivider .
For example, if progressDivider = 10, you will receive only ten callbacks for this values of progress: 0, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100 Use it for performance issues. If progressDivider = 0, you will receive all progressCallback calls, default value is 0.
(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, see the Background Downloads Tutorial (iOS) section.
(IOS only): If options.resumable is provided, it will be invoked when the download has stopped and and can be resumed using resumeDownload() .
stopDownload(jobId: number): void
Abort the current download job with this ID. The partial file will remain on the filesystem.
(iOS only) resumeDownload(jobId: number): void
Resume the current download job with this ID.
(iOS only) isResumable(jobId: number): Promise
Check if the the download job with this ID is resumable with resumeDownload() .
(iOS only) completeHandlerIOS(jobId: number): void
For use when using background downloads, tell iOS you are done handling a completed download.
Read more about background downloads in the Background Downloads Tutorial (iOS) section.
options ( Object ) - An object containing named parameters
If options.begin is provided, it will be invoked once upon upload has begun:
If options.progress is provided, it will be invoked continuously and passed a single object with the following properties:
Percentage can be computed easily by dividing totalBytesSent by totalBytesExpectedToSend .
(iOS only) stopUpload(jobId: number): Promise
Abort the current upload job with this ID.
Returns an object with the following properties:
(Android only) scanFile(path: string): Promise
Scan the file using Media Scanner.
(Android only) getAllExternalFilesDirs(): Promise
Returns an array with the absolute paths to application-specific directories on all shared/external storage devices where the application can place persistent files it owns.
(iOS only) pathForGroup(groupIdentifier: string): Promise
groupIdentifier ( string ) Any value from the com.apple.security.application-groups entitlements list.
Returns the absolute path to the directory shared for all applications with the same security group identifier. This directory can be used to to share files between application of the same developer.
Invalid group identifier will cause a rejection.
For more information read the Adding an App to an App Group section.
Background Downloads Tutorial (iOS)
Background downloads in iOS require a bit of a setup.
First, in your AppDelegate.m file add the following:
The handleEventsForBackgroundURLSession method is called when a background download is done and your app is not in the foreground.
We need to pass the completionHandler to RNFS along with its identifier .
BE AWARE! iOS will give about 30 sec. to run your code after handleEventsForBackgroundURLSession is called and until completionHandler is triggered so don't do anything that might take a long time (like unzipping), you will be able to do it after the user re-launces the app, otherwide iOS will terminate your app.
Test app to demostrate the use of the module. Useful for testing and developing the module:
If this project has helped you out, please support us with a star 🌟
This library is a ReactNative Bridge around native libraries. It allows you to natively select/pick file from device file system:
Android: nbsp-team/MaterialFilePicker/ |
---|
Note: It allows you to pick file without using Intent/Third Party Software
Note: It allows you to select only local files associate to app sandbox.
$ npm install react-native-file-selector --save
This library is supports RN60 and above
iOS Prerequisite: Please make sure CocoaPods is installed on your system
Please make sure Flipper iOS Setup Guidelines steps are added to Podfile, since iOSPhotoEditor is implemented using Swift and we have to use use_frameworks! in Podfile
Android
Add below color attributes in your app's android/app/src/main/res/values/color.xml file. You can provide your own color codes.
import RNFileSelector from 'react-native-file-selector';
Prop | Type | Default | Note |
---|---|---|---|
title | string | Title on the toolbar | |
closeMenu | string | true | Color of tint |
hiddenFiles: Android | bool | false | If true it shows hidden files as well |
path | string | Path of directory | |
filter | string | Filter to sort the files | |
filterDirectories: Android | bool | Filter should be applied on directories or not | |
onDone | func | Function called when file is selected | |
onCancel | func | Function called when file selector is closed without selecting any file | |
visible | bool | false | To invoke file selector |
🤔 How to contribute
Have an idea? Found a bug? Please raise to ISSUES. Contributions are welcome and are greatly appreciated! Every little bit helps, and credit will always be given.
💫 Where is this library used?
If you are using this library in one of your projects, add it in this list below. ✨
This library is provided under the Apache License.
💖 Support my projects
I open-source almost everything I can, and I try to reply everyone needing help using these projects. Obviously, this takes time. You can integrate and use these projects in your applications for free! You can even change the source code and redistribute (even resell it).
However, if you get some profit from this or just want to encourage me to continue creating stuff, there are few ways you can do it:
In this tutorial you will learn how to create native modules for ReactNative, how to download a file and how to store it on device, and how to send and store images in gallery on both IOS and Android, although this is not a very detailed tutorial on Java or ObjectiveC but i will try to explain anything when it’s possible.
My first experience with ReactNative was like, what the heck? what am I supposed to do with this thing, this thing gonna wrap me up, will cuff my hands, and keep me from being free to do anything i like to do, like writing api specific codes or other thing, well you might wonder why do i actually use ReactNative, that’s interesting but we get on to that later, but for this problem I found that I could write native codes to connect my application to outside world (yeah it’s actually like that), well it’s simple, you write native modules on both side on some standards, native modules are like interfaces, you should be careful to write modules on both side with the same function names and same variables to make them available on both IOS and android, it’s not that complicated that i’m saying it is, it is actually so so simple.
First of all, let me explain something to you, we are going to use “Base64” encryption everywhere in our IO streams and data communication between React and our Native Modules, also we are going to use it to display some image on some view.
In Javascript world we would be very happy to use Base64 strings, the good approach is to download a file as an ArrayBuffer, then convert it to Base64 string, then we could pass it to either Native Modules or to do other things with it. here is an example how:
In this part we are going to create a fresh codebase using React Native CLI, let’s initialize a blank React application
You will need Node, Watchman, the React Native command line interface, and Xcode (on Mac), and I assume you know how to do this on Linux or Windows, but the purpose of this tutorial is to make modules available to both IOS and Android, and since you could only compile ObjectiveC code on MacOS (Jesus, sounds so selfish to me) i decided to explain it, only on mac, so excuse me for this :)
Let me tell you a secret, i use Yarn :) [f**k npm, don’t ask, join the campain]
Then we create project using command line:
Don’t forget to add dependencies:
Now lets add some functionality to our app, like when user hit a Button, download task starts and after that, we save downloaded file to phone.
Now we’re going to add IOS module, go to [project directory]/ios/ and open ioBridgeModule.xcodeproj using XCode then:
- right click on the project and create a Group named MyModules then >
- add a new Cocoa Touch Class named FileIO and click next.
Now that we have created our classes let’s add it to React Modules, and add a function to determine where to store our files, in IOS there’s a local Documents folder, were gonna use that to store our data:
Now we want to pass data from Javasrcript to NativeModule, we have to use a special type of functions to do this, unlike resolvePath that we have written before there are other types of methods in ReactNative that allows us to expose native functionality to our application, we use ReactNative predefined macros to do this.
F irst approach is to use synchronous methods, they declared using RCT_EXPORT_METHOD and they allow us to send data to module at time, no callback, and no return, like a one way street:
and in javascript:
S econd approach is to use callbacks, we declare them using RCT_EXPORT_METHOD with RCTResponseSenderBlock as argument, in javascript we send a callback function as an argument to function:
and in javascript:
T hird approach is to use Promise like interface to call our native function, we declare them using RCT_REMAP_METHOD:
and in javascript:
[save method] Now that we understand how bridge methods works, let’s add a save method to store a file to device.
open FileIO.m and add these lines, saving file to device doesn’t need to be asynchronous unless we want to see if file stored successfully or find out if any error occurred.
Now let’s go back to our App.js and use this function to save downloaded file to device:
then run it using command line react-native run-ios , then click on “Download” button. you should see “Download Finished!” on the screen.
Now lets check if file stored correctly in device storage, Simulator files are located at somewhere on ~/Library/Developer/CoreSimulator/. /Documents/
now let’s add some other methods before we get to AndroidModule Instalation. here is full FileIO.h and FileIO.m :
Now we could use these functions too
Well it’s time to give our chance to android, we are going to write exact functions on android too, with the same interface like mentioned above.
First of all open [project directory]/android/ inside AndroidStudio and if you don’t have it, it’s not a problem, you could add Java Classes and gradle will build it for you.
Now inside /app/src/main/java/com/iobridgemodule/ add two Java Class, one named StorageModule.java and another StoragePackage.java
and in StorageModule.java:
and one another step, you have to add your Package to Application, now inside MainApplication.java add StoragePackage where getPackages functions declared:
almost done, now you can test your application,
first run an emulator then cmd react-native run-android :)
Now what if we wanted to view the information, consider a scenario where you downloaded a picture, you wanted to store it and use it later for offline use, first of all ReactNative is fully capable of showing Base64 images, see example bellow :
try to make these changes to App.js:
in this part we are going to create some wrapper in both Android and IOS to do such action for us, let’s start with ObjectiveC.
open FileIO.h and include UIKit.h header, we are going to need it to store images.
then open FileIO.m and add these two functions :
now open Info.plist and add these two lines:
or follow these instruction > open Info.plist in Xcode > then add a new key inside “Information Property List” > Search for “Privacy — Photo Library Additions Usage Description” > then were done
compile application and we done :) hooof
we’re gonna change App.js again. (don’t kill me) to add a save button, i tried my best to cover everything including this :D
Now if you run the application and press on “Save” button you see that it get stored on gallery.
Now let’s do the same on android:
open StorageModule.java and add these a few lines:
and don’t forget to give needed permissions to AndroidManifest.xml
Now we’re done, let’s test it :) haha it works, and here’s the screenshot:
I think we’re done here, and i have to tell you this was the first Story of mine on Medium, please give me feedback, i do really love to prepare more tutorial for you. and if there are any grammar mistakes please tell me :) my english is awful (kidding)
Фреймворк React Native радикально изменил процесс разработки мобильных приложений, особенно после создания таких гибридных мобильных приложений, как Phone-gap, Ionichas и т.д.
Однако набора компонентов React Native вам будет недостаточно, если вы нацелены на разработку масштабируемого и обслуживаемого продакшн приложения. В этом случае вы столкнетесь с необходимостью создания проекта с различными широко применяемыми пакетами npm, разработанными крутым сообществом свободного программного обеспечения, и тем самым ускорите процесс разработки приложения.
В этой статье мы рассмотрим различные библиотеки и инструменты, на которые вам стоит обратить внимание при создании очередного приложения на React Native. Надеюсь, что материал статьи поможет вам сделать правильный выбор на разных этапах разработки.
На официальном сайте React Native предлагается два способа установки фреймворка — Expo CLI и React Native CLI. Рассмотрим достоинства и недостатки каждого из них.
Jest и enzyme
+являются простыми фреймворками для тестирования;
+поддерживают TypeScript, Node, React, Angular и Vue;
+содержат фреймворки тестовых макетов;
+имеют огромное сообщество разработчиков.
В процессе разработки крупного или долгосрочного приложения вам не обойтись без четкой стратегии управления состояниями и обменом данных между компонентами.
Graphql Appolo client
+ использует один клиент для REST APIs и Graphql APIs;
+ по умолчанию помогает в кэшировании данных;
- не часто используется в продакшне.
Если вы ищите способ повторного использования вашего кода, создания простой в обслуживании кодовой базы и сохранения согласованного UI, то начинайте пользоваться хабами облачных компонентов, например, Bit.dev.
Firebase Crashlytics
Самый известный инструмент сервиса аналитики мобильных приложений Fabric объединился с Google и стал известен как Firebase Crashlytics. Он бесплатный и предоставляет полный отчет о сбоях. Firebase Crashlytics также интегрируется с корпоративным менеджером Slack, так что вы можете получать уведомления о сбоях в режиме реального времени.
В большинстве случаев необходимо распространить приложение для увеличения числа команды разработчиков или клиентов, чтобы таким образом получить обратную связь перед фактическим опубликованием приложения в App Store. Вы можете воспользоваться функционалом таких платформ, как Firebase, App Center и Testfairy.
Testfairy
+нацелена на предприятия с поддержкой;
+предлагает оригинальные функции, такие как встряхивание устройства для получения отчета об ошибке и создания тикета в Jira;
+предоставляет автоматическую запись видео того пользовательского потока, который ведет к сбою/ошибке;
- требует покупки лицензии.
На этапе распространения и публикации приложения любой крупной команде разработчиков следует автоматизировать этот процесс для экономии времени и предотвращения ошибки. Рассмотрим следующие варианты:
TypeScript
TypeScript — это язык программирования c открытым исходным кодом, являющийся расширенной строгой синтаксической версией JavaScript.
+очень популярен в сообществе программистов и широко используется в бэкенд и фронтенд разработках таких, как NodeJs, Angular 2+, VueJs и др;
+ быстрее, чем Flow;
- имеет ограничения в поддержке React.
Flow не является языком программирования, но представляет собой статический модуль проверки типов для JavaScript.
+отлично поддерживает React;
- Facebook переходит к использованию TypeScript вместо Flow;
- имеет небольшое сообщество разработчиков;
- плохая документация.
Axios
+проверенный временем и классический способ формирования запросов;
-потребуется отдельная библиотека для использования GraphQL APIs.
Хуки и Context API
Отметим, что Redux использует внутри Context API , который по началу носил экспериментальный характер и был добавлен в React 16.4 для продакшна. Использование хуков React и React Context API позволит не зависеть от библиотеки и уменьшить размер приложения. При работе с хуками React и React Context API:
+отсутствует необходимость добавлять новую библиотеку, что позволяет уменьшить размер приложения;
- требуется планирование и стандартное соглашение всех разработчиков, работающих над приложением.
При наличии более двух экранов, вам понадобится определить маршрут и навигацию, которые были бы масштабируемыми и простыми в обслуживании. В этом случае вам поможет навигация React.
React Context API
+использует контекстное API React;
+прост в использовании;
- требует пользовательской реализации для использования разнообразных функций, таких как множественное число и контекст (например, мужской/женский род).
Bitrise
Это один из самых легких и быстрых способов создания и публикации приложений.
+отличается быстрой настройкой;
+полноценно интегрируется с Firebase, Slack и другими платформами;
+Fastlane;
+предполагает комплексный подход при создании приложений для Android или iOS;
-требует платной лицензии.
Firebase
+идет совместно с пакетом Google сервисов, таких как Crashlytics, Analytics, OCR др;
-требует много времени на настройку и публикацию приложения;
- находится на стадии бета-версии.
React-hook-form
+превосходит в производительности Formik;
+ поддерживает хуки, простая и удобная библиотека для разработок.
- имеет небольшое сообщество.
Разрабатывая крупные и сложные приложения, мы стремимся сделать их переносимыми на разные устройства, масштабируемыми и способными к непрерывному развертыванию. В связи с этим возникает потребность в хорошем фреймворке для установки конфигураций, примером которого может быть react-native-config.
React i18 next
+широко используется и имеет крупное сообщество;
+содержит разнообразные функции, такие как множественное число и контекст (например, мужской/женский род);
-являясь внешним пакетом, увеличивает размер приложения по сравнению с Context API.
Аналитика — важный способ отслеживать и контролировать поведение покупателей. На мой взгляд, для большинства основных ситуаций подойдет Firebase google analytics. Если вам нужна поддержка или помощь в решении таких вопросов, как анализ рекламы и ее охват или анализ маркетинговой коммуникации, то можно использовать Clever tap, Appsflyer или mix panel. Для работы с ними нужна платная лицензия.
Навигация React
+имеет огромное сообщество;
+в большинстве случаев используется для маршрутизации на основе имен, передачи данных из маршрутов, навигации по вкладкам, аутентификации потоков, глубоких ссылок и аналитических триггеров и т.д.;
+позволяет использовать предустановленные react-хуки навигации.
В процессе разработки приложений в React определенную сложность представляет написание форм, с чем я сам не раз сталкивался по ходу работы. Вот почему нам нужен более простой и удобный способ создания форм. Предлагаю рассмотреть следующие варианты:
Redux
+является функционально разносторонним шаблоном, проверенным на стадии продакшна;
+очень популярна в среде разработчиков;
+ предоставляет возможность двигаться по ходу разработки и отладки приложения в обратном направлении (Time Travel Debugging);
- уступает в производительности другим библиотекам управления состояниями, таким как Mobx.
+обладает повышенной производительностью;
- уступает Redux в масштабируемости;
- не предназначена для крупных и сложных приложений.
Expo CLI
+позволяет быстро приступить к написанию первого экрана;
+обеспечивает быструю дистрибуцию, а также установку приложения;
+отлично подходит для демо и PoC (проверки практической реализуемости) приложений;
- увеличивает размер приложения на 20–25 MB;
- не рекомендован для долгосрочных проектов;
- требует перенастройки конфигурации Expo для написания нативного кода.
React Native CLI
+легко добавляет нативный код Android and iOS;
- предназначен только для широко масштабируемых приложений;
- есть сложности в распространении и установке приложения;
- требует Mac для iOS разработок.
Как JavaScript разработчик, я постепенно начинаю склоняться к строгой типизации при написании кода. Проверка статических типов помогает выявлять ошибки на этапе разработки и повышает читаемость кода. Для проверки типов можно использовать TypeScript или Flow, у каждого из которых есть свои особенности.
Bit.dev
+постоянно публикует компоненты из любой кодовой базы;
+легко устанавливает компоненты в любой репозиторий;
+документирует и структурирует все компоненты в одном месте;
+отлично поддерживает React Native.
Модульное тестирование — важное условие для стабильной работы приложения. В качестве инструментов его проведения рассмотрим Jest и Enzyme.
App Center
+предоставляет бесплатное распространение и идет совместно с Crashlytics и Analytics;
- требует терпения для настройки и публикации приложения.
Formik
+имеет огромное сообщество;
- уступает в производительности react-hook-form.
Автоматизированные конвейеры сборки
Для подписания и создания файлов apk и ipa можно использовать Fastlane. Публикация приложений может осуществляться на одной из платформ, упомянутых в предыдущем разделе.
+ контролируется и снижает затраты;
- требует много времени на настройку;
- требует особых навыков и знаний для настройки от начала до конца (end to end);
- для создания файлов ipa требует запустить линию сборки на Circle ci или Travis ci. В качестве альтернативы для этого вы можете сделать хостом ваш собственный Mac mini.
Читайте также: