A React Native module for uploading files and camera roll assets. Supports progress notification.
You can use file upload with fetch
and if you want progress bar, you can use xhr. Read my post How to upload photo/file in react-native. Even after read my post, but you are not enough, read the following.
npm install react-native-uploader --save
rnpm link react-native-uploader
If you don't want use rnpm, do this
npm install react-native-uploader --save
- In XCode, in the project navigator, right click
Libraries
➜Add Files to [your project's name]
- Go to
node_modules
➜react-native-uploader
➜RNUploader
and addRNUploader.xcodeproj
- In XCode, in the project navigator, select your project. Add
libRNUploader.a
to your project'sBuild Phases
➜Link Binary With Libraries
- Run your project (
Cmd+R
)
- Add to your settings.gradle:
include ':RNFileTransfer', ':app'
project(':RNFileTransfer').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-file-transfer-android/android')
- Add to your android/build.gradle:
dependencies {
...
compile project(':RNFileTransfer')
}
- Add to MainActivity.java
import com.burlap.filetransfer.FileTransferPackage;
...
mReactInstanceManager = ReactInstanceManager.builder()
.setApplication(getApplication())
.setBundleAssetName("index.android.bundle")
.setJSMainModuleName("index.android")
.addPackage(new MainReactPackage())
.addPackage(new FileTransferPackage())
See ./examples/UploadFromCameraRoll
var RNUploader = require('react-native-uploader');
var {
StyleSheet,
Component,
View,
DeviceEventEmitter,
} = React;
componentDidMount(){
// upload progress
DeviceEventEmitter.addListener('RNUploaderProgress', (data)=>{
let bytesWritten = data.totalBytesWritten;
let bytesTotal = data.totalBytesExpectedToWrite;
let progress = data.progress;
console.log( "upload progress: " + progress + "%");
});
}
doUpload(){
let files = [
{
name: 'file[]',
filename: 'image1.png',
filepath: 'assets-library://....', // image from camera roll/assets library
filetype: 'image/png',
},
{
name: 'file[]',
filename: 'image2.gif',
filepath: "data:image/gif;base64,R0lGODlhEAAQAMQAAORHHOVSKudfOulrSOp3WOyDZu6QdvCchPGolfO0o/XBs/fNwfjZ0frl3/zy7////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAkAABAALAAAAAAQABAAAAVVICSOZGlCQAosJ6mu7fiyZeKqNKToQGDsM8hBADgUXoGAiqhSvp5QAnQKGIgUhwFUYLCVDFCrKUE1lBavAViFIDlTImbKC5Gm2hB0SlBCBMQiB0UjIQA7", // base64 only support ios
filetype: 'image/gif',
},
];
let opts = {
url: 'http://my.server/api/upload',
files: files,
method: 'POST', // optional: POST or PUT, only support ios, android always have POST
headers: { 'Accept': 'application/json' }, // optional, only support ios, android always have { 'Accept': 'application/json' }
params: { 'user_id': 1 }, // optional, Android support this only string. If you want this in Android use params: { 'user_id': '1' }
};
RNUploader.upload( opts, (err, response) => {
if( err ){
console.log(err);
return;
}
let status = response.status;
let responseString = response.data;
let json = JSON.parse( responseString );
console.log('upload complete with status ' + status);
// android's response is response.body.string.
});
}
options
is an object with values:
type | required | description | example | |
---|---|---|---|---|
url |
string | required | URL to upload to | http://my.server/api/upload |
method(only iOS) |
string | optional | HTTP method, values: [PUT,POST], default: POST | POST |
headers(only iOS) |
object | optional | HTTP headers | { 'Accept': 'application/json' } |
params(iOS) |
object | optional | Query parameters | { 'user_id': 1 } |
params(Android) |
object | optional | Query parameters | { 'user_id': '1' } only support string value. You can't use int, boolean, etc.. |
files |
array | required | Array of file objects to upload. See below. | [{ name: 'file', filename: 'image1.png', filepath: 'assets-library://...', filetype: 'image/png' } ] |
callback
is a method with two parameters:
type | description | example | |
---|---|---|---|
error | string | String detailing the error | A server with the specified hostname could not be found. |
response(iOS) | object{status:Number, data:String} | Object returned with a status code and data. | { status: 200, data: '{ success: true }' } |
response(Android) | String | String returned with responseBody. | success: true |
files
is an array of objects with values:
type | required | description | example | |
---|---|---|---|---|
name | string | optional | Form parameter key for the specified file. If missing, will use filename . |
file[] |
filename | string | required | filename | image1.png |
filepath | string | required | File URI Supports assets-library: , data: and file: URIs and file paths. |
assets-library://...(iOS) content://...(Android) data:image/gif;base64,R0lGODlhEAAQAMQAAORHHOV...(only iOS) file:/tmp/image1.png /tmp/image1.png |
filetype | string | optional | MIME type of file. If missing, will infer based on the extension in filepath . |
image/png |
To monitor upload progress simply subscribe to the RNUploaderProgress
event using DeviceEventEmitter.
DeviceEventEmitter.addListener('RNUploaderProgress', (data)=>{
let bytesWritten = data.totalBytesWritten;
let bytesTotal = data.totalBytesExpectedToWrite;
let progress = data.progress;
console.log( "upload progress: " + progress + "%");
});
To cancel an upload in progress:
RNUploader.cancel()
Inspired by similiar projects:
- https://github.com/booxood/react-native-file-upload
- https://github.com/kamilkp/react-native-file-transfer
...with noteable enhancements:
- uploads are performed asynchronously on the native side
- progress reporting
- packaged as a static library
- support for multiple files at a time
- support for files from the assets library, base64
data:
orfile:
paths - no external dependencies (ie: AFNetworking)
- support Android
MIT