touchID的使用和编程

    最近我在开发一个需要touchID登入的类,于是我去官网上面 ,查找到了KeychainTouchIDUsingTouchIDwithKeychainandLocalAuthentication  ,这里面有很详细的教程,于是我封装了我自己使用的类,主要功能是通过touchID获得我放在密码链里面的账号和密码,只支持放入NSData数据也可以进行加密保存。


   首先是将你的账号和密码放入密码链,使用SecItemAdd函数添加一个数据进入密码链,代码如下:( 仅供参考,不可以直接复制粘贴)

 // we want the operation to fail if there is an item which needs authentication so we will use
    // kSecUseNoAuthenticationUI
    NSDictionary *attributes = @{
        (__bridge id)kSecClass: (__bridge id)kSecClassGenericPassword,
        (__bridge id)kSecAttrService: @"SampleService",
        (__bridge id)kSecValueData: [@"SECRET_PASSWORD_TEXT" dataUsingEncoding:NSUTF8StringEncoding],
        (__bridge id)kSecUseNoAuthenticationUI: @YES,
        (__bridge id)kSecAttrAccessControl: (__bridge_transfer id)sacObject
        };
    
    dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        OSStatus status =  SecItemAdd((__bridge CFDictionaryRef)attributes, nil);
        
        NSString *msg = [NSString stringWithFormat:NSLocalizedString(@"SEC_ITEM_ADD_STATUS", nil), [self keychainErrorToString:status]];
        [self printResult:self.textView message:msg];
    });


然后是登入的时候,弹出touchID输入框:

LAContext *context = [[LAContext alloc] init];
#ifdef MYDEBUG
    __block  NSString *msg;
#endif
    
    // show the authentication UI with our reason string
    if (![context canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:nil]) {
        //如果不能调用TouchID直接查询进去
        [self queryItem:sucess failure:failure];
    }else{
        [context evaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics localizedReason:strLoginName reply:
         ^(BOOL successFlag, NSError *authenticationError) {

下面根据successFlag进行判断,如果是NO,说明有错误,根据authenticationError来判断怎么处理,如果成功就去钥匙链里面获取,刚刚放进去的数据,重要函数是

SecItemCopyMatching,这些东西都请看官方的文档


</pre><pre>
    NSDictionary *query = @{
                            (__bridge id)kSecClass: (__bridge id)kSecClassGenericPassword,
                            (__bridge id)kSecAttrService: @"SampleService",
                            (__bridge id)kSecReturnData: @YES,
                            (__bridge id)kSecUseOperationPrompt: NSLocalizedString(@"AUTHENTICATE_TO_ACCESS_SERVICE_PASSWORD", nil)
                            };
    
    dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        CFTypeRef dataTypeRef = NULL;
        
        OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)(query), &dataTypeRef);
        if (status == errSecSuccess)
        {
            NSData *resultData = ( __bridge_transfer NSData *)dataTypeRef;
            NSDictionary *userinfo = [NSJSONSerialization JSONObjectWithData:resultData options:NSJSONReadingAllowFragments error:nil];
            sucess(userinfo);
           
        } else {
            failure(LAErrorAuthenticationFailed);
        }
    });




版权声明:本文为博主原创文章,未经博主允许不得转载。

posted @ 2014-10-29 11:53  _Roy  阅读(254)  评论(0编辑  收藏  举报