Search code examples
ioswatchkitwatchos-2watchconnectivitywcsession

WatchConnectivity transferUserInfo not working when watch app terminated


As I read the doc, transferUserInfo is a queued process of 1, and the latest data will surely reach the watch sandbox.

This is the code on the iOS app:

-(void)sendViaTransferUserInfo {
    NSDictionary *weatherData = [[NSDictionary alloc] initWithObjectsAndKeys:
                                     self.cityName, @"City",
                                     self.tempCelciusStr, @"Temp",
                                     nil];

    WCSession *session = [WCSession defaultSession];
    [session transferUserInfo:weatherData]; 
}

If the iOS app and the watch app are both active, this works all the time.

But when I close the watch app, then call this method again from the iOS app, wait a few seconds and then open the watch app again, the watch delegate didReceiveUserInfo: is not being triggered at all.

Do I correctly understand transferUserInfo: usage? Can anybody explain why the delegate is not being called on the watch app?


Solution

  • As I read the doc, transferUserInfo is a queued process of 1,

    No, its possible to queue multiple user info transfers, and each will be received in the order that it was delivered.

    What you're describing is updateApplicationContext. Only one context can be queued, and the most recent context replaces any previously received one.

    and the latest data will surely reach the watch sandbox.

    No, transfers will only complete if the session is active. Transfers will fail with an error if the session is inactive.

    This is why the delegate did not get called on the watch side, as your watch app did not receive any data. The transfer failed on the phone side before sending, and nothing actually was transferred to the watch.

    How to resolve the issues:

    • Check the activationState before transferring any data. Only attempt to transfer data when the session is active.

      Check the value of this property before attempting to transfer data or files using the methods of this object. When the value is WCSessionActivationStateActivated you may initiate the transfer of data and files normally. If it is any other value, do not initiate any transfers.

    • Use session(_:didFinishUserInfoTransfer:error:) to determine if the transfer succeeded.

      The session object calls this method when a data transfer initiated by the current app finished, either successfully or unsuccessfully. Use this method to note that the transfer completed or to respond to errors, perhaps by trying to send the data again at a later time.