使用Swift将项添加到钥匙串 [英] Adding item to keychain using Swift

查看:369
本文介绍了使用Swift将项添加到钥匙串的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用Swift将项目添加到iOS钥匙串,但无法弄清楚如何正确输入。从WWDC 2013会话709开始,给出以下Objective-C代码:

I'm trying to add an item to the iOS keychain using Swift but can't figure out how to type cast properly. From WWDC 2013 session 709, given the following Objective-C code:

NSData *secret = [@"top secret" dataWithEncoding:NSUTF8StringEncoding];
NSDictionary *query = @{
    (id)kSecClass: (id)kSecClassGenericPassword,
    (id)kSecAttrService: @"myservice",
    (id)kSecAttrAccount: @"account name here",
    (id)kSecValueData: secret,
};

OSStatus = SecItemAdd((CFDictionaryRef)query, NULL);

尝试在Swift中执行如下操作:

Attempting to do it in Swift as follows:

var secret: NSData = "Top Secret".dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)
var query: NSDictionary = [
    kSecClass: kSecClassGenericPassword,
    kSecAttrService: "MyService",
    kSecAttrAccount: "Some account",
    kSecValueData: secret
]

产生错误无法将表达式的'Dictionary'转换为'DictionaryLiteralConvertible'。

yields the error "Cannot convert the expression's type 'Dictionary' to 'DictionaryLiteralConvertible'.

我采用的另一种方法是使用Swift和一个字典上的 - setObject:forKey:方法,用键kSecClass添加kSecClassGenericPassword。

Another approach I took was to use Swift and the - setObject:forKey: method on a Dictionary to add kSecClassGenericPassword with the key kSecClass.

在Objective-中C:

In Objective-C:

NSMutableDictionary *searchDictionary = [NSMutableDictionary dictionary];
[searchDictionary setObject:(id)kSecClassGenericPassword forKey:(id)kSecClass];

在目标中C代码,各种keychain项类键的CFTypeRef使用id桥接。在Swift 文档中,它是提到Swift将id作为AnyObject导入。但是,当我试图将kSecClass转换为该方法的AnyObject时,我得到的错误是Type'AnyObject'不符合NSCopying。

In the Objective-C code, the CFTypeRef of the various keychain item class keys are bridged over using id. In the Swift documentation it's mentioned that Swift imports id as AnyObject. However when I attempted to downcast kSecClass as AnyObject for the method, I get the error that "Type 'AnyObject' does not conform to NSCopying.

任何帮助,无论是否是关于如何与Core Foundation类型互动的直接答案或一些指导将不胜感激。

Any help, whether it's a direct answer or some guidance about how to interact with Core Foundation types would be appreciated.

编辑2

此解决方案从Xcode 6 Beta 2开始不再有效。如果您使用Beta 1,则以下代码可能有效。

var secret: NSData = "Top Secret".dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)
let query = NSDictionary(objects: [kSecClassGenericPassword, "MyService", "Some account", secret], forKeys: [kSecClass,kSecAttrService, kSecAttrAccount, kSecValueData])

OSStatus status = SecItemAdd(query as CFDictionaryRef, NULL)

要使用Keychain Item Attribute键作为字典键,您必须使用takeRetainedValue或take来打开它们UnretainedValue(视情况而定)。然后你可以将它们转换为NSCopying。这是因为它们是标题中的CFTypeRefs,它们都不是可复制的。

To use Keychain Item Attribute keys as dictionary keys you have to unwrap them by using either takeRetainedValue or takeUnretainedValue (as appropriate). Then you can cast them to NSCopying. This is because they are CFTypeRefs in the header, which aren't all copyable.

然而,从Xcode 6 Beta 2开始,这会导致Xcode崩溃。

As of Xcode 6 Beta 2 however, this causes Xcode to crash.

推荐答案

在xcode 6.0.1中你必须这样做!!

In the xcode 6.0.1 you must do this!!

let kSecClassValue = NSString(format: kSecClass)
let kSecAttrAccountValue = NSString(format: kSecAttrAccount)
let kSecValueDataValue = NSString(format: kSecValueData)
let kSecClassGenericPasswordValue = NSString(format: kSecClassGenericPassword)
let kSecAttrServiceValue = NSString(format: kSecAttrService)
let kSecMatchLimitValue = NSString(format: kSecMatchLimit)
let kSecReturnDataValue = NSString(format: kSecReturnData)
let kSecMatchLimitOneValue = NSString(format: kSecMatchLimitOne)

这篇关于使用Swift将项添加到钥匙串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