简体   繁体   中英

Access to shared keychain in iOS 8 share extension returns nil

The problem:

I have an iOS 8 application with a framework for keychain access and a share extension.

在此处输入图片说明

Both, the host application and the share extension link the keychain access framework and they both share a keychain.

Everything works in Debug configuration. But when I use the Release configuration the value dataTypeRef is always nil when I try to receive a password from the keychain.

I have already tried to add an App Group but without luck.

Has anyone an idea why it doesn't work for Release builds? Thanks

The code for the keychain access:

In the keychain access framework I add a password to the keychain like this:

public class func setPassword(password: String, account: String, service: String = "kDDHDefaultService") {
    var secret: NSData = password.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!
    let objects: Array = [secClassGenericPassword(), service, account, secret]

    let keys: Array = [secClass(), secAttrService(), secAttrAccount(), secValueData()]

    let query = NSDictionary(objects: objects, forKeys: keys)

    SecItemDelete(query as CFDictionaryRef)

    let status = SecItemAdd(query as CFDictionaryRef, nil)
}

To receive the password I do this:

 public class func passwordForAccount(account: String, service: String = "kDDHDefaultService") -> String? {

    let keys: [AnyObject] = [secClass(), secAttrService(), secAttrAccount(), secReturnData()]
    let objects: [AnyObject] = [secClassGenericPassword(), service, account, true]

    println("keys \(keys), objects \(objects)")

    let queryAttributes = NSDictionary(objects: objects, forKeys: keys)

    var dataTypeRef : Unmanaged<AnyObject>?
    let status = SecItemCopyMatching(queryAttributes, &dataTypeRef);
    if status == errSecItemNotFound {
        println("not Found")
        return nil
    }

    if dataTypeRef == nil {  // dataTypeRef is always nil in Release builds
        println("dataTypeRef == nil")
        return nil
    }

    let retrievedDataRef : CFDataRef = dataTypeRef!.takeRetainedValue() as CFDataRef
    let retrievedData : NSData = retrievedDataRef

    let password = NSString(data: retrievedData, encoding: NSUTF8StringEncoding)

    return password as? String
}

Note: This has nothing to do with the share extension it even doesn't work for the host application.

Update: For a test I have added the KeychainAccess class to the target of the host application. But I still can't access the keychain in Release builds.

I think I found a temporary fix. As suggested in a comment to this answer I set the optimization of the Swift compiler to None[-Onone] in the keychain access target and it seems to work now.

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