Has anyone been able to get transferCurrentComplicationUserInfo to work?

Has anyone been able to get transferCurrentComplicationUserInfo to do anything? I call it from the parent iPhone app, and the complication doesn't wake up or call the extension delegate method didReceiveUserInfo like it's supposed to.

Replies

this should work fine. Please provide some code snippets or file a radar so that we can take a look (reply with radar number if you file one).

It was working really well for me until I went from the developer GM 2.0 build to the official public 2.0 build where it stopped working.


didReceiveUserInfo never gets called if the Watch App isn't running in the foreground. As soon as I background it, it fails to get called.


I've checked this with the debugger attached to the Watch and iPhone Apps. As soon as I bring my Watch App into the foreground all the calls come through as if they were queued up with all the normal userinfo updates.



iPhone App side snippet

    func updateComplication() {
        let session = WCSession.defaultSession()
        guard session.paired && session.watchAppInstalled else {return} // nothing to do if not paired and installed

        var watchComplication = WatchComplication() // Helper class to hold data and convert into deictionary

        NSLog("Sending complication data to watch %@", watchComplication.description())

        WCSession.defaultSession().transferCurrentComplicationUserInfo(watchComplication.getRaw())
    }


Watch App snippet

func session(session: WCSession, didReceiveUserInfo userInfo: [String : AnyObject]) {
        NSLog("UserInfo recieved from iPhone\n%@", userInfo.description)
      
        let theComplication = WatchComplication(withData: userInfo)
      
        let complicationServer = CLKComplicationServer.sharedInstance()
        for complication in complicationServer.activeComplications {
            complicationServer.reloadTimelineForComplication(theComplication)
        }
    }


WCSession is started by a singleton that most controllers keep a reference to. The Extension Delegate holds a reference as well as the ComplicationController

e.g.

class ExtensionDelegate: NSObject, WKExtensionDelegate {
   
    private var sessionManager :SessionManager = sessionManager.sharedInstance

...

This all sounds good. I'm guessing you've verified that your app's complication is active on the watch face?


The other option I could think of is maybe your complication used up all its budget for today. If your complication was out of budget, you should have seen a call to the CLKComplicationDataSource's requestedUpdateBudgetExhausted: just prior to it starting to not get delivered immediately; did you?


If neither of those, filing a bug report with an attached sample project where this reproduces, and replying with the number here, is probably the best next course of action.

Thanks for the reply.


I have been playing around with the code and have found what I beleive is the issue.


I use a singleton which is responsible for activating the WCSession and handling all the delegate calls. When it gets updates from the iPhone App it persists them and provides a means for the complication and Watch App to view the latest information.


The singleton reference is used in most places including the Extension Delegate, but also in the ComplicationController where it was instantiated as a top level var. It seems that the ComplicationController is the first to be instantiated on Watch App launch and causes my singleton to activate the WCSession. If I remove this top level var and grab the singleton in the delegate functions of my ComplicationController as needed then the ExtensionDelegate is the first to cause WCSession to be activated and it all works fine again!


e.g. I went from this


class ComplicationController: NSObject, CLKComplicationDataSource {
    let sessionManager = SessionManager.sharedInstance // <-- Removed this line and it all works!
...


and instead grabed it when needed like this

func getTimelineStartDateForComplication(complication: CLKComplication, withHandler handler: (NSDate?) -> Void) {
     let sessionManager = SessionManager.sharedInstance
...


In summarry, the bug was accidentally activating the WCSession in the ComplicationController, when I assumed the first to activate it would be the ExtensionDelegate.