gpt4 book ai didi

cocoa - 将 SecIdentityRef 存储到 NSUserDefaults 中

转载 作者:行者123 更新时间:2023-12-03 17:14:44 24 4
gpt4 key购买 nike

我找到了将 APNS 与 cocoa 结合使用的绝佳解释。 APNS Pusher现在我不想每次都选择我的 SecIdentityRef (因为我很懒)我尝试将 SecIdentityRef 放入 NSData 并将其保存为默认值。下次应用程序启动时,我会再次加载它,它总是会收到 exc_bad_access 。这是我添加的代码:

// For saving
NSData *secRefData = [NSData dataWithBytes:[SFChooseIdentityPanel sharedChooseIdentityPanel].identity length:sizeof([SFChooseIdentityPanel sharedChooseIdentityPanel].identity)];
[[NSUserDefaults standardUserDefaults] setValue:secRefData forKey:@"identity"];

//For loading
NSData *secRefData = [[NSUserDefaults standardUserDefaults] valueForKey:@"identity"];
if([secRefData length] != 0) {
[[APNS sharedAPNS] setIdentity:(SecIdentityRef)CFRetain([secRefData bytes])];
}

我怎样才能让它发挥作用?我还有其他方式存储身份吗?

编辑

因此,我通过保存身份的名称找到了一种解决方案,在启动应用程序时,它会查找哪些可用身份具有此名称并使用具有正确名称的身份。代码如下:

//For loading
NSString *lastIdentityName = [[NSUserDefaults standardUserDefaults] valueForKey:@"identityName"];
if([lastIdentityName length] != 0) {
NSArray *allIdentities = [self identities];
for (id object in allIdentities) {
NSString *theName = [[[X509Certificate extractCertDictFromIdentity:(SecIdentityRef)object] valueForKey:@"Subject"] objectForKey:@"CommonName"];
if([theName isEqualToString:lastIdentityName]) {
[[APNS sharedAPNS] setIdentity:(SecIdentityRef)CFRetain((__bridge_retained SecIdentityRef)object)];
[[NSUserDefaults standardUserDefaults] setValue:[self identityName] forKey:@"identityName"];
// KVO trigger
[self willChangeValueForKey:@"identityName"];
[self didChangeValueForKey:@"identityName"];
}
}
}

//For saving
[[NSUserDefaults standardUserDefaults] setValue:[self identityName] forKey:@"identityName"];

最佳答案

使用SecKeychainItemCreatePersistentReference()SecKeychainItemCopyFromPercientReference()——它们可以在进程之间传递或持久化。不过,有一些注意事项:

  1. 您无法保留身份,只能保留证书,因此您必须经过额外的跃点才能在两者之间进行转换。
  2. 您将获得带有长且不透明数据 block 的NSData,因此您必须将其存储为这样,而不是例如作为字符串;并且忘记能够手动编辑此设置。

这就是我在 PDF 签名应用程序中的做法,到目前为止它工作完美。以下是代码的相关部分:

- (NSData*) identityToPersistent:(SecIdentityRef)ident
{
OSStatus status;
SecCertificateRef cert;
CFDataRef data = nil;

status = SecIdentityCopyCertificate(ident, &cert);
if (status != noErr)
return nil;
status = SecKeychainItemCreatePersistentReference((SecKeychainItemRef)cert, &data);
CFRelease(cert);
if (status != noErr)
return nil;

return CFBridgingRelease(data);
}

- (SecIdentityRef) identityFromPersistent:(NSData*)data
{
OSStatus status;
SecKeychainItemRef cert;
SecIdentityRef ident = nil;

status = SecKeychainItemCopyFromPersistentReference((__bridge CFDataRef)data, &cert);
if (status != noErr)
return nil;
status = SecIdentityCreateWithCertificate(NULL, (SecCertificateRef)cert, &ident);
CFRelease(cert);

return ident;
}


- (SecIdentityRef) getPreferredIdentity
{
NSData *data = [[NSUserDefaults standardUserDefaults] dataForKey:@"SigningIdentity"];
if (!data)
return nil;
return [self identityFromPersistent:data];
}

- (void) setPreferredIdentity:(SecIdentityRef)ident
{
NSData *data = [self identityToPersistent:ident];
[[NSUserDefaults standardUserDefaults] setObject:data forKey:@"SigningIdentity"];
}

关于cocoa - 将 SecIdentityRef 存储到 NSUserDefaults 中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10140244/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com