CFDictionaryGetValue 无法使用 CFStringRef 调用

CFDictionaryGetValue can't invoke with CFStringRef

我正在尝试实现 CFDictionaryGetValue(),如 this appledoc 清单 3 所示:

server = CFDictionaryGetValue(credentialDict, kSecAttrServer);
userName = CFDictionaryGetValue(credentialDict, kSecAttrAccount);
password = CFDictionaryGetValue(credentialDict, kSecSharedPassword);

我是这样实现的

let userName = CFDictionaryGetValue(credentialDict, kSecAttrAccount)
let password = CFDictionaryGetValue(credentialDict, kSecSharedPassword)

但我收到错误 "Cannot invoke "CFDictionaryGetValue",参数列表类型为“(CFDictionaryRef, CFStringRef)”

我不明白这与苹果文档的实现方式有何不同。

谢谢

是的,雷达中提到的代码存在问题 here

我为您找到了解决方法:

  let unsafeCred = CFArrayGetValueAtIndex(credentials, 0)
  let credential: CFDictionaryRef = unsafeBitCast(unsafeCred, CFDictionaryRef.self)
  let dict: Dictionary<String, String> = credential as! Dictionary<String, String>
  let username = dict[kSecAttrAccount as String]
  let password = dict[kSecSharedPassword.takeRetainedValue() as! String]

更新

SecRequestSharedWebCredential("www.reddit.com", .None)  {
  credentials, error in 
    if CFArrayGetCount(credentials) > 0 {
      let dict = unsafeBitCast(
               CFArrayGetValueAtIndex(credentials, 0), 
               CFDictionaryRef.self) as Dictionary
    let username = dict[kSecAttrAccount as String]
    let password = dict[kSecSharedPassword as String]
    login(username, password)
  }
}

请注意这里的区别:

iOS8

var kSecSharedPassword: Unmanaged<AnyObject>!
func SecRequestSharedWebCredential(_ fqdn: CFString!,
                                   _ account: CFString!,
                                   _ completionHandler: ((CFArray!,
                                            CFError!) -> Void)!)

iOS9

let kSecSharedPassword: CFString
func SecRequestSharedWebCredential(_ fqdn: CFString?, 
                                   _ account: CFString?, 
                                   _ completionHandler: (CFArray?, CFError?) -> Void)

这是 swift2/iOS9/xcode7

的所有 changes

更新了 XCode 7.3 和 Swift 2.2

的答案
      if CFArrayGetCount(credentials) > 0 {
            let dict = unsafeBitCast(CFArrayGetValueAtIndex(credentials, 0), CFDictionaryRef.self) as NSDictionary
            let username = dict[kSecAttrAccount as String] as! String
            let password = dict[kSecSharedPassword as String] as! String
            dispatch_async(dispatch_get_main_queue()) {
                completion(error: nil, username: username, password: password)
            }

记住在返回用户名和密码的值时要小心,因为它必须在主线程上