Help us understand the problem. What is going on with this article?

iPhone で運転免許証を読み取ってみよう!【SwiftUI で簡単に】

こんにちは、aBiteエンジニアのけわしです!
SwiftUIとOSSライブラリを使って、簡単に運転免許証を読み取ってみましょう。

Xcode プロジェクト作成

新規プロジェクトを作成し、
Screenshot 2019-12-09 at 19.37.43.png
Single View App を選びます。
Screenshot 2019-12-09 at 19.40.46.png

SwiftUI となっていることを確認します。
Screenshot 2019-12-09 at 19.42.47.png

設定

ライブラリの導入, Capability と Entitlements の設定, Info.plist-の設定 の三つを行ってください。

SwiftUI

コードのプログラミングは、2ステップです。
- UserData.swift: NFCリーダの起動と、読み取り後の変数への代入を行います
- ContentView.swift: 見た目を書きます

UserData

UserData.swift
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

ContentView.swift
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 の良いところは、
- 見た目を表現するコードが見やすい
- プレビューを見ながら、レイアウトを整えられる
- プレビューをクリックして触ると、コードに反映される
ことですね。

Screenshot 2019-12-09 at 20.15.26.png

SceneDelegate を修正

23行目くらいの次のコードを

SceneDelegate.swift
let contentView = ContentView()

次のように変更します。

SceneDelegate.swift
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

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした