Подтвердить что ты не робот

Определите, существует ли Touch-защищенный брелок?

Есть ли способ определить, был ли элемент (пароль, токен и т.д.) установленным в цепочке ключей iOS с помощью элемента управления доступом Touch ID без, запрашивающего пользователя для Touch ID? Нам нужно определить, были ли уже сохранены учетные данные в цепочке ключей (с защитой сенсорного ID) перед выполнением операции, но мы не хотим прерывать пользователя с помощью подсказки Touch ID.

Я пробовал следующее...

NSMutableDictionary *query = ...
query[(__bridge id)kSecUseNoAuthenticationUI] = (__bridge id)kCFBooleanTrue;

OSStatus opStatus = SecItemCopyMatching((__bridge CFDictionaryRef)query, NULL);

...

Однако, когда этот код вызывается, пользователь все еще видит приглашение Touch ID. Мы не хотим, чтобы в пользовательском интерфейсе отображалось НИЧЕГО, и просто хотите получить ошибку, возвращенную в OSStatus, если бы был необходим Touch ID.

Любые мысли?

4b9b3361

Ответ 1

NSDictionary *query = @{
                        (__bridge id)kSecClass: (__bridge id)kSecClassGenericPassword,
                        (__bridge id)kSecAttrService: @"SampleService",
                        (__bridge id)kSecUseNoAuthenticationUI: @YES
                        };

dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    CFTypeRef dataTypeRef = NULL;
    OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)(query), &dataTypeRef);
    if (status == errSecInteractionNotAllowed) {
        NSLog(@"ITEM EXIST");
    } else if (status == errSecItemNotFound) {
        NSLog(@"ITEM DOES NOT EXIST");
    } else {
        NSLog(@"status: %@", @(status));
    }
});

Ответ 2

на основе кода neoneye и Swift 3. Я добавил errSecAuthFailed.

    query[kSecClass as String] : kSecClassGenericPassword,
    query[kSecAttrService as String] : "serviceName"    
    query[kSecUseAuthenticationUI as String] = kSecUseAuthenticationUIFail

    DispatchQueue.global().async {

        var result : AnyObject?
        let status = SecItemCopyMatching(query as CFDictionary, &result)

        if status == errSecInteractionNotAllowed {

            DispatchQueue.main.async {

                // item exists
            }
        } else if status == errSecAuthFailed {

            DispatchQueue.main.async {

                // item exists but someone removed the touch id or passcode
            }
        } else if status == errSecItemNotFound {

            DispatchQueue.main.async {

                // it does not exist
            }
        } else {

            DispatchQueue.main.async {

                // another OSStatus
            }
        }
    }