1

I'd like to extend the Document.close function to first run some of my own code when the completionHandler triggers before calling the completionHandler that was passed to the function by the user. So something like this:

override func close(completionHandler: ((Bool) -> Void)? = nil) {
    super.close(completionHandler: { (success) in
        // TODO: do something AFTER writeContents has completed

        // TODO: call completionHandler
    })
}

So far so good, but I'm not able to call the completionHandler that was passed to the function. Using completionHandler() causes the compiler to complain about Cannot call value of non-function type '((Bool) -> Void)?'. A few StackOverflow searches later it sounds like we have to use the @escaping annotation:

override func close(completionHandler: @escaping ((Bool) -> Void)? = nil) {
    super.close(completionHandler: { (success) in
        // TODO: do something AFTER writeContents has completed

        // TODO: call completionHandler
    })
}

but the compiler complains again: @escaping attribute only applies to function types. This leads us to other questions like Swift 3 optional escaping closure parameter, but we are not able to change the function definition because it's overriding an (Objective-C) system library.

Am I misunderstanding something? If not, is there a way to workaround this limitation?

TomTasche
  • 5,448
  • 7
  • 41
  • 67

1 Answers1

2

You can pass completion as below,

class Document: UIDocument {

    override func close(completionHandler: ((Bool) -> Void)? = nil) {
        let completion: ((Bool) -> Void)? = { success in
            print("I got \(success)")
            // TODO: do something AFTER writeContents has completed
            //....
            //....
            //....

            // TODO: call completionHandler
            completionHandler?(success)
        }
        super.close(completionHandler: completion)
    }
}
Kamran
  • 14,987
  • 4
  • 33
  • 51