WebServiceを使った連続読み取り機能の開発

RayBarcodeではWebServiceを使って連続読み取り機能を開発できます。この方法では、カメラ画面を維持したまま連続して複数のバーコードを読み取る操作が可能になります。

※「連続読み取り機能」の操作の流れについては、「バーコード読み取りの仕組み - 連続読み取り機能の操作の場合」を参照してください。

  • 連続読み取りのカメラ画面では、読み取った個数と結果をオーバーレイ表示されます。
  • 連続読み取りの途中でカメラ画面の右上に表示される「閉じる」をタップすると、読み取り動作を停止し、読み取り開始画面へ戻ります。
  • 連続読み取りの間隔は、ユーザがRayBarcode Readerモバイルアプリケーション上で設定できます。画面右上の三点の縦リーダーアイコンをタップして「設定」の「連続スキャン間隔」から変更できます。開発者が変更することはできません。
  • 連続読み取りで読み取りの終了タイミングは、開発者がWebServiceで指定できます。エンドユーザーもカメラ画面の左上にある「←」をタップすることで、連続読み取りを終了させることができます。
  • 読み取ったバーコードの情報は、複数の読み取り結果を蓄積してからまとめてSalesforceに送信することも、1回の読み取りごとにSalesforceに送信することもできます。これは開発者がWebServiceで実装できます。
  • 連続読み取りを制御するWebServiceは、VisualforceおよびLightning Auraコンポーネント、Lightning Webコンポーネントから共通で使用できます。
  • WebServiceの呼び出しは、Salesforce組織のAPI要求数を消費します。読み取りの成功、失敗にかかわらず1回の読み取り制御につき1消費します。Salesforce組織のAPI要求数が最大に達したとき、読み取り機能は単独読み取りの場合と同じ動作になります。

前提

WebServiceによる連続読み取り機能の開発にあたって、次の知識が必要です。

  • VVisualforceおよびLightning Auraコンポーネント、Lightning Webコンポーネントの開発
  • CSSを使った開発
  • JavaScriptを使った開発
  • Salesforceモバイルアプリケーションの開発
  • ApexによるWebServiceの開発

開発手順

連続読み取りに対応する、バーコード読み取り画面の開発手順は次のようになります。

  1. 画面のレイアウトを決定する。最小の構成で「読み取りボタン」と「読み取り結果の表示領域」が必要。
  2. 連続読み取りを制御するWebService(Apex)を作る。
  3. 読み取りが成功した後の処理をコントローラ(ApexまたはJavaScript)で受ける。
  4. 作成したアプリケーションをSalesforceアプリのナビゲーションメニューに表示する。

Visualforceによる連続読み取り

Visualforceページの開発では、1回の読み取り操作ごとに「読み取り開始」ボタンをタップする必要がありました。複数のQRコードを連続して読み取りたい場合、何度もタップするのは不便です。ここでは連続読み取りを実装します。

連続読み取りを有効にするには、gcbc:GcBarcodeScannerVFコンポーネントのcontinuousScan属性をtrueに設定します。さらにcontinuousScanCallback属性により、連続でバーコードを読み取る場合の操作を制御するコールバックを指定します。

  1. Salesforce Classicの場合、「設定 > ビルド > 開発 > Apexクラス」を開く。Lightning Experienceの場合、歯車アイコンをクリックした後「設定 > プラットフォームツール > カスタムコード > Apexクラス」を開く。
  2. 読み取り結果を受け取るコントローラ「Tutorial5Controller.cls」と連続読み取りを制御するWebServiceである「Tutorial5Service.cls」を作成する。

    // Tutorial5Controller.cls
    public with sharing class Tutorial5Controller {
    
    public PageReference onContinuousScanCompleteAction() {        
        return null;
    }
        
    // 読み取り結果を表示する要求に対して読み取り結果を返す
    public string getContinuousScanOutputMessage() {
        string[] results = splitMultipleScanResult(this.continuousScanResult);
            
        if (results != null){
            string message = '';
            integer counter = 1;
            string[] types = this.continuousScanTypes.split(',');
            for(string result : results){
                message += counter + ')[' + types[counter - 1] +  '] ' + result + '\r\n';
                counter++;
            }
            return message;
        }
        return '';        
    }
        
    // 連続読み取りのバーコードの値を格納する
    public string continuousScanResult {get;set;}
        
    // 連続読み取りのバーコードの種類を格納する
    public string continuousScanTypes {get;set;}
        
    private static string[] splitMultipleScanResult(string scanResult) {
        if (string.isEmpty(scanResult)) {
            return null;
        }
        string[] scanResultList = scanResult.split(',');
        for (Integer i = 0; i < scanResultList.size(); i++){
            // UTF-8でURLデコードする
            scanResultList[i] = EncodingUtil.urlDecode(scanResultList[i], 'UTF-8');
        }
        return scanResultList;
    }
    }
    

