react-native-document-picker
A React Native wrapper for Apple's UIDocumentMenuViewController
and for Android's Intent.ACTION_OPEN_DOCUMENT
/ Intent.ACTION_PICK
.
Installation
npm i --save react-native-document-picker
Automatically Link Native Modules
For 0.29.2+ projects, simply link native packages via the following command (note: rnpm has been merged into react-native)
react-native link
As for projects < 0.29 you need rnpm
to link native packages
rnpm link
Manually Link Native Modules
- Run
npm install react-native-document-picker --save
- Open your project in XCode, right click on
Libraries
and clickAdd Files to "Your Project Name"
(Screenshot) then (Screenshot). - Add
libRNDocumentPicker.a
toBuild Phases -> Link Binary With Libraries
(Screenshot).
CocoaPods
Add the following to your podfile:
pod 'react-native-document-picker', :path => '../node_modules/react-native-document-picker`
Android
// file: android/settings.gradle
...
include ':react-native-document-picker'
project(':react-native-document-picker').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-document-picker/android')
// file: android/app/build.gradle
...
dependencies {
...
compile project(':react-native-document-picker')
}
// file: MainApplication.java
...
import com.reactnativedocumentpicker.ReactNativeDocumentPicker;; // Import package
public class MainApplication extends Application implements ReactApplication {
/**
* A list of packages used by the app. If the app uses additional views
* or modules besides the default ones, add more packages here.
*/
@Override
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
new MainReactPackage(),
new ReactNativeDocumentPicker() // Add package
);
}
...
}
Example
import { DocumentPicker, DocumentPickerUtil } from 'react-native-document-picker';
// iPhone/Android
DocumentPicker.show({
filetype: [DocumentPickerUtil.images()],
},(error,res) => {
// Android
console.log(
res.uri,
res.type, // mime type
res.fileName,
res.fileSize
);
});
// iPad
const {pageX, pageY} = event.nativeEvent;
DocumentPicker.show({
top: pageY,
left: pageX,
filetype: ['public.image'],
}, (error, url) => {
alert(url);
});
Note
The full list of UTI is available here: (https://developer.apple.com/library/ios/documentation/Miscellaneous/Reference/UTIRef/Articles/System-DeclaredUniformTypeIdentifiers.html)]
Here is how it looks:
How to send it back ?
I recommend using https://github.com/johanneslumpe/react-native-fs
I had to modify Uploader.m so it would use NSFileCoordinator
with NSFileCoordinatorReadingForUploading
option.
I added a check for file length that would be thrown into RNFS catch block.
if ([fileData length] == 0) {
NSError *errorUp = [NSError errorWithDomain:@"com.whatever.yourapp" code:77 userInfo:[NSDictionary dictionaryWithObject:@"empty" forKey:NSLocalizedDescriptionKey]];
_params.errorCallback(errorUp);
return;
}
let url = "file://whatever/com.bla.bla/file.ext"; //The url you received from the DocumentPicker
// I STRONGLY RECOMMEND ADDING A SMALL SETTIMEOUT before uploading the url you just got.
const split = url.split('/');
const name = split.pop();
const inbox = split.pop();
const realPath = `${RNFS.TemporaryDirectoryPath}${inbox}/${name}`;
const uploadBegin = (response) => {
const jobId = response.jobId;
console.log('UPLOAD HAS BEGUN! JobId: ' + jobId);
};
const uploadProgress = (response) => {
const percentage = Math.floor((response.totalBytesSent/response.totalBytesExpectedToSend) * 100);
console.log('UPLOAD IS ' + percentage + '% DONE!');
};
RNFS.uploadFiles({
toUrl: uploadUrl,
files: [{
name,
filename:name,
filepath: realPath,
}],
method: 'POST',
headers: {
'Accept': 'application/json',
},
begin: uploadBegin,
beginCallback: uploadBegin, // Don't ask me, only way I made it work as of 1.5.1
progressCallback: uploadProgress,
progress: uploadProgress
})
.then((response) => {
console.log(response,"<<< Response");
if (response.statusCode == 200) { //You might not be getting a statusCode at all. Check
console.log('FILES UPLOADED!');
} else {
console.log('SERVER ERROR');
}
})
.catch((err) => {
if (err.description) {
switch (err.description) {
case "cancelled":
console.log("Upload cancelled");
break;
case "empty"
console.log("Empty file");
default:
//Unknown
}
} else {
//Weird
}
console.log(err);
});
File Type
All type of Files 'public.allFiles' or DocumentPickerUtil.allFiles()
Only PDF 'public.pdf' or DocumentPickerUtil.pdf()
Audio 'public.audio' or DocumentPickerUtil.audio()
Plain Text 'public.plainText' or DocumentPickerUtil.plainText()
Reminder
You need to enable iCloud Documents to access iCloud
Halp wanted: Improvements
- Fix Xcode warning about constraints
- support options for the UIDocumentMenuViewController
- Handle Upload by itself ?