デバイスの正当な所有者であることを
- 生体認証のみで認証する
- 生体認証または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) | |
} | |
} | |
} |