Seddiki Anass Seddiki Anass - 4 months ago 30
Swift Question

withUnsafeMutablePointer doesn't compile

I've been struggling on an issue for some time now. I'm wondering why this code :

private func generateIdentity (base64p12 : String, password : String?, url : NSURL) {

let p12KeyFileContent = NSData(base64EncodedString: base64p12, options: NSDataBase64DecodingOptions(rawValue: 0))
if (p12KeyFileContent == nil) {
NSLog("Cannot read PKCS12 data")
return
}

let options = [String(kSecImportExportPassphrase):password ?? ""]
var citems: CFArray? = nil
let resultPKCS12Import = withUnsafeMutablePointer(&citems) { citemsPtr in
SecPKCS12Import(p12KeyFileContent!, options, citemsPtr)
}
if (resultPKCS12Import != errSecSuccess) {
print(resultPKCS12Import)
return
}

let items = citems! as NSArray
let myIdentityAndTrust = items.objectAtIndex(0) as! NSDictionary
let identityKey = String(kSecImportItemIdentity)

identity = myIdentityAndTrust[identityKey] as! SecIdentityRef
hasCertificate = true
print("cert cre", identity)
}


compiles, whereas this other one not :

private func generateIdentity (base64p12 : NSData, password : String?) {
let p12KeyFileContent = NSData(data: base64p12)

let options = [String(kSecImportExportPassphrase):password ?? ""]
var citems: CFArray? = nil
let resultPKCS12Import = withUnsafeMutablePointer(&citems) { citemsPtr in // line with the error
SecPKCS12Import(p12KeyFileContent!, options, citemsPtr)
}
if (resultPKCS12Import != errSecSuccess) {
print(resultPKCS12Import)
return
}

let items = citems! as NSArray
let myIdentityAndTrust = items.objectAtIndex(0) as! NSDictionary
let identityKey = String(kSecImportItemIdentity)

identity = myIdentityAndTrust[identityKey] as! SecIdentityRef
hasCertificate = true
print("cert cre", identity)
}


XCode tells me that :


Cannot convert value of type 'inout CFArray?' (aka 'inout Optional') to expected argument type 'inout _'


I really don't see how the 2 codes are different for the citems variable because what I basically just did was to use a NSData argument for the function, thus bypassing base64 string conversion to NSData.

Answer

The error message is super-confusing, but the cause of the error resides here:

SecPKCS12Import(p12KeyFileContent!, options, citemsPtr)

In your second example, with declaring let p12KeyFileContent = NSData(data: base64p12), the type of p12KeyFileContent is NSData, not NSData?. So, you cannot use ! for p12KeyFileContent.

Try changing the line as:

SecPKCS12Import(p12KeyFileContent, options, citemsPtr)

(! removed.)


One more.

You usually have no need to use withUnsafeMutablePointer to call SecPKCS12Import.

Try replacing these 3 lines (in your second example):

let resultPKCS12Import = withUnsafeMutablePointer(&citems) { citemsPtr in // line with the error
    SecPKCS12Import(p12KeyFileContent!, options, citemsPtr)
}

with this:

let resultPKCS12Import = SecPKCS12Import(p12KeyFileContent, options, &citems)

The first example code can be rewritten as well.

Comments