我想使用KeychainItemWrapper将UUID保存在钥匙串中,所以我在 MyKeychainManager.m 中添加以下方法:
#define keychain_idenentify @"com.myapp.bundle1"
+ (void)saveUUID:(NSString *)UUID{
if([MyKeychainManager getUUID].length > 0) {
return;
}
KeychainItemWrapper *keychain = [[KeychainItemWrapper alloc]initWithIdentifier:keychain_idenentify accessGroup:nil];
[keychain setObject:UUID forKey:(__bridge id)kSecAttrLabel];
}
+ (NSString *)getUUID {
KeychainItemWrapper *keychain = [[KeychainItemWrapper alloc]initWithIdentifier:keychain_idenentify accessGroup:nil];
NSString *uuidString = [keychain objectForKey:(__bridge id)kSecAttrLabel];
return uuidString;
}
但是在将 keychain_idenentify 更改为 com.otherApp.bundle 之后,它崩溃了
result = SecItemAdd((CFDictionaryRef)[self dictionaryToSecItemFormat:keychainItemData],NULL); NSAssert(结果 == noErr,@“无法添加钥匙串项目。” );
,错误为错误-25299
这是为什么以及如何解决?我应该选择哪一个,例如 kSecAttrLabel ?我将其更改为 kSecAttrService ,它很有趣,但是我不知道是否还有其他潜在的错误。
任何帮助将不胜感激。
答案 0 :(得分:0)
此错误表示具有该标识符的项目已经存在(https://osstatus.com/search/results?platform=all&framework=all&search=-25299)。尝试从钥匙串中删除它,然后您的代码应该可以使用。
答案 1 :(得分:0)
我花了很多天努力解决同样的问题。最后,我发现它的原因太容易过去了。
这是钥匙串的重要常数。看一下代码。 (假设我是第一次在目标中使用钥匙串)
KeychainItemWrapper *test1 = [[KeychainItemWrapper alloc] initWithIdentifier:@"test10" accessGroup:nil];
[test1 setObject:(id)@"value1" forKey:(id)kSecValueData];
//Normally it works
KeychainItemWrapper *test2 = [[KeychainItemWrapper alloc] initWithIdentifier:@"test20" accessGroup:nil];
//At this point , we meet the crash with the message of 'Couldn't add the Keychain Item.'
[test2 setObject:(id)@"value2" forKey:(id)kSecValueData];
即使'initWithIdentifier'的名称不同,常量'kSecAttrAccount'也必须是唯一的。 其默认值为“”(为空)。一旦使用了钥匙串包装器,它的'kSecAttrAccount'将被保存。因此,当您使用另一个“ initWithIdentifier”时,您需要特别注意“ kSecAttrAccount”。
我可以通过添加一些代码来解决上述代码的崩溃问题。
KeychainItemWrapper *test1 = [[KeychainItemWrapper alloc] initWithIdentifier:@"test10" accessGroup:nil];
[test1 setObject:@"test1" forKey:(id)kSecAttrAccount];
[test1 setObject:(id)@"value1" forKey:(id)kSecValueData];
KeychainItemWrapper *test2 = [[KeychainItemWrapper alloc] initWithIdentifier:@"test20" accessGroup:nil];
[test2 setObject:@"test2" forKey:(id)kSecAttrAccount];
[test2 setObject:(id)@"value2" forKey:(id)kSecValueData];
有关更多信息,如果您使用KeychainItemWrapper的accessGroup, 如上所述,无论是否使用accessGroup,kSecAttrAccount都必须唯一。
以下是示例。
KeychainItemWrapper *test = [[KeychainItemWrapper alloc] initWithIdentifier:@"test" accessGroup:"App_ID.SampleName"];
如您所知,应该在Apple开发人员处创建App_ID,并在您的应用目标的KeyChain共享功能下设置SampleName。 “。”必须在App_ID和SampleName之间添加。这是关键点。
请参阅其他人上传的帖子,以了解如何设置。