我正在尝试创建一个keychain查询,但我在使用Attribute Item Keys作为字典键时遇到了困难.在创建字典时,我可以将包含在数组中的属性项作为字典键传递,如此没有任何问题
genericPasswordQuery = NSMutableDictionary(objects: [kSecClassGenericPassword, identifier], forKeys: [kSecClass, kSecAttrGeneric])
Run Code Online (Sandbox Code Playgroud)
但是,如果我尝试将另一个类似项添加到查询字典中,如下所示:
genericPasswordQuery.setObject(accessGroup, key:kSecAttrAccessGroup)
Run Code Online (Sandbox Code Playgroud)
它抱怨密钥不符合NSCopying并提供类型错误:
"无法找到接受所提供参数的'setObject'的重载"
这是SecItemAdd的标准实现,但我在Swift中遇到问题.
我想我找到了一个解决方案.来自文档:
当Swift导入尚未注释的API时,编译器无法自动内存管理返回的Core Foundation对象.Swift将这些返回的Core Foundation对象包装在Unmanaged结构中.所有间接返回的Core Foundation对象也是不受管理的.
从未注释的API接收非托管对象时,应在使用它之前立即将其转换为内存管理对象.这样,Swift可以为您处理内存管理.Unmanaged结构提供了两种方法来将非托管对象转换为内存托管对象-takeUnretainedValue()和takeRetainedValue().
目前的实施:
genericPasswordQuery = NSMutableDictionary(objects: [kSecClassGenericPassword, identifier], forKeys: [kSecClass, kSecAttrGeneric])
var kSecAttrAccessGroupSwift: NSString = kSecAttrAccessGroup.takeRetainedValue() as NSString
genericPasswordQuery.setObject(accessGroup, forKey: kSecAttrAccessGroupSwift)
Run Code Online (Sandbox Code Playgroud)
这在Xcode中运行良好,但当我添加.takeRetainedValue时,Playground会立即崩溃