Deepak Sharma
Deepak Sharma

Reputation: 6487

Swift closure with multiple params

I am trying to define a Swift closure with two arguments but it is throwing compilation errors. What am I doing wrong?

 var processor: (CMSampleBuffer, CVPixelBuffer) throws -> Void { (sampleBuffer, outputPixelBuffer) in
    ....
}

EDIT: An = was missing which was correctly pointed out in the comments. But now I am trying to pass this closure as a param and it is giving compilation errors in declaration:

 func process(_ processor: ((_ sampleBuffer: CMSampleBuffer,  toPixelBuffer:CVPixelBuffer) throws)? = nil) {


 }

Upvotes: 0

Views: 519

Answers (2)

OOPer
OOPer

Reputation: 47896

Function Type needs to be written in this syntax:

( ArgumentList ) throws -> ResultType

(Simplified, you can find a full description in the link above.)

The keyword throws is optional according to your requirement, but -> ResultType is required even if the ResultType is Void.

And ArgumentList cannot have parameter labels, you need to use _ as parameter label when you want to show parameter names for readability.

So, your process(_:) should be something like this:

func process(_ processor: ((_ sampleBuffer: CMSampleBuffer,  _ toPixelBuffer: CVPixelBuffer) throws -> Void)? = nil) {
    //...
}

Or else, if you define a typealias for the parameter type, you can rewrite it as follows:

typealias ProcessorType = (_ sampleBuffer: CMSampleBuffer,  _ toPixelBuffer: CVPixelBuffer) throws -> Void

func process(_ processor: ProcessorType? = nil) {
    //...
}

One more, when you ask something about compilation errors, it is strongly recommended to show whole error message.

You can find a copyable text through the Report Navigator in the Navigator pane (in the Left side of Xcode).

Upvotes: 1

Lucas van Dongen
Lucas van Dongen

Reputation: 9858

So the following code seems to pass in a Playground:

func process(_ processor: ((String, String))? = nil) {

}

I am pretty sure the main problem is that you want to force throws as a keyword. I don't think that's possible in any way, I would rather propose to use a Result enum pattern that looks more or less like this:

enum ProcessResult {
    case success(someReturnValue: YourType) // Or no associated value if you just want to know it worked
    case failed(anError: Error)
}

By requiring the block to return a ProcessResult you can enforce something you might use a try/catch for in other languages.

Upvotes: 1

Related Questions