2

I am listing the events in my app. User can create, edit and delete the events. In viewDidLoad method I fetch all events I need and push them into an array. It works like expected.

For creating, editing and deleting events I use EKEventEditViewController and EKEventViewController which works pretty well. In delegate methods of the controllers I make the changes I need on my array and reload my view.

Of course I would like also know and handle, if user make some changes from another app (like built-in calendar app). So I observe EKEventStoreChangedNotification. From that notification I get only "changes have been occurred" and not which event or from which app. Actually what I want to know is, if the change has been occurred from my app or another app and which events have been changed. Since I already handle the changes(from my app) in EKEventEditViewControllerDelegate method, I do not need to handle them again.

If I do not know which objects have been changed, I have to fetch ans sort all of them.

For now I have only 5 events in the calendar(development device), of course it is not a problem to fetch and sort all events, but if user has more then 1000, it is overkill for maybe only one event change.

So my question is: How to handle EKEventStoreChangedNotification?

Mert
  • 6,025
  • 3
  • 21
  • 33

2 Answers2

1

You can detect exactly which event has been changed by the following code [Disclaimer code is not my idea, I have found it in another Stack Overflow answer and modified it a little bit].

I'm using a lib called "JSCalendarManager" for interaction with eventstore and in my case as the events created using my App and synced with iCalendar I already saved their eventIdentifier in local DB , I can retrieve my time bound to search for events in iCalendar and get match for changed one.

+(void)iCloudStoreChanged:(NSNotification*)eventStoreChangeNotification{
NSArray* allScheduleRecords =[self getAllScheduleRecordSyncedToICalendar];

NSDate* startDate = [NSDate new];
NSDate* endDate   = [NSDate new];

NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];

if (allScheduleRecords.count >= 2) {
    startDate = [dateFormatter dateFromString:[[allScheduleRecords firstObject] objectForKey:@"meetingTime"]];
    endDate = [dateFormatter dateFromString:[[allScheduleRecords lastObject] objectForKey:@"meetingTime"]];
}else if (allScheduleRecords.count > 0){
    startDate = [dateFormatter dateFromString:[[allScheduleRecords firstObject] objectForKey:@"meetingTime"]];

    NSDate *today = [NSDate date];
    NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
    NSDateComponents *components = [gregorian components:(NSEraCalendarUnit | NSYearCalendarUnit | NSMonthCalendarUnit) fromDate:today];
    components.day = 1;
    endDate = [gregorian dateFromComponents:components];
}else{
}

NSArray *ekEventStoreChangedObjectIDArray = [eventStoreChangeNotification.userInfo objectForKey:@"EKEventStoreChangedObjectIDsUserInfoKey"];

[calendarManager findEventsBetween:startDate
                               and:endDate
                 withSearchHandler:^(BOOL found, NSError *error, NSArray *eventsArray) {
                     [eventsArray enumerateObjectsUsingBlock:^(EKEvent *ekEvent, NSUInteger idx, BOOL *stop) {
                         // Check this event against each ekObjectID in notification
                         [ekEventStoreChangedObjectIDArray enumerateObjectsUsingBlock:^(NSString *ekEventStoreChangedObjectID, NSUInteger idx, BOOL *stop) {
                             NSObject *ekObjectID = [(NSManagedObject *)ekEvent objectID];
                             if ([ekEventStoreChangedObjectID isEqual:ekObjectID]) {
                                 // Log the event we found and stop (each event should only exist once in store)
                                 NSLog(@"calendarChanged(): Event Changed: title:%@", ekEvent.title);
                                 [self updateAppointmentForEvent:ekEvent];
                                 *stop = YES;
                             }
                         }];
                     }];
                 }];}
Mohamed Saleh
  • 2,881
  • 1
  • 23
  • 35
  • i found error on NSObject *ekObjectID = [(NSManagedObject *)ekEvent objectID]; this line of code please expel it – DURGESH Sep 21 '16 at 18:12
  • 1) undefined NsManagedObject 2) objectID not found in ekEvent – DURGESH Sep 24 '16 at 16:58
  • @DURGESHKUMAR honestly I don't know for sure, it was working correctly back then, maybe that Apple have changed things related to eventKit. Anyway: I totally don't recommend going in that way as it is not the way Apple want you to work with the Calendar with. You should ask eventkit for changes each time and not work directly with the coredata event models for events. – Mohamed Saleh Sep 25 '16 at 04:27
  • Any other way to find last added event in app with event name and event date – DURGESH Sep 26 '16 at 07:46
  • As I remember no, sorry It has been long since I have worked with this project. I think it is better to go with Apple recommended way instead of this workaround – Mohamed Saleh Sep 26 '16 at 11:48
0

Instead of fetching all events, can you not update only the events that are onscreen/active.

Awais Hussain
  • 98
  • 1
  • 2
  • 8