はじめに
- モバイルデバイスにとって、認証は重要です(モバイルじゃなくてもだけど)
- 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 ボタンを押すと、指紋認証を実行)
指紋認証
指紋認証失敗(パスコード入力を促すボタン表示)
パスコード入力
成功時
キャンセル時
パスコードが設定されていない場合
サンプルプロジェクト
- 今回作成したサンプルは、 GitHub からダウンロードできます。
参考サイト
-
App-Level Passcode | Cocoanetics
- iOS 9 以降では deviceOwnerAuthentication を利用する旨の解説あり
-
LAContext - LocalAuthentication | Apple Developer Documentation
- 公式ドキュメント(情報が古い?)
-
Apple の公式ドキュメント上では、この挙動に関する記述が見つけられませんでした。ご存知の方がいらっしゃれば、ご指摘頂けるとうれしいです。また、手元に iOS 8 の載ったデバイスがなかったので、 iOS 8 での確認ができてません。 ↩