简体   繁体   中英

CFDictionaryGetValue can't invoke with CFStringRef

I am trying to implement the CFDictionaryGetValue() as shown in this appledoc listing 3:

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

and I implemented like this

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

but I get the error "Cannot invoke "CFDictionaryGetValue" with argument list of type "(CFDictionaryRef, CFStringRef)"

I dont understand how this is different from how the apple doc implemented it.

thanks

Yes there is an issue with that code mentioned in radar here

I found a workaround for you:

  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]

UPDATE

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)
  }
}

Please mind the difference here:

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)

Here are all the changes for swift2/iOS9/xcode7

Updated answer for XCode 7.3 and 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)
            }

Remember to be careful when returning the values for username and password as it has to be on the main thread

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM