Search code examples
iosswiftclosuresarchivingzipzap

How to make an ((NSErrorPointer -> NSData!)!) closure in Swift


I'm trying to use the ZipZap method

ZZArchiveEntry(fileName: String!, compress: Bool, dataBlock: ((NSErrorPointer) -> NSData!)!)

in Swift, but can't figure out the right syntax for the dataBlock closure. I tried the following code:

let fileEntry = ZZArchiveEntry(fileName: "test.txt", compress: true, dataBlock: {
            (error: NSErrorPointer) in
            return "test".dataUsingEncoding(NSUTF8StringEncoding)!
        })

which leads to the following error:

Cannot find an initializer for type 'ZZArchiveEntry' that accepts an argument list of type '(fileName: String, compress: Bool, dataBlock: (NSErrorPointer) -> _)'

Are such closures possible, and if yes, how in Xcode 7.0 beta 3?


Solution

  • You are returning an unwrapped optional NSData (i.e. you're returning a non-optional) and the compiler is just getting confused.

    You can resolve it by staging the value in a variable:

    let fileEntry = ZZArchiveEntry(fileName: "test.txt", compress: true, dataBlock: {
        (error: NSErrorPointer) in
        let data = "test".dataUsingEncoding(NSUTF8StringEncoding)!
        return data
    })
    

    Or, because expected return type of that closure is an optional, if you remove that !, the error goes away:

    let fileEntry = ZZArchiveEntry(fileName: "test.txt", compress: true, dataBlock: {
        (error: NSErrorPointer) in
        return "test".dataUsingEncoding(NSUTF8StringEncoding)
    })
    

    Or, as others have pointed out, you can simplify this further:

    let fileEntry = ZZArchiveEntry(fileName: "test.txt", compress: true) { error in
        return "test".dataUsingEncoding(NSUTF8StringEncoding)
    }