Backward matching of the unlabeled trailing closure is deprecated... Any way to silence it, instead of stopping use of trailing closure?

Viewed 1458

Swift compiler today surprised me with new cool feature.. warning :

Backward matching of the unlabeled trailing closure is deprecated; label the argument with 'onSuccess' to suppress this warning

I use trailing closure syntax almost everywhere and I don't see where is the issue with this case.

Function is defined as this:

func send<Data>(operation: CSOperation<Data>, title: String, progress: Bool = true,
        canCancel: Bool = true, failedDialog: Bool = true, onInternetFailed: (() -> Void)? = nil,
        onSuccess: ((Data) -> Void)? = nil) -> CSProcess<Data> {}

It was called like this:

send(operation: model.server.downloadCensusDocument(), title: .page_thanks_confirmation_download) {
        documentController = UIDocumentInteractionController(url: $0.url)
        ...
    }

And compiler wants me to write it like this:

    send(operation: model.server.downloadCensusDocument(), title: .page_thanks_confirmation_download, onSuccess: {
        documentController = UIDocumentInteractionController(url: $0.url)
        ...
    })

Any way to silence it, instead of stopping use of trailing closure ?

1 Answers

As you're probably aware, the key new feature is that both the onInternetFailed: function and the onSuccess: parameter are now allowed to be trailing closures. Multiple trailing closures. The rule is that when you do that, the first one is not labeled and the others are labelled, with no comma. So:

send(....) {
    // onInternetFailed function body
} onSuccess: {
    // onSuccess function body
}

Okay, but then the problem here is: there are two optional trailing closures, so if you omit one, which one are you omitting?

You are assuming that you are omitting the first one. The compiler understands that you think that, and it permits this omission, but with a warning, temporarily, because eventually it will become illegal — or, to put it more technically, eventually it will be assumed that the omitted one is the second one.

To avoid the warning, therefore, you must include both closures.

So, I would now write

send(operation: model.server.downloadCensusDocument(),
    title: .page_thanks_confirmation_download) 
        {} onSuccess: {
             documentController = UIDocumentInteractionController(url: $0.url)
            //...
        }

That silences the warning and I don't think it looks too bad. Both closures trail, and the first one is just empty.

Related