我正在尝试使用Swift将项目添加到iOS钥匙串中,但无法弄清楚如何正确地进行类型转换。在WWDC 2013大会709上给出了以下Objective-C代码:
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中执行以下操作:
var secret: NSData = "Top Secret".dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)
var query: NSDictionary = [
kSecClass: kSecClassGenericPassword,
kSecAttrService: "MyService",
kSecAttrAccount: "Some account",
kSecValueData: secret
]
产生错误“无法将表达式的类型'Dictionary'转换为'DictionaryLiteralConvertible'。
我采用的另一种方法是使用Swift和- setObject:forKey:
Dictionary上的方法来添加带有密钥kSecClass的kSecClassGenericPassword。
在Objective-C中:
NSMutableDictionary *searchDictionary = [NSMutableDictionary dictionary];
[searchDictionary setObject:(id)kSecClassGenericPassword forKey:(id)kSecClass];
在Objective-C代码中,使用id桥接了各种钥匙串项类键的CFTypeRef。在Swift文档中,提到了Swift将id导入为AnyObject。但是,当我尝试将kSecClass转换为该方法的AnyObject时,出现以下错误:“类型'AnyObject'不符合NSCopying。
任何帮助,无论是直接答案还是有关如何与Core Foundation类型进行交互的指导,都将受到赞赏。
编辑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)
要将“钥匙串项属性”键用作字典键,您必须使用takeRetainedValue或takeUnretainedValue(视情况而定)对其进行解包。然后,您可以将它们强制转换为NSCopying。这是因为它们是标头中的CFTypeRefs,并非全部可复制。
从Xcode 6 Beta 2开始,这会导致Xcode崩溃。
在xcode 6.0.1中,您必须执行此操作!
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)
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句