title: Keychain error -25300 (errSecItemNotFound) when disabling and re-enabling Touch ID
body: <p>I save the password to keychain with Touch ID flags:</p>
  
  <pre><code>+ (void)setPasscode:(NSString *)passcode
  {
      CFErrorRef error = NULL;
      SecAccessControlRef sacObject;
  
      sacObject = SecAccessControlCreateWithFlags(kCFAllocatorDefault,
                                                      kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly,
                                                      kSecAccessControlUserPresence, &amp;error);
  
  
      if(sacObject == NULL || error != NULL)
      {
          DLog(@"can't create sacObject: %@", error);
          return;
      }
  
      NSDictionary *attributes = @{
                                   (__bridge id)kSecClass: (__bridge id)kSecClassGenericPassword,
                                   (__bridge id)kSecAttrService: kKeychainServiceName,
                                   (__bridge id)kSecValueData: [passcode dataUsingEncoding:NSUTF8StringEncoding],
                                   (__bridge id)kSecUseNoAuthenticationUI: @YES,
                                   (__bridge id)kSecAttrAccessControl: (__bridge_transfer id)sacObject
                                   };
  
      dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
          SecItemAdd((__bridge CFDictionaryRef)attributes, nil);
      });
  }
  </code></pre>
  
  <p>And retrieving it:</p>
  
  <pre><code>+ (void)getCurrentPasscodeWithSuccess:(void (^)(NSString *))success failure:(void (^)(OSStatus))failure
  {
      NSDictionary *query = @{
                              (__bridge id)kSecClass: (__bridge id)kSecClassGenericPassword,
                              (__bridge id)kSecAttrService: kKeychainServiceName,
                              (__bridge id)kSecReturnData: @YES,
                              (__bridge id)kSecUseOperationPrompt: kOperationPrompt
                              };
  
      dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
          CFTypeRef dataTypeRef = NULL;
  
          OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)(query), &amp;dataTypeRef);
          if (status == errSecSuccess)
          {
              if (success) {
                  NSData *resultData = ( __bridge_transfer NSData *)dataTypeRef;
                  NSString *result = [[NSString alloc] initWithData:resultData encoding:NSUTF8StringEncoding];
                  success(result);
              }
          } else {
              if (failure) {
                  failure(status);
              }
          }
      });
  }
  </code></pre>
  
  <p>This works fine. But if you disable Touch ID, and re-enable it on device, SecItemCopyMatching returns OSStatus -25300 (errSecItemNotFound).
  Problem is that item still exists there (I think). Because when I try tio access it, Touch ID prompt comes up.</p>
  
  <p>I tried to check if item exists with the following method:</p>
  
  <pre><code>+ (void)checkIfPasscodeExistsInKeychainWithCompletion:(void (^)(BOOL))completion
  {
      NSDictionary *query = @{
  
                              (__bridge id)kSecClass: (__bridge id)kSecClassGenericPassword,
                              (__bridge id)kSecAttrService: kKeychainServiceName,
                              };
  
      dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
          CFTypeRef dataTypeRef = NULL;
  
          OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)(query), &amp;dataTypeRef);
          BOOL exists = status != errSecItemNotFound;
  
          if (completion) {
              completion(exists);
          }
      });
  }
  </code></pre>
  
  <p>And this triggers the Touch ID prompt, and then returns error that it doesn't exist when touch is provided.</p>
  
  <p>But if I remove  (__bridge id)kSecClass: (__bridge id)kSecClassGenericPassword line, I get the status that it exists in keychain.</p>