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
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.