最近剛好在學習 React Native 想搞個掃描條形碼,二維碼的小應用,因為涉及硬體介面,而且自己本身並沒有原生開發背景,踩了幾個坑,記錄一下。
掃描二維碼
首先當然是 google 一下看看是否有現成的 React Native 庫支援二維碼,感謝最大的同性交友網站 GitHub,還真有兩個:react-native-camera 和 react-native-barcodescanner 。
不過,各自都有一點問題,react-native-camera 主要是用來呼叫攝像頭的,Android iOS 都可以用,但是識別條形碼的功能只有 iOS 有,而react-native-barcodescanner 直接只支援 Android。於是為了方便,有人把這兩個庫搞到一起,弄了個 react-native-barcode-scanner-universal 。裡面程式碼也比較簡單,就是利用 React Native 根據不同平臺會去讀 xxx.ios.js 或者 xxx.android.js 的原理,寫一個公共的 index.js 然後分別呼叫不同平臺的庫。
// index.js
module.exports = require("./BarcodeScanner");
// BarcodeScanner.android.js
import BarcodeScanner from "react-native-barcodescanner";
module.exports = BarcodeScanner;
// BarcodeScanner.ios.js
import Camera from "react-native-camera";
module.exports = Camera;複製程式碼
既然都打包好了,那我們就開始用 react-native-barcode-scanner-universal 這個庫吧。
既然是要呼叫硬體 API,那肯定有原生程式碼在裡面,需要把原生模組給連結到相應的原生專案中。
這裡既可以手動,又可以使用一個叫 rnpm
的工具。
rnpm
的全名是『React Native Package Manager』,高大上有木有,主要就是用來把一些 React Native 庫中用到的原生模組給新增到相應的原生專案中。
安裝比較簡單:
npm install -g rnpm複製程式碼
連結:
rnpm link react-native-camera
rnpm link react-native-barcodescanner複製程式碼
這個最新版是 1.9.0,不過我連結的時候總是提示各種奇怪的問題,於是查了下,改成 1.5.5 版本就好了,如果你遇到新版報錯有問題,可以嘗試退到 1.5.5 版本試試。
還可以用手動連結的方法,參考:
連結好之後,閒話不多說,直接寫個 View 開搞,這裡以 iOS 為主。
import BarcodeScanner from 'react-native-barcode-scanner-universal'
import React, {Component} from 'react';
import {
StyleSheet,
View,
Text,
Platform
} from 'react-native';
export default class ScanView extends Component {
constructor(props) {
super(props);
this.state = {
code: "None"
};
this._show = this._show.bind(this);
}
render() {
let scanArea = null;
if (Platform.OS === 'ios') {
scanArea = (
<View style={styles.rectangleContainer}>
<View style={styles.rectangle} />
</View>
)
}
return (
<View>
<Text style={ [{color:"red"},{fontSize:16}] }>{this.state.code}</Text>
<BarcodeScanner
onBarCodeRead={ (code) => this._show(code)}
style={styles.camera}>
{scanArea}
</BarcodeScanner>
</View>
)
}
_show(val) {
this.setState({
code:val.data
})
}
}
var styles = StyleSheet.create({
camera: {
flex: 1
},
rectangleContainer: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
backgroundColor: 'transparent'
},
rectangle: {
height: 250,
width: 250,
borderWidth: 2,
borderColor: '#00FF00',
backgroundColor: 'transparent'
}
})複製程式碼
簡單解釋一下,就是一進來就開始掃,識別到東西就現實到上面的 <Text>
中去。
實際執行一下,由於要使用攝像頭,這裡電腦要連一個 iOS 裝置。我用 Xcode 開啟 React Native 工程,設定好使用真機除錯。
點下執行按鈕,結果報錯了:Code signing is required for product type 'xxxx' in SDK 'iOS 8.0'
寶寶,沒搞過 iOS,寶寶心裡苦。大意是說要什麼什麼簽名,一般這種設定應該都在專案的公共設定裡面吧,於是點了下專案檔案,還真有個 Signing
,於是新增了一堆東西進去。
再點執行,又報錯了: Code signing is required for product type 'Unit Test Bundle' in SDK 'iOS 8.0'
這單元測試包是啥子,於是 google 一番,原來這個地方是可以下拉的,沒文化真可怕:
和上面那個一樣,這裡也是設定一番就好。其中要確認 "Code Signing Identity" 這一項不能是 "Don't Code Sign"。
又一次按下執行鍵,這次顯示構建成功,在 iOS 裝置上信任了開發證照之後,開啟程式,因為我是一開啟程式就開始掃描的,於是 Crash 了。
這時候 Xcode 控制檯幽幽的飄出一個錯誤:
簡單來說:因為你想用敏感資料,又沒有事先告訴我,所以我讓你掛了,如果你想不掛,就去 Info.plist 裡面按我說的新增點東西,說說你為什麼要用這些資料。
多麼友好的提示啊,於是就按照提示加加加,找到專案的 Info.plist
檔案,右鍵選擇 Open As -> Source Code
, 新增它說的東西,裡面的文字就是每次新裝應用彈的框提示要什麼什麼許可權的:
這裡順便把訪問照片庫的許可權也給加了。關於 iOS 加許可權的可以參考 這篇文章
之後讓我再給個機會執行一下,同意一堆許可權之後,終於看到攝像頭畫面了,試試掃一掃,還真成功了。
總結
總結一下,這次跌跌撞撞的經歷
- 把庫連結好;
- 把程式的簽名弄好;
- 把該加的許可權加號,雖然這裡是用 iOS 做例子,可想而知,Android 一樣要在 Gradle 檔案裡面弄一波許可權;
- 瞭解原生開發很重要
React Native 的哲學是 『Learn once, write anywhere』,實際使用下來,感覺卻是『Learn once, and learn others』,也就是常說的『一專多長』。
既要學習 React Native 本身的內容,也要學習 Android,iOS 的知識,不說了,趕快去亞馬遜上買本 OC 的書壓壓驚。
碎碎念
最近總想記錄一些所思所想,寫寫科技與人文,寫寫生活狀態,寫寫讀書感悟,主要是扯淡和感悟,歡迎關注,交流。
微信公眾號:程式設計師的詩和遠方
公眾號ID : MonkeyCoder-Life