0

I'm using WatchConnectivity to send a simple dictionary from an iPhone to Apple Watch.

On the Apple Watch side, to get around the fact that contexts may not be queued when the app is opened, the last received data is saved to UserDefaults and retrieved if there is nothing in the queue when setting up my WatchKit table. I have implemented this in another WatchKit app and everything worked somewhat fine, but in this one data is never received by the Watch.

I've only tried it in the simulator because my app spins for eternity on my Watch and never loads (the loading screen looks like a WatchOs 1 screen?). The WatchConnectivity framework is included in each product (Extension and iPhone app). Thanks for your help.

Here's the iPhone code (implemented in a ViewController):

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.

    if ([WCSession isSupported]) {
        WCSession *session = [WCSession defaultSession];
        session.delegate = self;
        [session activateSession];
    }
}

- (void)viewDidAppear:(BOOL)animated {
    NSDictionary *toPass = [[NSDictionary alloc] initWithObjectsAndKeys:AppDelegate.profiles,@"profiles", nil];
    [[WCSession defaultSession] updateApplicationContext:toPass error:nil];
    NSLog(@"sent data");
    [self.tableView reloadData];
}

And the Apple Watch Code:

- (void)awakeWithContext:(id)context {
    [super awakeWithContext:context];
    // Configure interface objects here.
    self.profiles = [[NSMutableArray alloc] init];

    if ([WCSession isSupported]) {
        WCSession *session = [WCSession defaultSession];
        session.delegate = self;
        [session activateSession];
    }

    [self setupTable];

}

- (void)session:(WCSession *)session didReceiveApplicationContext:(NSDictionary<NSString *,id> *)applicationContext {
    NSDictionary *receieved = [[NSDictionary alloc] init];
    receieved = applicationContext;

    NSMutableArray *profiles = [[NSMutableArray alloc] init];
    profiles = [receieved objectForKey:@"profiles"];

    self.profiles = [[NSMutableArray alloc] init];
    self.profiles = profiles;

    NSData *arrayData = [NSKeyedArchiver archivedDataWithRootObject:self.profiles];

    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    [defaults setObject:arrayData forKey:@"bookmarks"];

    [self setupTable];
    NSLog(@"new");
}

- (void)setupTable {

    ...
    After some setup code

    if (self.profiles.count == 0) {
        NSLog(@"Nothing in the queue, checking defaults");
        NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
        NSData *got = [defaults objectForKey:@"bookmarks"];
        NSLog(@"Got Defaults!");
        self.profiles = [[NSMutableArray alloc] init];
        self.profiles = [NSKeyedUnarchiver unarchiveObjectWithData:got];
    }

    ...
    More setup code later
}
ipinak
  • 5,739
  • 3
  • 23
  • 41
Alex Wulff
  • 2,039
  • 3
  • 18
  • 29

1 Answers1

0

Change this line:

[[WCSession defaultSession] updateApplicationContext:toPass error:nil];

To be:

NSError *error = nil;
If (![[WCSession defaultSession] updateApplicationContext:toPass error:&error]) {
    NSLog(@"error: %@", error);
}

And I bet you'll see you are getting an error returned!

Also, what type of objects does AppDelegate.profiles contain?

ccjensen
  • 4,578
  • 2
  • 23
  • 25
  • Aha! Good call - it's saying that "Payload contains unsupported type". It's an array of custom objects with two NSString properties. Will archiving the array as NSData NSKeyedArchiver work? – Alex Wulff Jan 02 '16 at 15:05
  • That will work, though the apple engineers, during the WatchConnectivity WWDC talk, specifically recommended not using NSKeyedArchiver as it is not optimized for space efficiency. – ccjensen Jan 02 '16 at 15:54
  • One solution would be to convert the custom objects to dictionaries containing mapping a of variable name => nsstring – ccjensen Jan 02 '16 at 15:55
  • Thanks for your help, that's very good to know about space optimization. I think I'll map it out as NSDictionaries before sending. – Alex Wulff Jan 02 '16 at 17:22