iOSでQRコードのバイナリデータを取得する
以前書いた Android で QR コードのバイナリデータを取得するサンプルの、iOS 版です。
以前書いた記事はこちら
iOSの方もQRコードのバイナリデータを読み込む方法がなかなか見つからなかったので、サンプルコードを提示しておきます。
QRコードのバイナリデータを読み込むアプリ「QRefine」は iOS 版もあるので、アプリが必要であればこちらも是非お使いください。
今回のサンプルコードも全文は GitHub にあげてます。あわせて参照ください。
環境
- macOS High Sierra 10.13.3
- Xcode 9.2
- ZXingObjC 3.2.2
- Swift 4
準備
ZXingObjC のインストール
iOS の方も QR コードの読み込みには ZXing を使います。
ZXing は Googleが開発している、様々な1次元/2次元バーコードの読み書きができるオープンソースのライブラリで、Objective-C にもポーティングされてるので、そのライブラリを使います。
ZXing の Objecitve-C のポーティングは ZXingObjC というライブラリですので、これを使います。
Carthage、CocoaPods で提供されていますが、ここでは CocoaPods を使うことにします。
Podfile にpod 'ZXingObjC', '~> 3.2.2'
を追加してpod install
を実行してインストールします。
カメラを使うことを info.plist で宣言
作成した xcworkspace を開いてコードを書いていきますが、その前に今回のアプリではカメラを使うため、info.plist でカメラを使うことを宣言しておきます。
info.plist で Privacy - Camera Usage Description
という項目を追加し、適当にメッセージを設定しておきます。(このメッセージはユーザにカメラの使用許可を問い合わせる時に表示されます)
コード
プレビュー用の UIView を配置
まずは、カメラでキャプチャした画面を表示するための View を配置します。Storyboard で View を配置し、レイアウトは適当に画面いっぱいに拡げておきます。
UIView を適当な名前でコードの方に紐付けます。ここでは preview という名前で紐付けました。
ZXing 制御コードを追加
QR コード読み取りコードを追加する。メインの処理を下記に書き出します。
まずはキャプチャ結果を取得するための ZXCaptureDelegate という Protocol の実装を行います。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
extension ViewController : ZXCaptureDelegate { func captureResult(_ capture: ZXCapture!, result: ZXResult!) { guard capturing else { return } if (result.barcodeFormat != kBarcodeFormatQRCode){ return; } capturing = false zxcapture?.stop() if let text = result.text { print("Result text: \(text)") } if let bytes = result.resultMetadata.object(forKey: kResultMetadataTypeByteSegments.rawValue) as? NSArray { let byteArray = bytes[0] as! ZXByteArray let data = Data.init(bytes: UnsafeRawPointer(byteArray.array), count: Int(byteArray.length)) // print result var resultString = "" data.forEach { (byte) in resultString.append(String(format:"0x%02X,", byte)) } print("Result binary: \(resultString)") } } } |
そして、ZXing のクラス ZXCapture のインスタンスを作成し、
- ZXCapture がカメラでキャプチャした画面を preview で表示できるように addSubLayer でつなぐ
- delegate を指定
- ZXCapture#start() を呼び出してキャプチャ開始
を行います。そのあたりのコードを抜き出したのが下記
1 2 3 4 5 6 7 8 9 10 |
let zxcapture = ZXCapture() self.zxcapture = zxcapture zxcapture.delegate = self zxcapture.camera = zxcapture.back() zxcapture.layer.frame = preview.bounds preview.layer.addSublayer(zxcapture.layer) zxcapture.start() |
これでキャプチャ開始され、QRコードを読み込んだタイミングで captureResult が呼び出され、認識結果が ZXResult という型で渡されます。
よく利用されるテキストデータは ZXResult#text というプロパティに格納されています。
バイナリデータは、ZXResult#resultMetadata (Dictionary型) の kResultMetadataTypeByteSegments.rawValue というキーの値として入っています。
バイト配列の配列として格納されているので、そこから値を取り出してきます。実際のコードは上記のとおり。
動作確認
一応、動作確認したので結果を載せておきます。Android 版の記事でも使った QR コードを読み込んでみます。
URL などのテキストデータ
1 2 3 4 5 |
2018-02-10 16:18:41.141692+0900 QrCodeBinarySample[315:12149] [MC] System group container for systemgroup.com.apple.configurationprofiles path is /private/var/containers/Shared/SystemGroup/systemgroup.com.apple.configurationprofiles 2018-02-10 16:18:41.142073+0900 QrCodeBinarySample[315:12149] [MC] Reading from public effective user settings. Result text: http://ryuta46.com/qrefine Result binary: 0x68,0x74,0x74,0x70,0x3A,0x2F,0x2F,0x72,0x79,0x75,0x74,0x61,0x34,0x36,0x2E,0x63,0x6F,0x6D,0x2F,0x71,0x72,0x65,0x66,0x69,0x6E,0x65, |
テキストデータとして URL、バイナリの方にはその UTF-8 のエンコードバイナリが格納されています。
バイナリデータ
1 2 3 4 5 |
2018-02-10 16:20:29.910598+0900 QrCodeBinarySample[317:12941] [MC] System group container for systemgroup.com.apple.configurationprofiles path is /private/var/containers/Shared/SystemGroup/systemgroup.com.apple.configurationprofiles 2018-02-10 16:20:29.911808+0900 QrCodeBinarySample[317:12941] [MC] Reading from public effective user settings. Result text: qbÌ“h¯"~ ...(省略)... Result binary: 0x0C,0x71,0x62,0xED,0xD2,0x68,0xF8, ...(省略)... |
相変わらずバイナリデータの方は中身はわかりませんが、Android 版と同じようにデータが読めているようです。
さいごに
Android も iOS バイナリデータを読み込むサンプルがなかなか無かったので、ちょっと実装に苦労しました。
ZXing は QR コードの書き出しもサポートしているので、これらも使いこなせれば QR コードを使うアプリを問題なく作っていけるかと思います。
最後まで読んでいただきありがとうございます。 このブログを「いいな」と感じていただけましたら、Twiter にてフォローいただけるとうれしいです。ブログ更新情報などもお届けします。
Follow @ryuta461
この記事をシェアする