我正在处理一段代码,它应该完成以下操作:
- 在Keychain中存储一些数据。
- 只有在用户通过Touch ID或Pass Code进行身份验证后才能获取数据。
我编写了一些代码,但我的假设不起作用。这是我所写的:如果您在将新值添加到Keychain时设置正确的参数,则下次尝试取出它时,系统将自动显示Touch ID弹出窗口。
//
// Secret value to store
//
let valueData = "The Top Secret Message V1".data(using: .utf8)!;
//
// Create the Access Controll object telling how the new value
// should be stored. Force Touch ID by the system on Read.
//
let sacObject =
SecAccessControlCreateWithFlags(kCFAllocatorDefault,
kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly,
.userPresence,
nil);
//
// Create the Key Value array, that holds the query to store
// our data
//
let insert_query: NSDictionary = [
kSecClass: kSecClassGenericPassword,
kSecAttrAccessControl: sacObject!,
kSecValueData: valueData,
kSecUseAuthenticationUI: kSecUseAuthenticationUIAllow,
// This two valuse ideifieis the entry, together they become the
// primary key in the Database
kSecAttrService: "app_name",
kSecAttrAccount: "first_name"
];
//
// Execute the query to add our data to Keychain
//
let resultCode = SecItemAdd(insert_query as CFDictionary, nil);
起初我以为模拟器有问题,但是实际上我可以通过以下代码检查Touch ID是否存在:
//
// Check if the device the code is running on is capapble of
// finger printing.
//
let dose_it_can = LAContext()
.canEvaluatePolicy(
.deviceOwnerAuthenticationWithBiometrics, error: nil);
if(dose_it_can)
{
print("Yes it can");
}
else
{
print("No it can't");
}
我还能通过以下代码编程方式显示Touch ID弹出窗口:
//
// Show the Touch ID dialog to check if we can get a print from
// the user
//
LAContext().evaluatePolicy(
LAPolicy.deviceOwnerAuthenticationWithBiometrics,
localizedReason: "Such important reason ;)",
reply: {
(status: Bool, evaluationError: Error?) -> Void in
if(status)
{
print("OK");
}
else
{
print("Not OK");
}
});
总结
Touch ID可以工作,但是使用系统本身强制Touch ID标志将一个值保存到Keychain中无法工作——我错过了什么?
苹果的示例
苹果提供的示例称为KeychainTouchID:使用Touch ID与Keychain和LocalAuthentication也显示不一致的结果,Touch ID没有被系统强制执行。
技术规格
- Xcode 8.1
- Swift 3
SecItemCopyMatching
在哪里?你有存储数据到钥匙串的代码,但没有读取它的代码吗? - Bryan Chen