0

I have a button that calls this function and also calls performSegueWithIdentifier. Segue occurs before the data is the two query returns data. How do i get round this?

-(void)recommendSomeone {
    NSString *currentUserID = [NSString stringWithFormat:@"%@%@",@"KU",self.liaResponse[@"id"]];
    CKContainer *myContainer  = [CKContainer defaultContainer];
    CKDatabase *publicDatabase = [myContainer publicCloudDatabase];
    CKRecordID *currentUserRecordID = [[CKRecordID alloc] initWithRecordName:currentUserID];
    CKReference *recordToMatch = [[CKReference alloc] initWithRecordID:currentUserRecordID action:CKReferenceActionNone];

    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"contactList CONTAINS %@",recordToMatch];
CKQuery *query = [[CKQuery alloc] initWithRecordType:@"knotworkGhostUsers" predicate:predicate];
[publicDatabase performQuery:query inZoneWithID:nil completionHandler:^(NSArray *results, NSError *error) {
    if (error) {
        // Error handling for failed fetch from public database
        NSLog(@"error querying knotwork users %@", error);
    }
    else {
        // Display the fetched records
        self.randomGhostUser = results[arc4random_uniform([results count])];
        NSLog(@"this is the first name %@", self.randomGhostUser[@"firstname"]);
        NSLog(@"knotwork ghost users for current user data returned ordinary title %@",results);
        NSString* searchQuery = @" ";
        NSString *kuTitle = [self.randomGhostUser[@"title"] lowercaseString];
        NSArray *keyWords = @[@"developer",@"networking",@"sales manager",@"engineer",@"doctor",@"facility manager"];
        for(NSString* keyWord in keyWords){
            NSRange checkResult = [kuTitle rangeOfString:keyWord];
            if(checkResult.location != NSNotFound){
                searchQuery = [NSString stringWithFormat:@"%@%@%@",searchQuery,@" ",keyWord];
            }
        }

        NSPredicate *predicate = [NSPredicate predicateWithFormat:@"allTokens tokenmatches[cdl] %@ AND contactList CONTAINS %@",searchQuery,recordToMatch];
        CKQuery *query2 = [[CKQuery alloc] initWithRecordType:@"knotworkGhostUsers" predicate:predicate];
        [publicDatabase performQuery:query2 inZoneWithID:nil completionHandler:^(NSArray *response, NSError *error) {
            if (error) {
                // Error handling for failed fetch from public database
                NSLog(@"error querying knotwork users %@", error);
            }
            else {
                // Display the fetched records
                self.recommendedGhostUser = response;
                NSLog(@"knotwork users data returned after recom %@", self.recommendedGhostUser);
            } 
        }];
    }
    [self performSegueWithIdentifier:@"Recommend" sender:nil];

}];

} emphasized text

Christian
  • 22,585
  • 9
  • 80
  • 106
Johnson
  • 243
  • 3
  • 7
  • You seem to have forgotten to ask a question. – Elliott Frisch Feb 05 '15 at 17:39
  • Normally, you would pass the data in prepareForSegue. Have you tried to implement that? There are hundreds of answers on SO about passing data between controllers, you should do some searching. – rdelmar Feb 05 '15 at 17:44
  • I have tried passing the data to prepareForSegue. But the problem remains that prepareForSegue takes place before the data is fetched – Johnson Feb 05 '15 at 18:10
  • @ElliottFrisch i have included the question – Johnson Feb 05 '15 at 18:11

1 Answers1

0

You have to replace your segue and put it inside your second completion-block. Because otherwise your completion-block will be called after you already have pushed the segue.

[publicDatabase performQuery:query2 inZoneWithID:nil completionHandler:^(NSArray *response, NSError *error) {
            if (error) {
                // Error handling for failed fetch from public database
                NSLog(@"error querying knotwork users %@", error);
            }
            else {
                // Display the fetched records
                self.recommendedGhostUser = response;
                NSLog(@"knotwork users data returned after recom %@", self.recommendedGhostUser);
                //Put it in here
                [self performSegueWithIdentifier:@"Recommend" sender:nil];
            } 
        }];

Also you could use prepareForSegue to pass your value to the second controller:

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    // Set Segue name from storyboard
    if ([[segue identifier] isEqualToString:@"seguename"])
    {
        // Get reference to the destination view controller
        YourViewController *vc = [segue destinationViewController];

        // Pass any objects to the view controller here, like...
        [vc setMyObjectHere:object];
    }
}

(Link to segue-answer)

Community
  • 1
  • 1
Christian
  • 22,585
  • 9
  • 80
  • 106
  • Thank you. I need to pass the results from the first completion block and response from the second to the view controller I am segueing to. How do i do that? Even though i have passed the two to global variables; the global variables are empty outside the block – Johnson Feb 05 '15 at 19:22