hacomono TECH BLOG

フィットネスクラブやスクールなどの顧客管理・予約・決済を行う、業界特化型SaaS「hacomono」を提供する会社のテックブログです!

QRコードをかざすのは難しい

この記事は hacomono advent calendar 2024 の24日目の記事です

こんにちは。hacomono 新規事業開発室に所属している teru です。モバイルエンジニアとしてモバイルアプリの開発をメインで担当しています。
健康維持やリフレッシュを目的として10年間以上ジム通いを続けています。今年は週2〜3回ペースでジムに通ってきましたが最近寒さが厳しく週2回を維持するのが精一杯な状況のため、寒さに負けないよう気持ちを引き締めていこうと思っています。

はじめに

hacomono では お客様が店舗をご利用される際、店頭に設置された iPad にメンバーサイト上に表示されるQRコードをかざすことで店舗スタッフさんを介さずにチェックインできるソリューションを提供しています。
この iPad で常時起動させる iPad アプリ(以下「店頭アプリ」)について、よりよいユーザー体験を提供するために行ってきた改善の一部を紹介したいと思います。

タブレット端末にQRコードをかざすのは難しい

一般的な小売店のレジでよく見かけるQRコード専用リーダーの場合は、QRコードをかざす位置がわかりやすいため比較的スムーズにスキャンすることができると思います。
一方タブレット端末などのように汎用的なカメラでスキャンするケースでは、カメラに向け適切な距離でQRコードをかざす必要があり、慣れるまではQRコードをかざす位置や距離の調整に時間がかかる人が多いと思います。

初期バージョンでの対策

店頭アプリの初期バージョンでは、次の2点を実現することでスムーズなQRコードを目指しました。

  • カメラのプレビューを表示させる
  • カメラの位置を示す矢印を点滅表示させる

QRコードをスキャンしているときの画面表示(初期バージョン)


更なる改善

上記対策を実施した状態でもカメラの位置が伝わりづらくプレビューの上にQRコードをかざすケースもあるようで(私も初見ならそうすると思います)、チェックインが集中する時間帯に行列ができてしまうというフィードバックもいただいたため更なる改善を行いました。

改善内容

プレビューの表示を画面中央ではなくカメラの位置に寄せる改善を行いました。これによりカメラの位置が伝わりやすくなり、プレビューの上にかざしたとしてもスムーズにスキャンしやすくなったと思います。効果測定は実施していませんが体感的にも改善されていると思います。

改善後の画面表示


iPad のカメラ位置

店頭アプリは全ての画面向き(4方向)をサポートしているため、画面の向きに応じて矢印の表示位置やプレビューの表示位置を変化させる実装を行っています。

機種による差異

ここで注意が必要となるのが iPad 第10世代 以降(iPad mini は除きます)はフロントカメラの位置が変更となっている点です。従来の iPad はディスプレイが縦向きの状態でディスプレイの上部にフロントカメラが実装されていましたが、最近は同状態でディスプレイの右側にカメラの位置が変更となりました。

機種判別とフロントカメラ位置

現在フロントカメラの位置を取得するAPIが用意されていないため、機種情報を取得してカメラがディスプレイ右側にある機種の場合は矢印・プレビューの表示位置を変更する実装を行いました。
機種情報を取得するために DeviceKit を採用し次のような extension を作成しました。

import DeviceKit
...
extension Device {
    // フロントカメラの位置(機種によりフロントカメラの位置が異なるため)
    static var frontCameraPosition: FrontCameraPosition {
        switch Device.current {
        case .iPad10, .iPadAir11M2, .iPadPro11M4, .iPadAir13M2, .iPadPro13M4:
            return .right
        default:
            return .top
        }
    }
}


Flutter の場合

最近個人的もマルチプラットフォーム開発に力を入れていまして、特に Flutter を積極的に選択するようにしています。店頭アプリで行っているような機種判別を、Flutter ではどのように実装すればよいかを調べてみましたので軽く触れてみたいと思います。

device_info_plus によるモデル名取得

device_info_plus を利用することでプラットフォームごとのモデル情報が取得できるようになります。iOS でモデル名が取得できるようになったのは最近リリースされた 11.2.0 からのようなので最新バージョンを利用するようにしましょう。
サンプルコード

import 'dart:io';
import 'package:device_info_plus/device_info_plus.dart';
...
if (Platform.isIOS) {
  IosDeviceInfo iosInfo = await deviceInfo.iosInfo;
  print('Running on ${iosInfo.modelName}');
} else if (Platform.isAndroid) {
  AndroidDeviceInfo androidInfo = await deviceInfo.androidInfo;
  print('Running on ${androidInfo.model}');
} else {
  WebBrowserInfo webBrowserInfo = await deviceInfo.webBrowserInfo;
  print('Running on ${webBrowserInfo.userAgent}');
}

iPad 第10世代での出力結果

flutter: Running on iPad 10


まとめ

QRコードをかざしてスキャンするという単純なユーザー体験でも奥が深く、UIや技術で改善できると実感できた事例でした。また何気ないハードウェアの仕様変更も、自身の関わっているプロダクトに影響が及ぶことがあるので、モバイルエンジニアとしてはガジェットにも興味・関心を持ち続けることが重要であると感じました。

※ QRコード®は株式会社デンソーウェーブの登録商標です。


株式会社hacomonoでは一緒に働く仲間を募集しています。
エンジニア採用サイトや採用ウィッシュリストもぜひご覧ください!