Using iOS Image Picker with React Native
14 Oct 2016
Playing with React Native the other weekend, I was building a simple messenger UI. One of the features was that messages could be text, but they could also be images or location.
Location is easy, but getting the camera roll picker was not as well documented.
Let's build a simple app that will prompt the user to pick an image, and then display that image.
Create a new app
If you don't have React Native installed, follow the official instructions.
Actually create a new app with:
react-native init CameraRollPicker
cd CameraRollPicker
The setup
The docs don't bring this up at all, but there are two things needed to get access to device's camera roll:
- declare photo library usage
- link the RCTCameraRoll library
Photo library usage declaration
In order to access user's private data on iOS, like location, camera roll, contacts, etc, the application has to get the user's permission.
For that, the application metadata has to list the reason why it needs a particular permission. Without this, no prompt will be shown, and the application will crash when trying to access the private data.
To use the camera roll, Privacy - Photo Library Usage Description
, or NSPhotoLibraryUsageDescription
, should be set.
To set it, first open the Xcode project:
open ios/CameraRollPicker.xcodeproj
Then, select CameraRollPicker in the left sidebar, and go to the Info tab.
You should see a screen like this:
Under Custom iOS Target Properties, hover over any item, say Bundle name and click the plus icon. In a new row, click the selector arrows and select Privacy - Photo Library Usage Description.
In the Value column, enter the text description of why the camera roll is needed.
For example, We need access to photos as it's the core app experience.
Whew! That wasn't so hard!
Link the RCTCameraRoll library
React Native provides the ImagePickerIOS API which we are going to use.
To actually use it, though, the RCTCameraRoll
native library is needed, and this is not documented.
It comes with React Native, but by default, it is not included in the project.
Let's link it.
First, locate the RCTCameraRoll.xcodeproj
:
open node_modules/react-native/Libraries/CameraRoll
Then, in Xcode, expand the CameraRollPicker and then Libraries on the sidebar.
After that, drag the RCTCameraRoll.xcodeproj
from Finder into the Libraries tree:
Should see:
Now, click on the CameraRollPicker in the left sidebar, go to the Build Phases, and expand Link Binary With Libraries.
Click the plus button in here, then pick libRCTCameraRoll.a at the top and Add it.
Wow, that feels like quite a bit of ceremony!
Luckily, we are done with the setup now. Close Xcode, we don't need it anymore. Let's go out and actually make the app!
The App
As mentioned, we will be using the ImagePickerIOS API.
Specifically, the openSelectDialog
function.
This is by far the easiest part — the function accepts a config ({}
would do), and two callbacks: one for success with the image URI, one for error.
index.ios.js
:
import React, { Component } from "react";
import { AppRegistry, Text, View, ImagePickerIOS, Image } from "react-native";
export default class CameraRollPicker extends Component {
constructor() {
super();
this.state = { image: null };
}
componentDidMount() {
this.pickImage();
}
pickImage() {
// openSelectDialog(config, successCallback, errorCallback);
ImagePickerIOS.openSelectDialog(
{},
(imageUri) => {
this.setState({ image: imageUri });
},
(error) => console.error(error)
);
}
render() {
return (
<View style={{ flex: 1 }}>
{this.state.image ? <Image style={{ flex: 1 }} source={{ uri: this.state.image }} /> : null}
</View>
);
}
}
AppRegistry.registerComponent("CameraRollPicker", () => CameraRollPicker);
Gorgeous!