こんにちは、aBiteエンジニアのけわしです!
SwiftUIとOSSライブラリを使って、簡単に運転免許証を読み取ってみましょう。
Xcode プロジェクト作成
新規プロジェクトを作成し、
Single View App を選びます。
設定
ライブラリの導入, Capability と Entitlements の設定, Info.plist-の設定 の三つを行ってください。
SwiftUI
コードのプログラミングは、2ステップです。
- UserData.swift: NFCリーダの起動と、読み取り後の変数への代入を行います
- ContentView.swift: 見た目を書きます
UserData
import Foundation
import TRETJapanNFCReader
final class UserData: NSObject, ObservableObject, DriversLicenseReaderSessionDelegate {
var reader: DriversLicenseReader?
@Published var registeredDomicileString: String? = nil
func driversLicenseReaderSession(didRead driversLicenseCard: DriversLicenseCard) {
// スキャン完了時の処理
self.publishCardInfo(driversLicenseCard)
}
func publishCardInfo(_ driversLicneceCard: DriversLicenseCard) {
// DispatchQueue.main.async を使う理由は、UserData と ContentView が別スレッドで走っているため。代入処理をこれで囲む
DispatchQueue.main.async {
self.registeredDomicileString = driversLicneceCard.registeredDomicile?.registeredDomicile
}
}
print("data has been published")
}
func japanNFCReaderSession(didInvalidateWithError error: Error) {
print("finished")
}
func startScan(items: [DriversLicenseCardItem], pin1: String = "", pin2: String = "") {
self.reader?.get(items: items,
pin1: pin1, pin2: pin2)
print("UserData startScan")
}
override init() {
super.init()
self.reader = DriversLicenseReader(delegate: self)
}
}
ContentView
import SwiftUI
struct ContentView: View {
@EnvironmentObject var userData: UserData
@State var pin1: String = ""
@State var pin2: String = ""
var body: some View {
NavigationView {
List {
if self.userData.registeredDomicileString != nil {
RecordView(key: "本籍", value: self.userData.registeredDomicileString)
}
SecureField("暗証番号1", text:$pin1).keyboardType(.numbersAndPunctuation)
SecureField("暗証番号2", text:$pin2).keyboardType(.numbersAndPunctuation)
Button(action: {
self.userData.startScan(items: [.registeredDomicile], pin1: self.pin1, pin2: self.pin2)
}) {
Text("スキャン").foregroundColor(.blue)
}.disabled(self.pin1.count != 4)
.disabled(self.pin2.count != 4)
}.navigationBarTitle("記載事項(本籍)")
}
}
}
struct RecordView: View {
var key: String
var value: String?
var body: some View {
HStack {
Text(key)
Spacer()
if (value != nil) {Text(value!).bold()}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView().environmentObject(UserData())
}
}
struct RecordView_Previews: PreviewProvider {
static var previews: some View {
RecordView(key: "本籍", value: "東京都千代田区〇〇")
.previewLayout(.fixed(width: 300, height: 40))
}
}
Swift の良いところは、
- 見た目を表現するコードが見やすい
- プレビューを見ながら、レイアウトを整えられる
-
プレビューをクリックして触ると、コードに反映される
ことですね。
SceneDelegate を修正
23行目くらいの次のコードを
let contentView = ContentView()
次のように変更します。
let contentView = ContentView().environmentObject(UserData())
#コード例、アプリ
この記事のコードは https://github.com/treastrain/TRETJapanNFCReader/tree/master/Examples/SwiftUIDriversLicenseReader に公開しております(ContentView.swiftはRegisteredDomicile.swiftに対応します)。
また、アプリも便利にお使い頂ければと、無料で公開しております。
https://apps.apple.com/jp/app/id1487791296?ign-mpt=uo%3D4
#参考記事
SwiftUI のチュートリアル:https://developer.apple.com/tutorials/swiftui
免許証読み取りの SwiftUI ではないバージョンは、こちらの記事です。環境設定などは共通しています。
https://qiita.com/treastrain/items/9025000acec37f77134a