ObjecTips

Swift & Objective-C で iOS とか macOS とか

指紋認証APIの iOS 8.3 での変更点

iOS 8.2 から iOS 8.3 で Touch ID を使った指紋認証APIに微妙な変更があった。

フォールバックボタンの表示

まず iOS 8.2 で以下のコードを呼び出す

    LAContext *context = [[LAContext alloc] init];
    [context evaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics
            localizedReason:@"<localizedReason>"
                      reply:^(BOOL success, NSError *error) {
                          
                      }];

iOS 8.2 では「パスワードを入力」と「キャンセル」が表示される。

f:id:Koze:20150501181321p:plain

同じコードを iOS 8.3 で呼び出すと「キャンセル」のみが表示される。

f:id:Koze:20150501181504p:plain

そして(登録していない指で認証を試みるなどして)一度指紋認証に失敗すると「パスワードを入力」が表示される。

f:id:Koze:20150501181813p:plain

iOS 8.2 では初期状態でフォールバックボタンが表示されているのに対して、iOS 8.3 では一度認証に失敗してからフォールバックボタンがされるように変更になっている。

余談だけどバッテリーの緑色のアイコンが iOS 8.3 だと後ろのレイヤーにいっているのと、WiFiの電波状況の表示が3から2になっているのも気になった。
iOS のバージョンが変わった以外はまったく同じ場所と環境でテストしているので電波状況の表示アルゴリズムが変更になったんだと思う。

maxBiometryFailures

iOS 8.3 API Diffs で初出なのにヘッダでは available iOS 8.1 なっているこのAPI
もう Touch ID が使える iPhone は全部 iOS 8.3 にしてしまったので iOS 8.1 で実際に利用可能かどうかは分からない。
たまに新APIが追加された際にヘッダでの NS_AVAILABLE の指定が間違っていて古いバージョンのOSでAPIを呼ぶとクラッシュしてしまうという事があるので、使用する際は実機でちゃんと動くか試した方が良い。
(そういう場合は Apple にバグレポすると次のバージョンでヘッダを修正してくれる。)

このAPIはドキュメントにはまだ反映されていないので使用方法についてはヘッダのコメントを読む必要がある。

/// Allows setting the limit for the number of failures during biometric authentication.
///
/// @discussion When the specified limit is exceeded, evaluation of LAPolicyDeviceOwnerAuthenticationWithBiometrics
///             evaluation will fail with LAErrorAuthenticationFailed. By default this property is nil and
///             the biometric authentication fails after 3 wrong attempts.
///
/// @warning Please note that setting this property with high values does not prevent biometry lockout after 5
///          wrong attempts.
@property (nonatomic) NSNumber *maxBiometryFailures NS_AVAILABLE(10_10, 8_1);

デフォルトでは指紋認証に3回失敗すると reply: のブロックが返ってくるところをこのプロパティで回数を設定できる。
例えば0回や1回を指定した場合、指紋認証に1回失敗すると即座に

Domain=com.apple.LocalAuthentication Code=-1 "Application retry limit exceeded.

のエラーが起きて reply: が呼ばれる。
また5回より多い回数を指定したとしても、5回目の認証失敗で

Domain=com.apple.LocalAuthentication Code=-1 "Biometry is locked out.

のエラーが起きて reply: が呼ばれる。


ちなみに

    LAContext *context = [[LAContext alloc] init];
    context.localizedFallbackTitle = @"";

iOS 8.3 に限らず、フォールバックタイトルに空文字を入れてやれば「パスワードを入力」のボタンを表示しないようにできるので、フォールバックオプション無しで指紋認証の機能のみを利用する事ができる。