Skip to content

Instantly share code, notes, and snippets.

@ryotapoi
Last active June 8, 2020 05:16
Show Gist options
  • Save ryotapoi/a14d6ff3d4d3acf6f4879552de77b2c0 to your computer and use it in GitHub Desktop.
Save ryotapoi/a14d6ff3d4d3acf6f4879552de77b2c0 to your computer and use it in GitHub Desktop.
Face ID(Touch IDを含む生体認証)

Face ID(Touch ID)

デバイスの正当な所有者であることを

  • 生体認証のみで認証する
  • 生体認証またはiOSパスワードで認証する
  • 生体認証またはアプリ独自の認証方式で認証する

を選べる。

注意

生体認証のみを使用し、アプリケーション独自のパスコードなども使用しない場合は var LAContext.localizedFallbackTitle: String に空文字列 "" を設定すること。 nil を設定してもデフォルト文字列でボタンが表示されてしまうため。

import UIKit
import LocalAuthentication
class ViewController: UIViewController {
override func loadView() {
view = UIView(frame: .zero)
let button = UIButton(frame: .zero)
button.translatesAutoresizingMaskIntoConstraints = false
button.setTitle("auth", for: .normal)
button.sizeToFit()
button.addTarget(self, action: #selector(auth(_:)), for: .touchUpInside)
view.addSubview(button)
NSLayoutConstraint.activate([
button.centerXAnchor.constraint(equalTo: view.centerXAnchor),
button.centerYAnchor.constraint(equalTo: view.centerYAnchor),
])
}
@IBAction func auth(_ sender: UIButton) {
let context = LAContext()
context.localizedCancelTitle = "Cancel" // cancel button title
// fallback button title
// 別手段で認証するためのボタンのこと。パスコードを入力させるなど。
// Fallbackさせたくない場合(iOSのパスコード入力をさせたくない場合も含む)空文字列 `""` を設定する。
// nilだとデフォルト文字列でFallbackボタンが表示されてしまう。
context.localizedFallbackTitle = "Fallback"
var error: NSError?
guard context.canEvaluatePolicy(.deviceOwnerAuthentication, error: &error) else {
let alert = UIAlertController(title: "ローカル認証が使用できません", message: nil, preferredStyle: .alert)
alert.addAction(.init(title: "ok", style: .cancel, handler: nil))
present(alert, animated: true, completion: nil)
return
}
// iOSのパスコードにfallbackさせる場合は `.deviceOwnerAuthentication`
// 自動でパスコードに遷移するので LAError.Code.userFallback のエラーは飛んでこなくなる。
context.evaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, localizedReason: "生体認証できず、CancelかFallbackするか決める時のメッセージ") { (result, error) in
if result {
print("success")
} else {
DispatchQueue.main.async {
self.showError(error)
}
}
}
}
func showError(_ error: Error?) {
if let error = error {
let laError = LAError(_nsError: error as NSError)
print(laError)
if laError.errorCode == LAError.Code.userFallback.rawValue {
// TODO: Fallback用の実装をする
print("fallback")
} else {
let alert = UIAlertController(title: "認証エラー", message: laError.localizedDescription, preferredStyle: .alert)
alert.addAction(.init(title: "ok", style: .cancel, handler: nil))
self.present(alert, animated: true, completion: nil)
}
} else {
let alert = UIAlertController(title: "認証エラー", message: "不明なエラーが発生しました。", preferredStyle: .alert)
alert.addAction(.init(title: "ok", style: .cancel, handler: nil))
self.present(alert, animated: true, completion: nil)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment