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

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

※「連続読み取り機能」の操作の流れについては、こちらの「連続読み取り機能の操作の場合」を参照してください。

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

前提

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

  • Visualforceページの開発またはLightningページの開発
  • CSSを使った開発
  • JavaScriptを使った開発
  • Salesforceモバイルアプリケーションの開発
  • ApexによるWebServiceの開発

利用手順

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

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

連続読み取りの実際の開発例は、このページのチュートリアル5とチュートリアル6を参照してください。その後に、インタフェースを説明します。

チュートリアル5. Visualforceアプリによる連続読み取り

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

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

次の手順ではPC(Mac)のブラウザで連続読み取りのアプリを作成します。

  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;
        }        
    }
}

次に読み取り開始画面を作成します。この画面は、連続読み取りの完了後に結果をすべて表示する画面も兼ねています。

以下の手順ではPC(Mac)のブラウザで「連続読み取り開始」ボタンを置く画面となるVisualforceページ 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>

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

チュートリアル6. Lightningアプリによる連続読み取り

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

  • continuousScan属性の値を「true」に設定する。
  • 連続と見取りの動作を制御するためのWebServiceを実装する。サンプルパッケージがインストールされている場合、「gcbc_continuousscandemo」サンプルを使用できる。
  • 複数の読み取り結果を処理する。

次のサンプルは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("読み取り失敗");
        }
    }
})

Salesforceアプリのナビゲーションメニューから「チュートリアル6」をタップして動作を確認します。

continuousScanCallback属性のWebService

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

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

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

global static BarcodeScanResponse processBarcodeContinuousScan()

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

Copyright © 2020 GrapeCity inc. All rights reserved.