次のコードは、連続読み取りを制御するWebServiceです。このWebServiceは連続読み取り中に読み取り結果をユーザに表示するメッセージを含みます。Apexクラスとして追加します。

// Tutorial5Service.cls
@RestResource(urlMapping='/gcbc_tutorial5/*')
global with sharing class Tutorial5Service {
    
    @HttpPost
    global static BarcodeScanResponse processBarcodeContinuousScan() {
        BarcodeScanData data = (BarcodeScanData)JSON.deserialize
            (RestContext.request.requestBody.toString(), BarcodeScanData.class);
        BarcodeScanResponse response = new BarcodeScanResponse();
        
        if (data.scannedResult == null || data.scannedType != 'QR_CODE') {
            // 読み取り結果が空の場合、またはQRコード以外のバーコードを読み取った場合

            // 現在の読み取り結果を破棄する
            response.preserveScanResult = false;

            // 開発者は、ここで読み取り履歴と現在の読み取り内容を比較し、
            // 重複がある場合に現在の読み取り内容を破棄することもできます。
            // 破棄された読み取りデータは、次回の読み取り時には履歴には含まれません。
            
            response.displayMessage = 
                '非対応のバーコード形式[' + data.scannedType + ']です。QRコードを読み取ってください。';
            response.notifyErrorFeedback = true;
        } else {
            // 読み取り結果がQRコードの場合
            response.preserveScanResult = true;
            // 現在の読み取り回数を返す
            integer count = 1;
            if (data.preservedScannedContent != null) {
                count = data.preservedScannedContent.size() + 1;
            }
            response.displayMessage = '読み取り済み: ' + count + ' / 5、現在の読み取り結果:' + data.scannedResult;
        }
        
        // 5回のQRコードの読み取りが完了した後、読み取りを終了する
        if (
            data.preservedScannedContent != null && 
            data.preservedScannedContent.size() >= 4 && 
            response.preserveScanResult) {
            response.shouldContinueScan = false;
        }
        else {
            response.shouldContinueScan = true;
        }
        
        return response;         
    }
    
    global class BarcodeScanData{
        // 読み取ったすべてのバーコードの値
        @testVisible string[] preservedScannedContent;
        // 読み取ったすべてのバーコードの種類
        @testVisible string[] preservedScannedType;
        // 現在読み取ったバーコードの値
        @testVisible string scannedResult;
        // 現在読み取ったバーコードの種類
        @testVisible string scannedType;     
    }
    
    global class BarcodeScanResponse {
        boolean preserveScanResult;
        string displayMessage;
        boolean shouldContinueScan;
        boolean notifyErrorFeedback;

        public BarcodeScanResponse() {
            // 読み取り結果をpreservedScannedContentとpreservedScannedTypeに蓄積しない
            this.preserveScanResult = false;
            // 連続読み取り時に読み取り画面に表示するメッセージを初期化
            this.displayMessage = '';
            // 連続読み取りを継続する
            this.shouldContinueScan = true;
            // 読み取りエラー時にビープ音を再生しない
            this.notifyErrorFeedback = false;
        }        
    }
}

次に読み取り開始画面および続読み取りの完了後に結果をすべて表示する画面 である「Tutorial5.vfp」を作成します

  1. Salesforce Classicの場合、「設定 > ビルド > 開発 > Visualforce ページ」を開く。Lightning Experienceの場合、歯車アイコンをクリックした後「設定 > プラットフォームツール > カスタムコード > Visualforce ページ」を開く。
  2. 「新規」ボタンをクリックする。
  3. 表示ラベルや名前欄に”Tutorial5”を入力し、オプション「Lightning Experience、Lightning コミュニティ、およびモバイルアプリケーションで利用可能」にチェックを入れる。
  4. 後述のソースコードを貼り付けて、「保存」ボタンをクリックする。

