Help us understand the problem. What is going on with this article?

react-native-camera を使ってカメラアプリ(バーコード読み込み)を作成

More than 1 year has passed since last update.

バージョンなど問題があり、少しハマったので現バージョンの情報をベースに構築した内容をメモ

実行環境

Mac: MacBook Air 13'' Early 2015
macOS 10.13.1 (High Sierra)

Xcode 9.2
node.js: v6.11.5

react-native-cli: 2.0.1
react-native-camera: v1beta

react-native インストール

npm コマンドで react-native-cli をインストール。

npm install -g react-native-cli

プロジェクトの作成

react-native コマンドを使って初期プロジェクトを作成。

react-native init cameraapp

出来上がったプロジェクトのパッケージを確認してみる。

cd cameraapp
cat package.json

実行結果

react:16.0.0
react-native: 0.51.0
がインストールされた。

{
  "name": "cameraapp",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "start": "node node_modules/react-native/local-cli/cli.js start",
    "test": "jest"
  },
  "dependencies": {
    "react": "16.0.0",
    "react-native": "0.51.0"
  },
  "devDependencies": {
    "babel-jest": "21.2.0",
    "babel-preset-react-native": "4.0.0",
    "jest": "21.2.1",
    "react-test-renderer": "16.0.0"
  },
  "jest": {
    "preset": "react-native"
  }
}

react-native-camera インストール

続いて react-native-camera をインストール。

react-native: 0.51 では react-native-camera v0.4, v0.6 が動かなかったため、
ホームページより v1 のページの readme[https://github.com/lwansbrough/react-native-camera/tree/v1] を見て実行。

npm install rnpm --global
npm install react-native-camera@https://github.com/lwansbrough/react-native-camera.git --save
rnpm link react-native-camera

rnpm@1.9.0
react-native-camera@0.12.0
がインストールされた。

カメラコードの追加

ホームページにある Usage を貼り付けても動く動かないので、少しアレンジしてバーコード読み込み処理とメッセージダイアログ(Modal)を貼り付け。
Modal は FaceBook の API ドキュメントのサンプルを参考に実装。

vi App.js 

コード内容

/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 * @flow
 */

import React, { Component } from 'react';
import {
  Platform,
  Dimensions,
  StyleSheet,
  Text,
  TouchableOpacity,
  TouchableHighlight,
  Modal,
  View
} from 'react-native';

import Camera from 'react-native-camera';


const instructions = Platform.select({
  ios: 'バーコードを読み取ります。',
  android: 'Double tap R on your keyboard to reload,\n' + 'Shake or press menu button for dev menu',
});

export default class App extends Component<{}> {
  state = {
    visibleModal: 0,
    barcode: { type:null, data:null, bounds:null },
  }

  render() {
    return (
      <View style={styles.container}>
        <Text style={styles.welcome}>
          Camera app
        </Text>
        <Text style={styles.instructions}>
          Read the Barcode
        </Text>
        <Camera
          ref={(cam) => {
            this.camera = cam;
          }}
          style={styles.preview}
          onBarCodeRead={this.onBarcodeRead.bind(this)}
          aspect={Camera.constants.Aspect.fill}>
          <Text style={styles.capture} onPress={this.takePicture.bind(this)}>[CAPTURE]</Text>
        </Camera>
        <Modal visible={this.state.visibleModal === 1}>
          {this.renderModalContent()}
        </Modal>
      </View>
    );
  }

  takePicture() {
    this.camera.capture()
      .then((data) => console.log(data))
      .catch(err => console.error(err));
  }
  onBarcodeRead(data) {
    console.log(data);
    this.setState({ visibleModal: 1, barcode: data })
  }

  renderModalContent = () => (
    <View style={styles.modalContent}>
      <Text>type:{this.state.barcode.type}</Text>
      <Text>data:{this.state.barcode.data}</Text>
      {this.renderButton('Close', () => this.setState({ visibleModal: null }))}
    </View>
  )
  renderButton = (text, onPress) => (
    <TouchableOpacity onPress={onPress}>
      <View style={styles.button}>
        <Text>{text}</Text>
      </View>
    </TouchableOpacity>
  )
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#F5FCFF',
  },
  welcome: {
    fontSize: 20,
    textAlign: 'center',
    margin: 10,
  },
  instructions: {
    textAlign: 'center',
    color: '#333333',
    marginBottom: 5,
  },
  preview: {
    flex: 1,
    justifyContent: 'flex-end',
    alignItems: 'center',
    height: Dimensions.get('window').height,
    width: Dimensions.get('window').width
  },
  capture: {
    flex: 0,
    backgroundColor: '#fff',
    borderRadius: 5,
    color: '#000',
    padding: 10,
    margin: 40
  },
  button: {
    backgroundColor: 'lightblue',
    padding: 12,
    margin: 16,
    justifyContent: 'center',
    alignItems: 'center',
    borderRadius: 4,
    borderColor: 'rgba(0, 0, 0, 0.1)',
  },
  modalContent: {
    backgroundColor: 'white',
    padding: 22,
    justifyContent: 'center',
    alignItems: 'center',
    borderRadius: 4,
    borderColor: 'rgba(0, 0, 0, 0.1)',
  },


});

