Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Where best to call updateApplicationContext using Watch Connectivity?

Several of the good blog posts detailing Watch Connectivity (http://www.kristinathai.com/watchos-2-tutorial-using-application-context-to-transfer-data-watch-connectivity-2/ and http://natashatherobot.com/watchconnectivity-application-context/) use simple app examples that send data to the watch when you tap on UI on the iPhone.

My app simply lists the data from my iPhone app, so I don't need to send data immediately, I just wanted to send it when the app loads or enters background...to this end I've made the updateApplicationContext in didFinishLaunching and didEnterBackground...however my dataSource delegate in my watch interface controllers are very spotting at getting triggered...particularly the glance only loads on the simulator and never on device. Is there a better time and place to push the info?

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
    WatchSessionManager.sharedManager.startSession()      
    do {
         try WatchSessionManager.sharedManager.updateApplicationContext(["peopleDict" : peopleDict])                                        
    } catch {
        print(error)
    }
     return true
}

func applicationDidEnterBackground(application: UIApplication) {     
     do {
         try WatchSessionManager.sharedManager.updateApplicationContext(["peopleDict" : peopleDict])                                      
     } catch {
         print(error)
     }
}

below is my WatchSessionManager I used to call activiateSession in my extensionDelegate's appliciationDidFinishLaunching

import WatchConnectivity

protocol DataSourceChangedDelegate {
    func dataSourceDidUpdate(dataSource: DataSource)
}


class WatchSessionManager: NSObject, WCSessionDelegate {

    static let sharedManager = WatchSessionManager()
    private override init() {
        super.init()
    }

    private var dataSourceChangedDelegates = [DataSourceChangedDelegate]()

    private let session: WCSession = WCSession.defaultSession()

    func startSession() {
        session.delegate = self
        session.activateSession()
    }

    func addDataSourceChangedDelegate<T where T: DataSourceChangedDelegate, T: Equatable>(delegate: T) {
        dataSourceChangedDelegates.append(delegate)
    }

    func removeDataSourceChangedDelegate<T where T: DataSourceChangedDelegate, T: Equatable>(delegate: T) {
        for (index, indexDelegate) in dataSourceChangedDelegates.enumerate() {
            if let indexDelegate = indexDelegate as? T where indexDelegate == delegate {
                dataSourceChangedDelegates.removeAtIndex(index)
                break
            }
        }
    }
}

// MARK: Application Context
// use when your app needs only the latest information
// if the data was not sent, it will be replaced
extension WatchSessionManager {

    // Receiver
    func session(session: WCSession, didReceiveApplicationContext applicationContext: [String : AnyObject]) {

        dispatch_async(dispatch_get_main_queue()) { [weak self] in
            self?.dataSourceChangedDelegates.forEach { $0.dataSourceDidUpdate(DataSource(data: applicationContext))}
        }

    }
}
like image 640
GarySabo Avatar asked Oct 21 '15 19:10

GarySabo


1 Answers

As updateApplicationContext only stores the newest application context you can update it whenever you like. The watch will only get the newest data. There is no queue with old contexts.

On the watch side the most secure location to activate the session and set the WCSessionDelegate is in the ExtensionDelegate init method:

class ExtensionDelegate: NSObject, WKExtensionDelegate {

    override init() {
        super.init()
        WatchSessionManager.sharedManager.startSession()
    }
    ...
}

Your Glance does not update because when the Glance is shown, applicationDidFinishLaunching is not being called (because the watch app is not launched when only the Glance is launched)

like image 63
joern Avatar answered Sep 16 '22 20:09

joern