Our website is made possible by displaying online advertisements to our visitors. Please consider supporting us by disabling your ad blocker.

Use The iOS Camera In Your React Native Mobile App

TwitterFacebookRedditLinkedInHacker News

In many mobile applications it is essential to be able to use the device camera. Maybe you’re creating the next Instagram or other photo sharing application.

Previously I wrote how to use the device camera in Ionic Framework, but how might we do the same with React Native?

Lucky for us, with React Native, there is an external component that lets us use the camera. Using react-native-camera by Loch Wansbrough, we have access to both the front and back device camera.

A few things to note about this particular tutorial before you get too invested. At the time of writing this, React Native works pretty much only for iOS. This means you’ll need to be using a Mac to develop with. As of right now the iOS simulators available in Xcode 6.4 do not support use of the camera. This means you’ll need to test on a native device.

With all this said, if you wish to continue, open your Terminal and execute the following command:

react-native init ReactProject

As mentioned earlier, we’re going to be using an external component. Download it to your project by first setting the project as your current working directory in your Terminal and running the following command:

npm install react-native-camera --save

The plugin has now been downloaded. At the time of writing this tutorial, I was using commit b1daed1 from the GitHub repository. The component may be downloaded, but you still need to include it in your Xcode project. This can be done with the following steps:

  1. In Xcode, right click on Libraries found in the project tree and choose Add Files to “ReactProject”…. Choose to add node_modules/react-native-camera/RCTCamera.xcodeproj when prompted.
  2. On the Build Phases tab in Xcode, choose to Link Binary With Libraries and select libRCTCamra.a when prompted.

The component is now ready to be used. More information on adding components can be found in the official React Native documentation.

It should be noted that some of the code you’ll see here was taken directly from the react-native-camera component’s documentation.

Open your project’s index.ios.js file and add the following line:

var Camera = require("react-native-camera");

The above line will load the class so we can make calls to the component via JavaScript. When our application initializes we want to make sure the camera is shooting from the back. This can be done by adding the following to the getInitialState function:

getInitialState: function() {
    return {
        cameraType: Camera.constants.Type.back
    }
}

Inside the render function we can add the Camera tag. Any child tags that exist in this tag will be overlays to the camera. For example:

<Camera
    ref="cam"
    style={styles.container}
    type={this.state.cameraType}>
    <View style={styles.buttonBar}>
        <TouchableHighlight style={styles.button} onPress={this._switchCamera}>
            <Text style={styles.buttonText}>Flip</Text>
        </TouchableHighlight>
        <TouchableHighlight style={styles.button} onPress={this._takePicture}>
            <Text style={styles.buttonText}>Take</Text>
        </TouchableHighlight>
    </View>
</Camera>

In the above snippet we use the camera with a two button overlay. The overlay buttons will allow for changing the camera between front and back as well as taking the photo. The two TouchableHighlight tags call the _switchCamera and _takePicture functions. They can be see below:

_switchCamera: function() {
    var state = this.state;
    state.cameraType = state.cameraType === Camera.constants.Type.back ? Camera.constants.Type.front : Camera.constants.Type.back;
    this.setState(state);
}

The above code just uses a ternary operator to switch the camera type and store it as a state.

_takePicture: function() {
    this.refs.cam.capture(function(err, data) {
        console.log(err, data);
    });
}

When it comes to taking the picture we make use of the reference we set in the Camera tag.

The full index.ios.js file I was using can be seen below:

"use strict";

var React = require("react-native");
var Camera = require("react-native-camera");

var {
    AppRegistry,
    StyleSheet,
    Text,
    View,
    TextInput,
    TouchableHighlight,
} = React;

var ReactProject = React.createClass({

    getInitialState: function() {
        return {
            cameraType: Camera.constants.Type.back
        }
    },

    render: function() {
        return (
            <Camera
                ref="cam"
                style={styles.container}
                type={this.state.cameraType}>
                <View style={styles.buttonBar}>
                    <TouchableHighlight style={styles.button} onPress={this._switchCamera}>
                        <Text style={styles.buttonText}>Flip</Text>
                    </TouchableHighlight>
                    <TouchableHighlight style={styles.button} onPress={this._takePicture}>
                        <Text style={styles.buttonText}>Take</Text>
                    </TouchableHighlight>
                </View>
            </Camera>
        );
    },

    _switchCamera: function() {
        var state = this.state;
        state.cameraType = state.cameraType === Camera.constants.Type.back ? Camera.constants.Type.front : Camera.constants.Type.back;
        this.setState(state);
    },

    _takePicture: function() {
        this.refs.cam.capture(function(err, data) {
            console.log(err, data);
        });
    }

});

var styles = StyleSheet.create({
    container: {
        flex: 1,
        justifyContent: "center",
        alignItems: "center",
        backgroundColor: "transparent",
    },
    buttonBar: {
        flexDirection: "row",
        position: "absolute",
        bottom: 25,
        right: 0,
        left: 0,
        justifyContent: "center"
    },
    button: {
        padding: 10,
        color: "#FFFFFF",
        borderWidth: 1,
        borderColor: "#FFFFFF",
        margin: 5
    },
    buttonText: {
        color: "#FFFFFF"
    }
});

AppRegistry.registerComponent('ReactProject', () => ReactProject);

The application will look like this:

React Native Camera Simulator

Of course I took the screenshot from the simulator which is why it is just black. If you wanted to get fancy you could switch out the text buttons for glyph icon buttons.

Conclusion

With the help of components, react-native-camera in particular, we can add device camera support to our React Native mobile application. This gives us the ability to take photos and switch between the front and rear cameras of the device.

Nic Raboy

Nic Raboy

Nic Raboy is an advocate of modern web and mobile development technologies. He has experience in C#, JavaScript, Golang and a variety of frameworks such as Angular, NativeScript, and Unity. Nic writes about his development experiences related to making web and mobile development easier to understand.