确定受 Touch ID 保护的钥匙串项是否存在?
Determine if Touch ID-Protected Keychain Item Exists?
有没有一种方法可以使用 Touch ID 访问控制 来确定是否已在 iOS 钥匙串中设置了一个项目(密码、令牌等) =25=] 提示用户输入 Touch ID?我们需要在执行操作之前确定凭据是否已保存到钥匙串(具有 Touch ID 保护),但我们不想用 Touch ID 提示打扰用户。
我试过以下...
NSMutableDictionary *query = ...
query[(__bridge id)kSecUseNoAuthenticationUI] = (__bridge id)kCFBooleanTrue;
OSStatus opStatus = SecItemCopyMatching((__bridge CFDictionaryRef)query, NULL);
...
但是,调用此代码时,用户仍会看到 Touch ID 提示。我们不希望 ANYTHING 显示在 UI 上,只希望在 OSStatus
中返回一个错误如果需要 Touch ID 。
有什么想法吗?
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));
}
});
基于 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
}
}
}
有没有一种方法可以使用 Touch ID 访问控制 来确定是否已在 iOS 钥匙串中设置了一个项目(密码、令牌等) =25=] 提示用户输入 Touch ID?我们需要在执行操作之前确定凭据是否已保存到钥匙串(具有 Touch ID 保护),但我们不想用 Touch ID 提示打扰用户。
我试过以下...
NSMutableDictionary *query = ...
query[(__bridge id)kSecUseNoAuthenticationUI] = (__bridge id)kCFBooleanTrue;
OSStatus opStatus = SecItemCopyMatching((__bridge CFDictionaryRef)query, NULL);
...
但是,调用此代码时,用户仍会看到 Touch ID 提示。我们不希望 ANYTHING 显示在 UI 上,只希望在 OSStatus
中返回一个错误如果需要 Touch ID 。
有什么想法吗?
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));
}
});
基于 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
}
}
}