Search code examples
iosobjective-ciphoneparse-platformwatchkit

If Watch app opens before iPhone app runs, no data is populated


I'm running into a problem where if I run my app in the Watch Simulator before the iPhone Simulator, there is no data in the Watch app.

This is because I get the Watch data from the iPhone app (where I query Parse and save the results to the Group Defaults where the Watch can access it), since from what I believe we have been told there is no way to run this sort of function in the Watch app (extension).

Am I incorrect about that?

How am I supposed to populate the Watch app the first time it runs, if the iPhone app has not run yet?

iPhone TableViewController.m:

- (void)viewDidLoad {
    PFQuery *query = [self queryForTable];
    // ... Query Parse to find data, then save it App Group...
    NSString *container = @"group.com.me.off";
    NSUserDefaults *defaults = [[NSUserDefaults alloc] initWithSuiteName:container];
    // ... finish saving to App Group
}

Watch `InterfaceController.m':

- (void)awakeWithContext:(id)context {
    [super awakeWithContext:context];
    // Initialize Parse.
    [Parse setApplicationId:@"xxx"
                  clientKey:@"xxx"];

    // GMT Date from Phone
    NSDate *gmtNow = [NSDate date];
    NSLog(@"GMT Now: %@", gmtNow);

    // Query Parse
    PFQuery *query = [PFQuery queryWithClassName:@"na"];

    [query whereKey:@"dateGame" greaterThanOrEqualTo:gmtNow];

    [query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
        if (!error) {
            NSMutableArray *localMatchup = [@[] mutableCopy];

            for (PFObject *object in objects) {
                // Add objects to local Arrays
                [localMatchup addObject:[object objectForKey:@"matchup"]];

                // App Group
                NSString *container = @"group.com.me.off";
                NSUserDefaults *defaults = [[NSUserDefaults alloc] initWithSuiteName:container];

                // Matchup
                [defaults setObject:localMatchup forKey:@"KeyMatchup"];
                NSArray *savedMatchup = [defaults objectForKey:@"KeyMatchup"];
                NSLog(@"Default Matchup: %@", savedMatchup);
                savedMatchup = self.matchupArray;
            }
            dispatch_async(dispatch_get_main_queue(), ^{
                NSLog(@"Say you went to dispatch");
            });   
        }
    }];

    // App Group
    NSString *container = @"group.com.me.off";
    NSUserDefaults *defaults = [[NSUserDefaults alloc] initWithSuiteName:container];

    // Matchup
    NSArray *savedMatchup = [defaults objectForKey:@"KeyMatchup"];
    self.matchupArray = savedMatchup;
}

- (void)willActivate {
    [super willActivate];

    // Hide "No Games" Label
    if ([self.matchupArray count] > 0) {

        self.noGamesLabel.hidden = YES;
        self.rowTable.hidden = NO;

        [self.rowTable setNumberOfRows:[self.matchupArray count] withRowType:@"rows"];

        for (NSInteger index = 0; index < [self.timeArray count]; index++) {
            // Matchup
            NSString *matchupString = [self.matchupArray objectAtIndex:index];
            RowController *controller = [self.rowTable rowControllerAtIndex:index];
            [controller.matchupLabel setText:matchupString];
        }
    }
    // Show "No Games" Label
    else {
        self.rowTable.hidden = YES;
        self.noGamesLabel.hidden = NO;
    }  
}

Solution

  • You can query Parse from you extension and you can write to the group defaults. Your extension can make URL requests just like your iOS app. You will want to be careful to not block the main thread while the query is running. You will need to have some initial UI to show the user you are querying for initial data so that the app doesn't look frozen.