在密匙链中访问安全项有时会在iOS中返回错误-25308(errSecInteractionNotAllowed)

在密匙链中访问安全项有时会在iOS中返回错误-25308(errSecInteractionNotAllowed),ios,security,error-handling,keychain,Ios,Security,Error Handling,Keychain,我发现,有时我在尝试获取以前使用KeychainAPI成功存储的安全项目时会出现这种错误。我在设备中运行的应用程序处于后台状态并且我锁定了屏幕时发现了它。设备未设置锁定代码,这是我正在调用的函数: + (NSString *)findValueForKey:(NSString *)keyStr { NSString *valueStr = @""; if ((keyStr != nil) && (![keyStr isEqualToString:@""])) {

我发现,有时我在尝试获取以前使用
Keychain
API成功存储的安全项目时会出现这种错误。我在设备中运行的应用程序处于后台状态并且我锁定了屏幕时发现了它。设备未设置锁定代码,这是我正在调用的函数:

+ (NSString *)findValueForKey:(NSString *)keyStr
{
   NSString *valueStr = @"";

   if ((keyStr != nil) && (![keyStr isEqualToString:@""])) {
       NSString *service = [[NSBundle mainBundle] bundleIdentifier];

       NSDictionary *query = @{(__bridge id)kSecClass : (__bridge id)kSecClassGenericPassword,
                            (__bridge id)kSecAttrService : service,
                            (__bridge id)kSecAttrAccount : keyStr,
                            (__bridge id)kSecReturnData : (__bridge id)kCFBooleanTrue};

       CFDataRef cfValue = NULL;
       OSStatus results = SecItemCopyMatching((__bridge CFDictionaryRef)query, (CFTypeRef *)&cfValue);

       if ([self checkIfNoError:results]) {
           valueStr = [[NSString alloc] initWithData:(__bridge_transfer NSData *)cfValue encoding:NSUTF8StringEncoding];
       }

       else {
          NSLog(@"%@", [self getErrorMessageForStatus:results]);
       }
   }

   return valueStr;
}
并通过调用此方法存储该项:

+ (BOOL)storeInKeychainWithKey:(NSString *)keyStr withValueStr:(NSString *)valueStr
{
   if ((keyStr != nil) && (![keyStr isEqualToString:@""]) &&
       (valueStr != nil) && (![valueStr isEqualToString:@""])) {

       NSData *valueData = [valueStr dataUsingEncoding:NSUTF8StringEncoding];
       NSString *service = [[NSBundle mainBundle] bundleIdentifier];

       NSDictionary *secItem = @{(__bridge id)kSecClass : (__bridge id)kSecClassGenericPassword,
                              (__bridge id)kSecAttrService : service,
                              (__bridge id)kSecAttrAccount : keyStr,
                              (__bridge id)kSecValueData : valueData};

       CFTypeRef result = NULL;

       OSStatus status = SecItemAdd((__bridge CFDictionaryRef)secItem, &result);

       NSLog(@"%@", [self getErrorMessageForStatus:status]);

      return [self checkIfItem:status];
   }
   else {
      return NO;
   }
}
我认为在iOS中总是可以访问钥匙链项目。。。这似乎是关于类似的东西,但我不确定它是否是不赞成的,我应该如何解决这个问题


提前感谢

我们有同样的问题,@AppsDev,你提到的帖子是准确的。我们解决了这个问题,将钥匙链作为我们需要的东西的最后手段,即使我们卸载/重新安装应用程序

我们现在返回应用程序默认值(在Swift 3中为UserDefaults.standard),以便在安装生命周期未达到“卸载”阶段时方便地保存这些信息


如果卸载,下一次安装时,我们将转到密钥链(根据定义,刚安装的应用程序不在后台,因此不会失败)。通过检索到的数据,我们刷新应用程序默认值,然后使用应用程序默认值。

您解决过这个问题吗?