iOS
Swift
TouchID
swift3

アプリ内での Touch ID を利用したユーザ認証

More than 1 year has passed since last update.

はじめに

  • モバイルデバイスにとって、認証は重要です(モバイルじゃなくてもだけど)
  • iOS デバイスには、 Touch ID という指紋認証機能が組み込まれています
  • Touch ID は、意外なほど簡単にアプリから利用できます

検証環境

  • Xcode 8.3.3
  • Swift 3.1
  • iOS 10.3

利用する機能

LocalAuthentication フレームワーク

LAContext クラス

  • このクラスを利用して、認証を行います
  • Touch ID 搭載されているデバイスでは Touch ID(または Passcode)を、搭載されていないデバイスでは Passcode で認証を行います
メソッド 説明
canEvaluatePolicy(_: error:) -> Bool Touch ID が搭載されていて有効な状態、または Passcode が設定されている状態(Touch ID がなくても)であれば true を返す。
evaluatePolicy(_: localizedReason: reply:) Touch ID または Passcode を利用した認証を実行する。認証結果に対する処理は、第3引数のコールバックとして指定する。

 LAPolicy 列挙型

  • 上記のメソッドに渡す定数が定義されています
  • iOS 9 以降であれば、後者の deviceOwnerAuthentication を利用します
定数 説明
deviceOwnerAuthenticationWithBiometrics iOS 8 で利用。 iOS 9 以降でこの定数を利用すると、フォールバックボタン(指紋が認証されなかった場合に Passcode 入力を促すボタン)を押しても、入力画面が出ない?1
deviceOwnerAuthentication iOS 9 以降で利用。

実装例

ViewController.swift
import UIKit
import LocalAuthentication

class ViewController: UIViewController {
    @IBOutlet weak var authResultLabel: UILabel!

    @IBAction func authenticate(_ sender: UIButton) {
        let myContext = LAContext()
        self.configure(context: myContext)
        let reason = "Only device owner can use this feature."

        var authError: NSError? = nil

        // Touch ID が有効または Passcode がセットされている状態であることを確認
        if myContext.canEvaluatePolicy(.deviceOwnerAuthentication, error: &authError) {
            // 認証を実行
            myContext.evaluatePolicy(.deviceOwnerAuthentication, localizedReason: reason) { (success, evaluateError) in
                if success {
                    print("Success")

                    DispatchQueue.main.async {
                        self.authResultLabel.text = "Success"
                    }
                } else {
                    let error = evaluateError! as NSError
                    let errorMessage = "\(error.code): \(error.localizedDescription)"

                    print(errorMessage)

                    DispatchQueue.main.async {
                        self.authResultLabel.text = errorMessage
                    }
                }
            }
        } else {
            // Touch ID と Passcode のいずれも有効ではない場合

            let errorMessage = "\(authError!.code): \(authError!.localizedDescription)"
            print(errorMessage)

            DispatchQueue.main.async {
                self.authResultLabel.text = errorMessage
            }
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    /// ボタンの文字列をカスタマイズ
    private func configure(context: LAContext) {
        context.localizedCancelTitle = "キャンセル"
        context.localizedFallbackTitle = "パスコードを入力"
    }
}

実行結果

初期状態(Authenticate ボタンを押すと、指紋認証を実行)

initial.png

指紋認証

touch_id.png

指紋認証失敗(パスコード入力を促すボタン表示)

try_again.png

パスコード入力

passcode.png

成功時

success.png

キャンセル時

cancelled.png

パスコードが設定されていない場合

no_passcode.png

サンプルプロジェクト

参考サイト



  1. Apple の公式ドキュメント上では、この挙動に関する記述が見つけられませんでした。ご存知の方がいらっしゃれば、ご指摘頂けるとうれしいです。また、手元に iOS 8 の載ったデバイスがなかったので、 iOS 8 での確認ができてません。