Asterisk社員の技術情報ブログ

AsReaderを”Flutter”で使う方法

最終更新日:2020年06月26日
カテゴリー:

大阪開発の林田です。

今回はAsReaderを”Flutter”で使う方法を記事にしたいと思います。

まず”Flutter”とはiOS, Android, Webなどの環境で動く
クロスプラットフォームの開発環境です。

クロスプラットフォーム環境ではよくReact Nativeとよく比較されますが
ここ最近は人気度やユーザ数などFlutterが優勢となっています。

さてまずAsReaderを導入する大まかな流れです。
1、AsReaderSDKをXcodeプロジェクトへ導入
2、AsReader管理クラスをXcodeで実装
3、AppDelegateファイルに”FlutterEventChannel”を作成
4、Flutter側でAsReaderから受けたイベントをストリームへ流す

一つずつ見ていきます。

1、AsReaderSDKをXcodeプロジェクトへ導入
以下のURLからSDKとSDK導入手順が記載されていますのでそちらを参照。
(※利用した機器によってSDKは切り替えてください)

2、AsReader管理クラスをXcodeで実装
SDKを制御するクラスを定義しコールバックを処理します

import Foundation
import AsReaderDockSDK

final class AsReaderManager: NSObject {
    
    static let shared = AsReaderManager()
    
    var onScan: FlutterEventSink?
    private let commonDevice = AsReaderDevice()
    
    9private override init() {}
    
    func setup() {
        commonDevice.delegateDevice = self
    }
    
}

extension AsReaderManager: AsReaderDeviceDelegate {
    func checkTriggerStatus(_ strStatus: String!) {}
    func plugged(_ plug: Bool) {
        guard plug else { return }
        commonDevice.setReaderPower(true, beep: true, vibration: true, led: true, illumination: true, mode: ASREADER_DEVICE_BARCODE)
    }
    func readerConnected(_ status: Int32) {}
    func responsePower(onOff isOn: Bool, hwModeChange isHWModeChange: Bool) {}
    func releasedTriggerButton() {}
    func pushedTriggerButton() {}
    func on(asReaderTriggerKeyEventStatus status: String!) {}
    func receivedScanData(_ readData: Data!) {
        guard readData != nil else { return }
        let value = String(data: readData, encoding: .ascii)
        onScan?(value)
    }
    func unknownCommandReceived(_ commandCode: Int32) {}
    func allDataReceived(_ data: Data!) {}
    func batteryReceived(_ battery: Int32) {}
    func stopReadScan(_ status: Int32) {}
    func startedReadScan(_ status: Int32) {}
    func errorReceived(_ errorCode: Data!) {}
}

3、AppDelegateファイルに”FlutterEventChannel”を作成
ここでプラットフォームからFlutterへ繋げる処理を記載します。

import UIKit
import Flutter

@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
  override func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
  ) -> Bool {
    
    //AsReader Setup
    AsReaderManager.shared.setup()
    
    //Method Channel
    let controller: FlutterViewController = window?.rootViewController as! FlutterViewController
    let eventChannel = FlutterEventChannel(name: "AsReader", binaryMessenger: controller.binaryMessenger)

    eventChannel.setStreamHandler(self)
    
    GeneratedPluginRegistrant.register(with: self)
    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
  }
}

extension AppDelegate: FlutterStreamHandler {
    func onListen(withArguments arguments: Any?, eventSink events: @escaping FlutterEventSink) -> FlutterError? {
        AsReaderManager.shared.onScan = events
        return nil
    }
    
    func onCancel(withArguments arguments: Any?) -> FlutterError? {
        return nil
    }
}

4、Flutter側でAsReaderから受けたイベントをストリームへ流す
プラットフォームから受け取ったコールバックをFlutter側で処理し
今回であればストリームへ流します。

/* Singleton */
class AsReader {
  static final _instance = AsReader._();
  factory AsReader() => _instance;
  AsReader._() {
    EventChannel("AsReader").receiveBroadcastStream().listen((event) {
      onScan.add(event);
    });
  }

  final onScan = StreamController();
}

ストリームへ流した結果はそれぞれ画面へ表示します

class _MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(""),
      ),
      body: Center(
          child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
            Text(
              'Scaneed Barcode',
            ),
            StreamBuilder(
                initialData: "",
                stream: AsReader().onScan.stream,
                builder: (context, AsyncSnapshot snapshot) {
                  if (snapshot.hasData) {
                    return Text(
                      '${snapshot.data}',
                      style: Theme.of(context).textTheme.headline4,
                    );
                  }
                  return Text("ここにバーコードが表示されます");
                }),
          ])),
    );
  }
}

以上になります。

ただ結論としてAsReaderはiOS専用でFlutterの特徴であるAndroidでも動くという点が
うまく使えていない為微妙かなとも思いますが…

記事のカテゴリー