Pas*_*tne 13 keychain ios swift
我正在尝试使用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);
Run Code Online (Sandbox Code Playgroud)
尝试在Swift中执行如下操作:
var secret: NSData = "Top Secret".dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)
var query: NSDictionary = [
kSecClass: kSecClassGenericPassword,
kSecAttrService: "MyService",
kSecAttrAccount: "Some account",
kSecValueData: secret
]
Run Code Online (Sandbox Code Playgroud)
产生错误"无法将表达式的类型'Dictionary'转换为'DictionaryLiteralConvertible'.
我采用的另一种方法是使用Swift和- setObject:forKey:Dictionary上的方法来添加kSecClassGenericPassword和密钥kSecClass.
在Objective-C中:
NSMutableDictionary *searchDictionary = [NSMutableDictionary dictionary];
[searchDictionary setObject:(id)kSecClassGenericPassword forKey:(id)kSecClass];
Run Code Online (Sandbox Code Playgroud)
在Objective-C代码中,使用id桥接各种keychain项类键的CFTypeRef.在Swift 文档中,提到Swift将id作为AnyObject导入.但是,当我试图将kSecClass转发为方法的AnyObject时,我得到的错误是"Type'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)
Run Code Online (Sandbox Code Playgroud)
要将Keychain Item Attribute键用作字典键,您必须使用takeRetainedValue或takeUnretainedValue(根据需要)将它们打开.然后你可以将它们转换为NSCopying.这是因为它们在头文件中是CFTypeRefs,它们都不是可复制的.
但是,从Xcode 6 Beta 2开始,这会导致Xcode崩溃.
Sam*_*fes 13
你只需要向下翻译文字:
let dict = ["hi": "Pasan"] as NSDictionary
Run Code Online (Sandbox Code Playgroud)
现在dict是一个NSDictionary.要制作一个可变的,它与Objective-C非常相似:
let mDict = dict.mutableCopy() as NSMutableDictionary
mDict["hola"] = "Ben"
Run Code Online (Sandbox Code Playgroud)
在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)
Run Code Online (Sandbox Code Playgroud)
也许事情有所改善.在Xcode 7 beta 4上,除了处理结果外,似乎没有必要进行转换AnyObject?.具体来说,以下似乎有效:
var query : [NSString : AnyObject] = [
kSecClass : kSecClassGenericPassword,
kSecAttrService : "MyAwesomeService",
kSecReturnAttributes : true, // return dictionary in result parameter
kSecReturnData : true // include the password value
]
var result : AnyObject?
let err = SecItemCopyMatching(query, &result)
if (err == errSecSuccess) {
// on success cast the result to a dictionary and extract the
// username and password from the dictionary.
if let result = result as ? [NSString : AnyObject],
let username = result[kSecAttrAccount] as? String,
let passdata = result[kSecValueData] as? NSData,
let password = NSString(data:passdata, encoding:NSUTF8StringEncoding) as? String {
return (username, password)
}
} else if (status == errSecItemNotFound) {
return nil;
} else {
// probably a program error,
// print and lookup err code (e.g., -50 = bad parameter)
}
Run Code Online (Sandbox Code Playgroud)
如果缺少密钥,请添加密钥:
var query : [NSString : AnyObject] = [
kSecClass : kSecClassGenericPassword,
kSecAttrService : "MyAwesomeService",
kSecAttrLabel : "MyAwesomeService Password",
kSecAttrAccount : username,
kSecValueData : password.dataUsingEncoding(NSUTF8StringEncoding)!
]
let result = SecItemAdd(query, nil)
// check that result is errSecSuccess, etc...
Run Code Online (Sandbox Code Playgroud)
需要指出的一些事项:您的初始问题可能是str.dataUsingEncoding返回Optional.添加'!' 或者更好的是,使用一个if let来处理nil返回,可能会使你的代码工作.打印出错误代码并在文档中查找它将有助于隔离问题(我得到错误-50 =错误的参数,直到我发现我的kSecClass有问题,与数据类型或强制转换无关!) .
| 归档时间: |
|
| 查看次数: |
14586 次 |
| 最近记录: |