Search code examples
watchosapple-watch-complication

activeComplications of the CLKComplicationServer are nil, although a complication is displayed


I have a watch app with complications. Updating the complication on a watch face did work for a long time, but stopped recently, maybe due to a watchOS update.
The reason is that the activeComplications property of the CLKComplicationServer.sharedInstance() is nil, although my complication placeholder is shown on the watch face (device & simulator).

The code could not be simpler:

final class ComplicationController: NSObject, CLKComplicationDataSource {
// …
    func updateComplications() {
//…
        let complicationServer = CLKComplicationServer.sharedInstance()
        if let activeComplications = complicationServer.activeComplications {
            for complication in activeComplications {
                complicationServer.reloadTimeline(for: complication)
            }
        }
//…
  }
//…
}  

If I stop at a breakpoint at the if let instruction, complicationServer has the following values:

enter image description here

And the following lldb command outputs nil:
enter image description here

What could be the reason?


Solution

  • My bad: I solved the problem 4 years ago, but forgot the solution during refactoring of the app.
    Actually I don’t know if this is a solution, a workaround or a hack:

    I suspect that the CLKComplicationServer or its CLKComplicationDataSource, i.e. the ComplicationController, is not correctly initialized if ComplicationController.shared is executed anywhere in the code. If not, the ComplicationController is correctly initialized by the CLKComplicationServer.

    Therefore, one cannot call any function in the ComplicationController, e.g. to update complications. Instead one can send a notification to the ComplicationController that executes the requested function. Of course, one has to ensure that the ComplicationController is already initialized and registered to receive such a notification before it is posted.
    If so, CLKComplicationServer.sharedInstance().activeComplications is no longer nil, and the complication update works.