Visualforceページの作成中に画面をプレビューすることができます。 ここで「プレビュー」ボタンをクリックすると、「連続読み取り開始」ボタンが表示されます。 ただし、PC(Mac)のブラウザではこのボタンをクリックすることはできません。

<!-- RayBarcode バーコード読み取り サンプルコード -->
<!-- Tutorial5.vfp -->
<apex:page controller="Tutorial5Controller">
    <!-- Lightning Design Systemを有効にする -->
    <apex:slds />
    <!-- 見出しを表示する -->
    <apex:sectionHeader title="チュートリアル5"/>
    <!-- 読み取りボタンを表示する -->
    <gcbc:GcBarcodeScannerVF
        id="continuousScanButton"
        buttonText="連続読み取り開始"
        continuousScan="true"
        continuousScanCallback="gcbc_tutorial5"
        onScanComplete="{!onContinuousScanCompleteAction}"
        reRender="allScansOutput"
        scanResults="{!ContinuousScanResult}" 
        scannedTypes="{!ContinuousScanTypes}"
        styleClass="slds-button slds-button--brand slds-m-top--medium" 
        style="width:200px;" />
    <!-- 結果の表示領域 -->    
    <apex:outputPanel id="allScansOutput" layout="block">
        <pre>{!ContinuousScanOutputMessage}</pre>       
    </apex:outputPanel>
    <script type="text/javascript">
        (function(){
            var id = "{!$Component.continuousScanButton}";
            var scannerDom = document.getElementById(id);
            scannerDom.addEventListener('scansuccess', (e)=>{        
                console.log(e.detail);                
                // 次のコードは、Apexへのデフォルトのアクションコールバックを防ぎます。
                //e.preventDefault();
            });            
        })();
    </script>
</apex:page>

「Tutorial5.vfp」のタブを設定し、Salesforceモバイルアプリケーションのメニューから設定したタブをタップして動作を確認します。。次の5つのバーコードのうち、はじめの3つはQRコードです。残りは、JAN13(EAN13)とITFです。QRコードを5回読み取れるので、上から順に読み取って、4番目と5番目でエラーになります。1~3番目を再度読み取って5回の連続読み取り操作を完了します。

Lightning Auraコンポーネントによる連続読み取り

連続読み取りに対応するには、次の作業が必要です。

  • continuousScan属性の値を「true」に設定する。
  • 連続読み取りの動作を制御するためのWebServiceを実装する。「Visualforceによる連続読み取り」で既に実装した「gcbc_tutorial5」を使用する。
  • 複数の読み取り結果を処理する。

次のサンプルはgcbc:GcBarcodeScannerLTで連続読み取りに対応する例です。

<aura:component implements="flexipage:availableForAllPageTypes" access="global">
    <aura:attribute name="continuousScanResult" type="String" />
    <aura:attribute name="continuousScannedTypes" type="String" />    
    <aura:attribute name="continuousScanResultOutout" type="String" />  
            
    <h1>連続読み取りを実行する</h1>
    <br />    
    <gcbc:GcBarcodeScannerLT
        aura:id="continuous-scan-button" 
        buttonText="連続読み取り"
        scanResults="{!v.continuousScanResult}"
        scannedTypes="{!v.continuousScannedTypes}"
        onScanComplete="{!c.onContinuousScanComplete}"
        continuousScan="true"
        continuousScanCallback="gcbc_tutorial5"
        />
    <br />
    <ui:outputText value="{!v.continuousScanResultOutout}" />
</aura:component>

サンプルに対して定義されたonContinuousScanCompleteメソッドは、次のようになります。

({
    onContinuousScanComplete: function (component, event, helper) {
        var result = event.getParam("success");
        if (result){
            var data = component.get("v.continuousScanResult");
            var types = component.get("v.continuousScannedTypes").split(",");
            var records = data.split(",");
            for(var i = 0; i < records.length; i++){
                records[i] = '[' + types[i] + '] ' + decodeURIComponent(records[i]);
            }
            component.set("v.continuousScanResultOutout", records.join("\r\n"));
        }else{
            alert("読み取り失敗");
        }
    }
})

作成したLightning Auraコンポーネントをタブに設定し、Salesforceモバイルアプリケーションのメニューから設定したタブをタップして動作を確認します。

