2015-12-10 26 views
10

C'è un modo per determinare se un elemento (password, token, ecc.) È stato impostato nel portachiavi iOS utilizzando il controllo di accesso Touch ID senza chiedendo all'utente Touch ID? Abbiamo bisogno di determinare se la credenziale è già stata salvata sul portachiavi (con protezione Touch ID) prima di eseguire un'operazione, ma non vogliamo interrompere l'utente con il prompt Touch ID.Determinare se esiste un elemento del portachiavi protetto da Touch ID?

Ho provato il seguente ...

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

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

... 

Tuttavia, quando questo codice viene chiamato l'utente vede ancora il prompt ID Touch. Non vogliamo NIENTE da visualizzare nell'interfaccia utente, e vogliono solo un errore restituito nella OSStatus se tocco ID sarebbe stato richiesto.

Qualche idea?

risposta

7
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)); 
    } 
}); 
1

basato sul codice di neoneye e Swift 3. Ho aggiunto 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 
      } 
     } 
    }