Use The iOS Camera In Your React Native Mobile App

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:

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:

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:

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:

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:

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:

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

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:

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 is an advocate of modern web and mobile development technologies. He has experience in Java, JavaScript, Golang and a variety of frameworks such as Angular, NativeScript, and Apache Cordova. Nic writes about his development experiences related to making web and mobile development easier to understand.

  • vinodsobale

    Hello Nic,

    Is there any way we could use ‘Edit’ Images? Or use functions such as Cropping/resizing?

    • You would have to design any post-processing after using the plugin, inside the callback.

  • Noel Farris

    Hi Nic,

    My build is failing after adding RCTCamera.xcodeproj to my project. Can I remove the RCTCamera project from my project under the compile sources?

    • What errors are you getting? Is this Xcode 7 and iOS 9?

      • Noel Farris

        Xcode 6.4 and iOS 8. Getting an Apple mach-O linker error.

        • Can you paste the full error please?

  • Ashish

    HEY Nic,
    how to install ionic in windows laptop. i am install Nodejs, cordova, ionic, apache ant and git. and i have create https://uploads.disquscdn.com/images/e40f45cb8d67da7235438bdc63c869ff7efcf5c357b047cfcfa35ec6d84d6192.png this error is displayed in my cmd prompt.
    can you give me some link to i am learn easily ionic.

    • You’re asking an Ionic Framework question on a React Native article. Unrelated questions should be directed at my Twitter account.

  • Jason Ho

    Hey Nick,

    I’m really hoping you can give me a quick answer on this high level question. Is it possible to use this camera component for a time lapse style app? Ie, take a picture with/or without a preview, and not require the user to confirm the picture is okay?

    What type of issues might I run into?

    I’ve been learning Ionic (no previous knowledge of programming), and it seems like such functionality with Cordova isn’t possible :/ Ugh, I’ve spend a lot of time learning Angular for the sole purpose of using Ionic too :/

    • When using a hybrid technology like React Native, Apache Cordova, and NativeScript, you’re stuck with whatever exists in a plugin. Since most are fine with basic camera functionality, the plugins are usually alright. However, when something more complex is needed, this is where the problem resides.

      If you wish to have complex camera features in your app you’ll have to design your own plugin.

      Best,

      • Jason Ho

        Thanks Nic, apologies on typing your name wrong :/

  • Matthew Jordan

    Hi Nic,

    Thanks a lot for the post, it has been tremendously helpful. My question is on capture and display. Very similar to Snapchat where a user can take a picture and choose to send or delete and retake.

    On the “takePhoto” render I have this component for when the take photo button is pressed (not initial state of takenPhotoURI = null):

    this.setState({takenPhotoURI:data})
    }
    this.camera.capture()
    .then(updatestate).catch(function(error){
    console.log(error)
    })
    },

    However it does not seem to be updating the “takenPhotoURI” state so that this funtion will rerender:

    render: function() {
    if (this.state.takenPhotoURI){
    return this.renderEditPhotoUI();
    }
    return this.renderTakePhotoUI();
    },

    My renderEditPhotoUI component is this:

    renderEditPhotoUI: function() {
    return (

    },

    I have spent many hours figuring this out and can’t get it. I’m sorry if this is an elementary question. Thanks so much for your time.

    Matt

    • It’s been a while since I touched React Native, but can you tell me if you can get anything printed in the updatestate function?

      Add some logging in various places to see where the disconnect is.

      Also, just to rule it out, can you make sure this.state.takenphotouri has the same capitalization in all parts of your code.

      Best,

      • Matthew Jordan

        Hi Nic,

        I figured it out. Here is the code for the take picture component:

        On the rerender I returned this value

        renderEditPhotoUI: function() {
        return (

        },

        Thanks!

        • Awesome! I’m glad you got it working and I appreciate you reporting back 🙂

  • Hi,

    Is there any way of changing the directory where the images are stored? Also can we change the name of the image and give it a custom name?

  • Michael Chen

    Help! I dunno what is wrong but the flip and take buttons aren’t working. See my SO post:
    http://stackoverflow.com/questions/42322681/undefined-is-not-an-object-evaluating-state-cameratype

  • happyhouserules

    Thank you for this. I still can’t figure it out, but I linked to it in this post. http://www.followmystartup.website/honestly-who-can-do-this-api-this-python-that-but-what-i-can-do-might-help-you/