使用来自 Swift 的 SecKeychainCreate
Using SecKeychainCreate from Swift
我正在编写一个应该维护自定义钥匙串的 OS X 应用程序,我正在尝试使用安全框架的 API 创建钥匙串,但是,我似乎无法获得它在 Swift.
下编译
这是我所拥有的,假设 path
包含一个可能存在的钥匙串的路径:
let pathName = (path as NSString).UTF8String
var keychain: Unmanaged<SecKeychain>?
var status = withUnsafeMutablePointer(&keychain) { pointer in
SecKeychainOpen(pathName, pointer)
}
if status != errSecSuccess {
status = withUnsafeMutablePointer(&keychain) { pointer in
SecKeychainCreate(pathName, UInt32(0), nil, false, nil, pointer)
}
}
编译器抱怨 SecKeychainCreate 调用中的类型,但是,我不明白我做错了什么。
Cannot invoke 'withUnsafeMutablePointer' with an argument list of type '(inout Unmanaged<SecKeychain>?, (_) -> _)'
如果我稍微修改第二个闭包,我会得到这个编译器错误:
Cannot invoke 'SecKeychainCreate' with an argument list of type '(UnsafePointer<Int8>, UInt32, nil, Bool, nil, (UnsafeMutablePointer<Unmanaged<SecKeychain>?>))'
感谢所有建议。
SecKeychainCreate()
的 promptUser
参数具有类型
Boolean
,它是 "Mac OS historic type" 和 UInt8
的别名,
所以它不同于Swift 1.2中的Swift Bool
。
(比较 Type 'Boolean' does not conform to protocol 'BooleanType' 的类似问题。)
这意味着你必须
通过 Boolean(0)
而不是 false
:
SecKeychainCreate(pathName, UInt32(0), nil, Boolean(0), nil, pointer)
补充说明:
withUnsafeMutablePointer()
不需要,可以传&keychain
到钥匙串功能。
(path as NSString).UTF8String
不需要,可以传一个Swift
字符串到需要 const char *
参数的 C 函数,
比较 String value to UnsafePointer<UInt8> function parameter behavior.
- 只允许将
nil
作为密码传递给 SecKeychainCreate()
如果 promptUser
是 TRUE
,否则会导致
"parameter error (-50)".
SecKeychainOpen()
即使钥匙串文件不成功
存在。根据文档,您必须检查
SecKeychainGetStatus()
。或者,您可以尝试创建
首先是钥匙串文件,例如 Open Local Items Keychain?.
一起:
let path = "/path/to/my.keychain"
var keychain: Unmanaged<SecKeychain>?
var status = SecKeychainCreate(path, 0, "", Boolean(0), nil, &keychain)
if status == OSStatus(errSecDuplicateKeychain) {
status = SecKeychainOpen(path, &keychain)
}
从 Swift 2 / Xcode 7 beta 5 开始, Mac 类型 Boolean
被映射
到 Swift 为 Bool
,钥匙链功能不再 return
非托管对象:
let path = "/path/to/my.keychain"
var keychain: SecKeychain?
var status = SecKeychainCreate(path, 0, "", false, nil, &keychain)
if status == OSStatus(errSecDuplicateKeychain) {
status = SecKeychainOpen(path, &keychain)
}
我正在编写一个应该维护自定义钥匙串的 OS X 应用程序,我正在尝试使用安全框架的 API 创建钥匙串,但是,我似乎无法获得它在 Swift.
下编译这是我所拥有的,假设 path
包含一个可能存在的钥匙串的路径:
let pathName = (path as NSString).UTF8String
var keychain: Unmanaged<SecKeychain>?
var status = withUnsafeMutablePointer(&keychain) { pointer in
SecKeychainOpen(pathName, pointer)
}
if status != errSecSuccess {
status = withUnsafeMutablePointer(&keychain) { pointer in
SecKeychainCreate(pathName, UInt32(0), nil, false, nil, pointer)
}
}
编译器抱怨 SecKeychainCreate 调用中的类型,但是,我不明白我做错了什么。
Cannot invoke 'withUnsafeMutablePointer' with an argument list of type '(inout Unmanaged<SecKeychain>?, (_) -> _)'
如果我稍微修改第二个闭包,我会得到这个编译器错误:
Cannot invoke 'SecKeychainCreate' with an argument list of type '(UnsafePointer<Int8>, UInt32, nil, Bool, nil, (UnsafeMutablePointer<Unmanaged<SecKeychain>?>))'
感谢所有建议。
SecKeychainCreate()
的 promptUser
参数具有类型
Boolean
,它是 "Mac OS historic type" 和 UInt8
的别名,
所以它不同于Swift 1.2中的Swift Bool
。
(比较 Type 'Boolean' does not conform to protocol 'BooleanType' 的类似问题。)
这意味着你必须
通过 Boolean(0)
而不是 false
:
SecKeychainCreate(pathName, UInt32(0), nil, Boolean(0), nil, pointer)
补充说明:
withUnsafeMutablePointer()
不需要,可以传&keychain
到钥匙串功能。(path as NSString).UTF8String
不需要,可以传一个Swift 字符串到需要const char *
参数的 C 函数, 比较 String value to UnsafePointer<UInt8> function parameter behavior.- 只允许将
nil
作为密码传递给SecKeychainCreate()
如果promptUser
是TRUE
,否则会导致 "parameter error (-50)". SecKeychainOpen()
即使钥匙串文件不成功 存在。根据文档,您必须检查SecKeychainGetStatus()
。或者,您可以尝试创建 首先是钥匙串文件,例如 Open Local Items Keychain?.
一起:
let path = "/path/to/my.keychain"
var keychain: Unmanaged<SecKeychain>?
var status = SecKeychainCreate(path, 0, "", Boolean(0), nil, &keychain)
if status == OSStatus(errSecDuplicateKeychain) {
status = SecKeychainOpen(path, &keychain)
}
从 Swift 2 / Xcode 7 beta 5 开始, Mac 类型 Boolean
被映射
到 Swift 为 Bool
,钥匙链功能不再 return
非托管对象:
let path = "/path/to/my.keychain"
var keychain: SecKeychain?
var status = SecKeychainCreate(path, 0, "", false, nil, &keychain)
if status == OSStatus(errSecDuplicateKeychain) {
status = SecKeychainOpen(path, &keychain)
}