3

I am trying to update my watchOS 2 app with complications to watchOS 3. Unfortunately I don't understand what I am doing wrong regarding the ComplicationController. I always get the following error (using Xcode 8 b6):

Type 'ComplicationController' does not conform to protocol 'CLKComplicationDataSource' Candidate has non-matching type '(CLKComplication, (CLKComplicationTimeTravelDirections) -> Void) -> ()'

Code:

class ComplicationController: NSObject, CLKComplicationDataSource {

    func getSupportedTimeTravelDirections(for complication: CLKComplication, withHandler handler: (CLKComplicationTimeTravelDirections) -> Void) {
        handler([.forward])
    }
...
}

I also tried:

handler(.forward)

Both approaches give me an error on watchOS 3 but work perfectly fine on watchOS 2 / Swift 2. Does someone have an idea what changed in Swift 3 regarding this function?

MikeB
  • 1,619
  • 2
  • 15
  • 27

2 Answers2

2

It's changed!

func getSupportedTimeTravelDirections(for complication: CLKComplication, withHandler handler: @escaping (CLKComplicationTimeTravelDirections) -> Void) {
    handler([.forward, .backward])
}

Notice the @escaping annotation.

Swift 3.0 requires us to explicitly label closures as 'escaping' if they are able to escape the scope of the function body - for example, if they can be copied off to a property.

ncke
  • 1,084
  • 9
  • 14
2

From the Xcode 8 beta 6 release notes:

Closure parameters are non-escaping by default, rather than explicitly being annotated with @noescape. Use @escaping to indicate that a closure parameter may escape.

If you created a new ComplicationController.swift project in Xcode 8 beta 6, the generated source code would now look like:

func getSupportedTimeTravelDirections(for complication: CLKComplication, withHandler handler: @escaping (CLKComplicationTimeTravelDirections) -> Void) {
    handler([.forward, .backward])
}

This change applies to every data source method that has a handler parameter.

  • 2
    *This change applies to every data source method that has a handler parameter*... can't underscore that enough. If you have trouble with errors like this, check the docs or the generated Swift interface for the header your API comes from. (Also, IIRC according to Hawking the only supported return from this method should be `.forward`.) – rickster Aug 22 '16 at 17:02