Frage

I am trying to search through a list of reminders in order to check if a reminder exists. There is an option in the method to save the value of whether or not the reminder exists. I am using a block, and within the block, when the reminder is found, the new value is assigned to the reminderExists variable, like it is supposed to. However, when I enter the save if statement, the value of reminderExists has changed from what it was assigned in the block. I am stumped with this issue, and I have tried many changes to diagnose the problem, to no avail. Thanks for any help!

- (BOOL)checkForReminderWithTitle:(NSString *)reminderTitle saveChanges:(BOOL)save {

NSNumber *currentGardenCurrentReminders = currentGarden.reminders;
__block NSNumber *reminderExists = [NSNumber numberWithBool:NO];

if (eventStore == nil)
{
    eventStore = [[EKEventStore alloc] init];

    [eventStore requestAccessToEntityType:EKEntityTypeReminder completion:^(BOOL granted, NSError *error) {

        if (!granted)
            NSLog(@"Access to store not granted");
    }];
}


if (eventStore != nil) {

    NSPredicate *predicate = [eventStore predicateForIncompleteRemindersWithDueDateStarting:[NSDate distantPast] ending:[NSDate distantFuture] calendars:[NSArray arrayWithObject:[eventStore defaultCalendarForNewReminders]]];

    [eventStore fetchRemindersMatchingPredicate:predicate completion:^(NSArray *reminders) {
        for (EKReminder *reminder in reminders) {

            NSLog(@"%@", reminderTitle);

            if ([reminder.title isEqualToString:reminderTitle]) {

                reminderExists = [NSNumber numberWithBool:YES];
                NSLog(@"reminder exists");
                NSLog(@"after reminder exists is assigned to YES, value is %@", ([reminderExists boolValue]) ? @"True" : @"False");
                if ([reminderExists boolValue]) NSLog(@"reminder exists variable works");

                NSArray *alarms = reminder.alarms;

                EKAlarm *alarm = [alarms objectAtIndex:0];

                NSDateFormatter *nextReminderDateFormatter = [[NSDateFormatter alloc] init];
                nextReminderDateFormatter.dateFormat = @"MM/dd/yyyy at hh:mm a";
                NSString *nextReminderDateString = [nextReminderDateFormatter stringFromDate:alarm.absoluteDate];

                NSLog(@"Next reminder is on %@", nextReminderDateString);

                break;

            }
        }
    }];

}

if (save && ([currentGardenCurrentReminders boolValue] != [reminderExists boolValue])) {

    if ([reminderExists boolValue]) {
        NSLog(@"within save, reminderexists == true");
    } else NSLog(@"within save, reminderexists == false");

    currentGarden.reminders = reminderExists;
    [self.managedObjectContext save:nil];
}

return [reminderExists boolValue];

}

War es hilfreich?

Lösung

The call to fetchRemindersMatchingPredicate:completion: is asynchronous. This means that your if statement after this call is actually being done long before the call to fetchRemindersMatchingPredicate:completion: is complete.

You can't have a useful return value in a method that does asynchronous processing. You need to change your checkForReminderWithTitle:saveChanges: method to return void and instead have it pass a completion block that will be called when the call to fetchRemindersMatchingPredicate:completion: is done.

BTW - why is reminderExists an NSNumber pointer and not just a BOOL?

Andere Tipps

The call to [EKEventStore fetchRemindersMatchingPredicate:completion:] is asynchronous. So when you check the value of reminderExists below the completion block, the completion block may not have executed yet, and reminderExists may not yet have the correct value.

To fix the problem, put your check code in the end of the completion block. As @rmaddy correctly points out, this function can't return a value, since it relies on an async call.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top