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.
(OK, so nobody has added any new insights in a while, so I will answer my own question with the contents of my last edit:)
ANSWER: Forget about the error parameter. I seems I am taking the address twice (i.e., pointer to a pointer). Instead, I should 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 '&'
) 
                        If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With