アプリのコンパイル・実行

react-native run-ios コマンドでコンパイル&実行

react-native run-ios

しばらくするとシミュレータが起動する。

xcode 上の調整

今回の環境では、そのままではシミュレータが起動してアプリ実行後ブラックアウトのまましばらくすると落ちてしまうので、xcode 上で微調整を実施。
ホームページ上の Manual install 手順を実行。

修正作業は以下3点
- libRTCamera.a の参照設定
- Signing Certificate の設定
- Info.plist への追記

libRTCamera.a の参照設定

xcode を起動して、作成したプロジェクトを読み込む。

ファイルチューザーで cameraapp/ios/cameraapp.xcodeproj を選択

ファイルリストから Libraries を選択

Add File to "cameraapp" を選択

cameraapp/node_modeules/

スクリーンショット 2017-12-21 3.15.21.png

Signing Certificate の設定

Apple Developer Program に参加していない場合、プロジェクトの General / Signing タブにて証明書の設定を手動で行う必要がある。

Bundle Identifier の設定変更

スクリーンショット 2017-12-21 3.16.47.png

General タブの Identity / Bundle Identifier を適切な名前に変更する。

Team のセレクトボックスにて、Add an Account を選択して、AppleID を入力する。

Bundle Identifier の設定変更

Info.plist への追記

以下の設定を Info.plist へ追加する。

<key>NSCameraUsageDescription</key>
<string>Your message to user when the camera is accessed for the first time</string>

<!-- Include this only if you are planning to use the camera roll -->
<key>NSPhotoLibraryUsageDescription</key>
<string>Your message to user when the photo library is accessed for the first time</string>

<!-- Include this only if you are planning to use the microphone for video recording -->
<key>NSMicrophoneUsageDescription</key>
<string>Your message to user when the microphone is accessed for the first time</string>

<!-- Include this only if you are planning to use the camera roll -->
<key>NSPhotoLibraryAddUsageDescription</key>
<string>Your message to user when the photo library is accessed for the first time</string>

スクリーンショット 2017-12-24 12.08.09.png

直接編集せず、xcode 上から Info.plist をダブルクリックして開き、適当なパラメータの+ボタンでキー名を入れて登録した。

react-native run-ios コマンドにて実行。

スクリーンショット 2017-12-24 12.06.25.png

エミュレータではカメラキャプチャ部分は黒く表示される。

実機での確認

iPhone をUSB で接続して、xcode を開く。

XCode から Prodcut => Desitination にて自分の iPhone を選択

Product => Run または ⌘+R で実行。

デベロッパープログラムに参加しないで開発を行っているので、iphone 上でデベロッパーAPPの認証を行う必要がある。
iphoneで 設定 => 一般 => プロファイルとデバイス管理を開くと、先ほど指定した自分の Appleアカウントのデベロッパー名が表示されるので、タップして信頼をする。

スクリーンショット 2017-12-24 12.29.38.png

バーコードが認識された場合、ポップアップにてコード種別とコードが表示される。

スクリーンショット 2017-12-24 12.24.46.png

参考

https://facebook.github.io/react-native/docs/getting-started.html

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away