AsReaderを”Flutter”で使う方法
大阪開発の林田です。
今回は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でも動くという点が
うまく使えていない為微妙かなとも思いますが…