I am trying to call a function in the Security.framework, from swift code. Forgetting about the "error out" (last) parameter for a second, if I call the function like this:
let accessControlRef = SecAccessControlCreateFlags(
kCFAllocatorDefault,
kSecAttrAccessibleWhenUnlockedThisDeviceOnly,
SecAccessControlCreateFlags.UserPresence,
nil
)
I ge tht efollowing error:
Cannot find an initializer for type 'SecAccessControlCreateFlags' that accepts an argument list 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
)
(specific types -e.g., CFAllocatorRef
- taken from function prototype on Xcode's autocomplete)...it compiles with no problem. What's going on?
Next, the error parameter. What should I pass? Migrating my Objective-C code, I am tempted to pass the following variable (prepended with &
, of course):
var accessControlError:CFErrorRef! = nil
...which gives the error:
Cannot invoke 'SecAccessControlCreateWithFlags' with an argument list of type '(CFAllocatorRef!, AnyObject!, SecAccessControlCreateFlags, inout CFErrorRef!)'
If, instead, I pass the following variable (again, prepended with the address-of operator):
var accessControlError:UnsafeMutablePointer<Unmanaged<CFError>?>
(Same type as suggested by prototype autocomplete), I get:
Cannot invoke 'SecAccessControlCreateWithFlags' with an argument list of type '(CFAllocatorRef!, AnyObject!, SecAccessControlCreateFlags, inout UnsafeMutablePointer?>)'
...so, what gives?
EDIT: Forget about the error parameter. I seems I am taking the address twice (i.e., pointer to a pointer). Instead, I should 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 within this answer.