Lightning Webコンポーネントによる連続読み取り

連続読み取りに対応するには、次の作業が必要です。

  • continuous-scan属性の値を「true」に設定する。
  • 連続読み取りの動作を制御するためのWebServiceを実装する。「Visualforceによる連続読み取り」で既に実装した「gcbc_tutorial5」を使用する。
  • 複数の読み取り結果を処理する。

次のサンプルはgcbc-gc-barcode-scanner-lwcで連続読み取りに対応する例です。

この手順は、Salesforce CLIやVisual Studio CodeなどLightning Webコンポーネントの開発環境が整っており、組織を操作するSalesforce DXプロジェクトでLightning WebコンポーネントやApexクラスなどを作成およびデプロイすることを前提としています。

  1. myFirstBarcodeContinuousScannerLwcという名前でLightning Webコンポーネントを新規に作成する。
  2. myFirstBarcodeContinuousScannerLwcに次のコードを記述する。
  3. myFirstBarcodeContinuousScannerLwcを組織にデプロイする。

myFirstBarcodeContinuousScannerLwc.html

<template>
    <h1>連続読み取りを実行する</h1>
    <div slot="actions">
        <gcbc-gc-barcode-scanner-lwc data-id="continuous-scan-button" button-text="連続読取"
            continuous-scan="true" continuous-scan-callback="gcbc_tutorial5"
            onscancomplete={onContinuousScanComplete}>
        </gcbc-gc-barcode-scanner-lwc>
    </div>
    <lightning-formatted-text value={continuousScanResultOutput}></lightning-formatted-text>
</template>

myFirstBarcodeContinuousScannerLwc.js

import { LightningElement, track } from 'lwc';

export default class MyFirstBarcodeContinuousScannerLwc extends LightningElement {
    @track continuousScanResultOutput;

    onContinuousScanComplete(event) {
        const data = event.detail;
        if (data && data.success) {
            const types = data.scanTypes && data.scanTypes.split(",") || [];
            const results = data.scanResults && data.scanResults.split(",") || [];
            const records = results.map((result, index) => `${index+1})[${types[index]}] ${decodeURIComponent(result)}`);

            this.continuousScanResultOutput = records.join("\r\n");
        } else {
            alert("読み取りはできませんでした。");
        }
    }
}

myFirstBarcodeContinuousScannerLwc.js-meta

<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>55.0</apiVersion>
    <isExposed>true</isExposed>
    <targets>
        <target>lightning__Tab</target>
    </targets>
</LightningComponentBundle>

次に、作成したLightning Webコンポーネントをタブに設定します。

  1. Salesforce Classicの場合、「設定 > ビルド > 作成 > タブ」をクリックする。Lightning Experienceの場合、歯車アイコンをクリックした後「設定 > プラットフォームツール > ユーザインタフェース > タブ」をクリックする。
  2. 「Lightning コンポーネントタブ」の「新規」ボタンをクリックする。
  3. 「Lightning コンポーネント」に「c:myFirstBarcodeContinuousScannerLwc」を選択する。
  4. 「タブの表示ラベル」に「MyFirstBarcodeContinuousScannerLwc」を入力する。
  5. 「タブ名」に「MyFirstBarcodeContinuousScannerLwc」を入力する。
  6. 「タブスタイル」に任意のスタイルを選択する。
  7. 「次へ」をクリックし、タブをプロファイルに割り当て、保存する。

Salesforceモバイルアプリケーションのメニューから「MyFirstBarcodeContinuousScannerLwc」をタップして動作を確認します。

continuousScanCallback属性のWebService

continuousScanCallback属性のWebServiceのリクエスト本体は、次のようなコードでBarcodeScanDataに変換できる文字列になります。

(BarcodeScanData)JSON.deserialize(RestContext.request.requestBody.toString(), BarcodeScanData.class);

コールバックの応答は BarcodeResponseScan オブジェクトとなります。ジョブを実行するメソッドは、 processBarcodeContinuousScan という名前にする必要がありますprocessBarcodeContinuousScan の定義は次のようになります。

global static BarcodeScanResponse processBarcodeContinuousScan()

WebServiceを使った連続読み取りを開発する際に使用するインターフェースについては、こちらを参照してください。

Copyright © 2023 MESCIUS inc. All rights reserved.