Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

EKEventStoreChangedNotification gets called several times

I am using the EKEventStore in my app. I grab the default store and register for the EKEventStoreChangedNotification to be notified when changes are made to the calendar. However, when a change is made, the sender for the notification gets called several (5-10) times, sometimes with up to 15 seconds in between each call. This messes up my code and makes things much more difficult to work with. Is there anything I can do about this?

Thanks

iOS7 EDIT: It seems like as of the release of iOS7, this problem has disappeared. Now, regardless of the change made to the CalendarStore, only one EKEventStoreChangedNotification gets sent.

like image 769
Kyle Rosenbluth Avatar asked Aug 30 '12 21:08

Kyle Rosenbluth


1 Answers

This is a result of exactly how the notifications are dispatched and what each is actually notifying about. In my experience, you can expect to receive at least one notification for a change to an item (event, reminder, etc.) and at least one more for the resultant change to the containing calendar for that item.

Without seeing your code and knowing what changes are being made, I can't be too specific about an answer; however, in general, you have two options.

  1. Observe the changes more closely - maybe you can safely ignore some notifications if they concern events that don't pertain to your app, or if you've already handled a change for a particular item.
  2. Coalesce multiple changes into a single batch of handler code. Basically, when you receive the notification, instead of kicking off your response right away, start a timer that will run the response in a second or two. Then, if another notification comes in before the timer fires, you can cancel the timer and reset it. This way, you can batch up multiple notifications that come in a short time window and only respond to them once (when the timer eventually fires).

The latter solution is my preferred answer, and might look something like (temporarily ignoring threading concerns):

@property (strong) NSTimer *handlerTimer;

- (void)handleNotification:(NSNotification *)note {
    // This is the function that gets called on EKEventStoreChangedNotifications
    [self.handlerTimer invalidate];
    self.handlerTimer = [NSTimer timerWithTimeInterval:2.0
                                                target:self
                                              selector:@selector(respond)
                                              userInfo:nil
                                               repeats:NO];
    [[NSRunLoop mainRunLoop] addTimer:self.handlerTimer
                              forMode:NSDefaultRunLoopMode];
}

- (void)respond {
    [self.handlerTimer invalidate];
    NSLog(@"Here's where you actually respond to the event changes");
}
like image 158
Tim Avatar answered Nov 09 '22 13:11

Tim