iPhoneブラウザのバーコードスキャナが精度がわるくて専用アプリをつくった話①

# はじめに
WebアプリをBlazorでつくっていたところ，要望があってバーコードリード機能を開発しました．最初はブラウザのカメラ機能をつかって実装していましたが，iPhoneだと読み取り精度が悪く，使いにくい事がわかりました．そこで，専用のiOSアプリを開発することになったので，その記録を残したいと思います．

# Blazor WebAssemlbyでバーコードスキャナ
Blazorにバーコードスキャナ機能の実装します．
Javascriptのライブラリを使用することにします．

## 使用ライブラリ
[html5-qrcode](https://github.com/mebjas/html5-qrcode)
* 比較的新しいバーコードスキャナライブラリ
* クロスプラットフォーム
* 様々なバーコードに対応
* ライセンス: Apache-2.0 license
* 2025年5月現在 メンテナンスモード(開発当時は積極的に更新してくれていた:persevere:)

[quaggaJS](https://github.com/serratus/quaggaJS)
* 歴史あるライブラリ
* 一次元バーコード様々なものに対応しているが，QRコードが読めない
* ライセンス: MIT license
* 2017年を最後に更新が止まっている

※ iPhoneでの精度の悪さがライブラリ起因なのかを確かめるために2つ用意して検証してみましたが，ライブラリ間での違いはなかったです．どちらのライブラリでもiPhoneだと読み取り精度は悪かったです．
※ 以降は，すべて[html5-qrcode](https://github.com/mebjas/html5-qrcode)を使用しています．

## 実装
実装方法の詳細は割愛しますが，機会があれば記事を書きたいと思います．
[MS ドキュメント](https://learn.microsoft.com/ja-jp/aspnet/core/blazor/javascript-interoperability/?view=aspnetcore-9.0)を参考にしました．

実装内容は以下の通りです．
* JSライブラリ(.min.js)をwwwrootに置く
* index.htmlでライブラリを読み込むようにする
* ライブラリを使用するServiceクラスを作る
* ページを作成して，Serviceクラスを使用する
* バーコード読み取りに関して，それっぽい縞模様があると誤検知されることがあるので，3回同じ内容を読み取れて初めて読み取り成功とみなす制御をいれる
* 読み取った値を画面表示にする

## iPhone版
* iPhone 15 Pro
* iOS 18.4.1
* Safari
![iphoneBarcode.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4044744/6a682014-2213-45ed-bf0d-779c7787fdb7.gif)

## Android版
* AQUOS wish4
* Android 14
* Chrome 124.0.6367.179
![AndroidBarcode.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4044744/82ce5b61-7c3c-4adb-87b2-3a5337dda433.gif)

# 比較してみて
iPhone版のほうが若干ですが，読み取り精度が悪いように見えます．
iPhoneはProだとだいぶ精度が上がってしまって，上記の比較であまり違いがなくってしまいました．
（本稿執筆時，手元には15 proしかありませんでした:disappointed_relieved:）
（実は，この話を聞いたときはiPhone 15 Proを使っていたものですから，「若干遅い気もするけど，そんなに違いなくない・・・？」と思っていました）

スタンダートモデルのiPhoneもしく古いものの場合とバーコードのサイズを小さくした場合は，Androidとの読み取り精度差は，顕著なものなります．実際に読み取っているところを確認してわかったのですが，具体的にはピントが全然合わなかったり，カメラ内のバーコードを認識しなかったりして，一個読み取りするのにも一苦労するレベルでした．

本アプリのユーザーは小さめのバーコードが密集しているような表を読み取りたいのことだったので，そのような状況だとiPhoneではますます読み取りづらくなってしまいました．
イメージ図[^1]
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4044744/02b82144-ef37-4c4c-98b1-bd75e5b0f266.png)


会社のiPhoneユーザー何人かにやってもらった結果です．
※ SDAはShape Detection API（Safariの設定から有効化できます）[^2]．
（SDAを使うとバーコードの検出がしやすくなります．デフォルトはOFFです．）
| 機種               | iOS/Safari    | テストバーコード | 小さいかつバーコードが密集する表 (SDA無効) | 小さいかつバーコードが密集する表 (SDA有効) | 
| :----------------- | :------------ | :------------------- | :--------------------- | :--------------------- | 
| iPhone 15          | 17.6.1/604.1  | 〇 (紙)              | ✕ (紙)                 | 〇 (紙)                |                    |
| iPhone 15 Pro      | 17.6.1/604.1  | 〇 (紙)              | ✕ (紙) 稀に読み取れる     | 〇 (紙)                |                    |
| iPhone 13 Pro      | 17.6.1/604.1  | 〇 (紙)              | ✕ (紙) 稀に読み取れる     | 〇 (紙)                | 本日確認           |
| iPhone SE (第三世代) | 17.6.1/604.1  | 〇 (紙)              | ✕ (紙)                 | ✕ (紙)                 |                    |
| iPhone 11          | 17.6.1/604.1  | 〇 (紙)              | ✕ (紙)                 | ✕ (紙)                 |                    |

* サイズが小さくなると（1cm x 5cm以下など）と読み取りにくくなる
* バーコードの近くに空白領域があるほど読み取りやすい
* サイズが小さくてそもそもピントが合いにくい場合，一度カメラを隠すと強制的にフォーカスされる
* 読み取れている端末も暗い部屋や自身の影が映ると読み取れない場合がある
* iPhone12以前（SE含む）のスペックはバーコードのサイズが小さいとピントが合ってもコードにフォーカスしない

# どうにかしたい
ライブラリではフォーカスモードやズーム周りの設定を変更できるようになっていましたが，いくら設定を変えても読み取り精度向上には至りませんでした．

そんな中，下のStackoverflowの投稿が目に入りました．
https://stackoverflow.com/questions/78769178/is-there-an-html5-api-to-control-camera-focus-and-zoom-on-iphone

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4044744/fe556889-60e3-4afc-a51a-0d3ffb6663e7.png)

調べてみると，iOSのWebカメラではソースコードからカメラの設定を触れないとのことでした．
また，Webからカメラハードウェアへのアクセスは，セキュリティやプライバシーの観点から制限しているみたいです．
つまり，読み取り精度の向上は難しそうでした．

# ネイティブアプリを作ろう！
ブラウザ上のカメラでバーコード読み取りはこれ以上の改善が見込めなさそうでしたので，iOSネイティブアプリを作ることにしました．アプリとしては，バーコードを読み取って，その値をWebアプリに返すという単純なものです．
iOSアプリといえばSwiftですが，投稿者は.NETの方が馴染み深かったことからクロスプラットフォームフレームワークである.NET MAUIを採用しました．
MAUIアプリ開発については，また記事を書いて投稿していきます．

# To Be Continued...
次回は，WebアプリとiOSアプリ（MAUI）とのデータのやり取りについて投稿したいと思います．

[^1]: [キーエンス バーコード講座](https://www.keyence.co.jp/ss/products/autoid/codereader/principles_printer.jsp)
[^2]: [MDN BarcodeDetector](https://developer.mozilla.org/ja/docs/Web/API/Barcode_Detection_API)