1
votes

my aim is to update a clock kit complication through the following steps:

  1. complication triggers ExtensionDelegate to sendMessage to AppDelegate in order to wake up the parent IOS app

  2. iOS app will then download / XML parse data

  3. AppDelegate will transfer data via transferCurrentComplicationUserInfo to ExtensionDelegate

  4. ExtensionDelegate passes on to Complication Controller

This all works when iOS app is running / active in foreground. It does not work when the app is not started.

Is there any setting I need to set? (already have setup in info.plist for background download) Please in Swift.

Added additional information:

In above scenario (ComplicationControllor regular / scheduled update request through ExtensionDelegate), waking the IOS app via WCSession sendMessage does not work.

I see the same problem when I start the app on apple watch (InterfaceController triggers in ViewDidLoad the ExtensionDelegate) to wake the parent app.

In both cases the message is being sent, but no reaction from IOS app if not in foreground.

With the very same code that above "automated" request scenarios use, I also implemented a button (to trigger manually for test purpose). if button is pressed on the watch, it sometimes works (ViewController through same function in ExtensionDelegate sends message to AppDelegate, this one wakes and replies). I am though unable to find a pattern.

As it uses the very same ExtenstionDelegate function, as in all scenarios the message is being sent, it is beyond my comprehension why only when manually triggered a response is received / wake of parent app is successful.

here the code from the ExtensionDelegate (which is called by ComplicationController, InterfaceController-ViewDidLoad as well as by mentioned button:

func sendMessage(){
            let session = WCSession.defaultSession()
            let applicationData = ["wake":"wakeUp"]
            session.sendMessage(applicationData, replyHandler: {replyMessage in
                }, errorHandler: {(error ) -> Void in
                    print("no reply message from phone")
            })
        }

and the AppDelegate:

func session(session: WCSession, didReceiveMessage message: [String : AnyObject], replyHandler: ([String : AnyObject]) -> Void) {
    let receivedMessage = message["wake"] as! String
    if receivedMessage == "wakeUp" {
        let applicationDict = ["wake": "nowAwake"]
        replyHandler(applicationDict as [String : String])
    }
    self.loadData()
}

func loadData(){

    ... code to load data

    dispatch_async(dispatch_get_main_queue()) { () -> Void in
        let dictionaryComplication = [...]

        if WCSession.isSupported() {

            let session = WCSession.defaultSession()
            if session.watchAppInstalled {
                do {
                    session.transferCurrentComplicationUserInfo(dictionaryComplication)
                    try session.updateApplicationContext(dictionaryContext)


                } catch {
                    print("ERROR: \(error)")
                }
            }

        }
    }
}
1

1 Answers

0
votes

Make sure you activate the WCSession in your ExtensionDelegate's init method and not in applicationDidFinishLaunching:

class ExtensionDelegate: NSObject, WKExtensionDelegate {

    override init() {
        super.init()
        if WCSession.isSupported() {
            let session = WCSession.defaultSession()
            session.delegate = self
            session.activateSession()
        }
    }
    ...
}

applicationDidFinishLaunching is only called when the user start the WatchApp, but not when a Complication requests new data.