SecAccessControlCreateWithFlags () in Swift
I am trying to call a function in Security.framework from swift code. Forgetting the "error" (last) parameter in a second if I call the function like this:
let accessControlRef = SecAccessControlCreateFlags(
kCFAllocatorDefault,
kSecAttrAccessibleWhenUnlockedThisDeviceOnly,
SecAccessControlCreateFlags.UserPresence,
nil
)
I am getting the following error:
Cannot find an initializer for type SecAccessControlCreateFlags that takes a list of arguments of type '(CFAllocator !, CFStringRef, SecAccessControlCreateFlags, nil)'
... however, if I reformat my code to the following:
let allocator:CFAllocatorRef! = kCFAllocatorDefault
let protection:AnyObject! = kSecAttrAccessibleWhenUnlockedThisDeviceOnly
let flags:SecAccessControlCreateFlags = SecAccessControlCreateFlags.UserPresence
let accessControlRef = SecAccessControlCreateWithFlags(
allocator,
protection,
flags,
nil
)
(the specific types - for example CFAllocatorRef
- are taken from the Xcode autocomplete function prototype) ... it compiles without issue. What's happening?
Next, the error parameter . What should I go through? While migrating my Objective-C code, I am tempted to pass the following variable (e.g. c &
):
var accessControlError:CFErrorRef! = nil
... which gives an error:
Unable to call "SecAccessControlCreateWithFlags" with an argument list of type (CFAllocatorRef !, AnyObject !, SecAccessControlCreateFlags, inout CFErrorRef!) '
If instead I pass in the following variable (again added with an operator-address):
var accessControlError:UnsafeMutablePointer<Unmanaged<CFError>?>
(same type as autocomplete prototype) I get:
Cannot call "SecAccessControlCreateWithFlags" with argument list of type (CFAllocatorRef !, AnyObject !, SecAccessControlCreateFlags, inout UnsafeMutablePointer?>) '
... so what gives?
EDIT: Forget the error. I seem to be taking the address twice (i.e. Pointer to Pointer). Instead, I have to do this:
var accessControlError:UnsafeMutablePointer<Unmanaged<CFError>?> = nil
// ^ Already a 'pointer'
let allocator:CFAllocatorRef! = kCFAllocatorDefault
let protection:AnyObject! = kSecAttrAccessibleWhenUnlockedThisDeviceOnly
let flags:SecAccessControlCreateFlags = SecAccessControlCreateFlags.UserPresence
let accessControlRef = SecAccessControlCreateWithFlags(
allocator,
protection,
flags,
accessControlError // <- Notice the lack of '&'
)
Source: sample code in this answer .
source to share
(Ok, so nobody added new ideas, so I'll answer my own question with the content of my last edit :)
ANSWER: Forget the error parameter. I seem to be taking the address twice (i.e. pointer to pointer). Instead, I have to do this:
let accessControlError:UnsafeMutablePointer<Unmanaged<CFError>?> = nil
// ^ Already a 'pointer'
let allocator:CFAllocator! = kCFAllocatorDefault
let protection:AnyObject! = kSecAttrAccessibleWhenUnlockedThisDeviceOnly
let flags:SecAccessControlCreateFlags = SecAccessControlCreateFlags.userPresence
let accessControlRef = SecAccessControlCreateWithFlags(
allocator,
protection,
flags,
accessControlError // <- Notice the lack of '&'
)
source to share