2016-02-01 14 views
5

Mam problem z weryfikacją, czy zdarzenie już istnieje w kalendarzu użytkownika. Muszę to sprawdzić, aby ustalić, czy powinienem go dodać, czy też nie, aby nie tworzyć duplikatów wpisów kalendarza. Obecnie tworzę duplikat przy każdym uruchomieniu kodu.Sprawdź, czy zdarzenie istnieje w kalendarzu

pierwsze, tutaj jest jak tworzę pozycję kalendarza:

+ (NSString *) addEventToCalenderWithDate : (NSDate *) eventDate 
           eventTitle : (NSString *) eventTitle 
          eventLocation : (NSString *) eventLocation 
           allDayEvent : (BOOL) isAllDay 
{ 
    EKEventStore *store = [[EKEventStore alloc] init]; 

[store requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted, NSError *error) { 

    if (!granted) { 

     returnValue = @"calendar error"; 

    } 

    else if ([self eventExists:dateAndTime eventTitle:eventTitle allDayEvent:isAllDay]) { 

     returnValue = @"duplicate"; 

    } 

    else { 

     EKEvent *event = [EKEvent eventWithEventStore:store]; 
     event.title = eventTitle; 

     event.startDate = dateAndTime; 

     if (eventTimeString == (id)[NSNull null] || eventTimeString.length == 0 || isAllDay) { 
      event.allDay = YES; 
      event.endDate = dateAndTime; 
     } else { 
      event.endDate = [event.startDate dateByAddingTimeInterval:60*60]; //set 1 hour meeting 
     } 

     event.location = eventLocation; 
     [event setCalendar:[store defaultCalendarForNewEvents]]; 
     NSError *err = nil; 
     [store saveEvent:event span:EKSpanThisEvent commit:YES error:&err]; 

     returnValue = @"success"; 
    } 
}]; 

return returnValue; 


} 

Ustawia zdarzenie poprawnie. Jednak jeśli uruchomię go ponownie, oczekuję, że klauzula else if zwróci YES i nie zostanie utworzony nowy wpis. Jednak zawsze zwraca ona NO i po każdym wykonaniu tworzę nowy wpis kalendarza. Tutaj jest to, że metoda:

+ (BOOL) eventExists : (NSDate *) date 
      eventTitle : (NSString *) eventTitle 
     allDayEvent : (BOOL) isAllDay 
{ 
    EKEventStore *store = [[EKEventStore alloc] init]; 

    NSPredicate *predicateForEventOnDate = [[NSPredicate alloc] init]; 

    if (isAllDay) 
     predicateForEventOnDate = [store predicateForEventsWithStartDate:date endDate:date calendars:nil]; // nil will search through all calendars 
    else 
     predicateForEventOnDate = [store predicateForEventsWithStartDate:date endDate:[date dateByAddingTimeInterval:60*60] calendars:nil]; // nil will search through all calendars 

    NSArray *eventOnDate = [store eventsMatchingPredicate:predicateForEventOnDate]; 
    NSLog(@"eventOnDate: %@", eventOnDate); 

    BOOL eventExists = NO; 

    for (EKEvent *eventToCheck in eventOnDate) { 
     if ([eventToCheck.title isEqualToString:eventTitle]) { 
      eventExists = YES; 
     } 
    } 

    return eventExists; 
} 

Jak przejść przez tą metodą, zauważam, że NSArray nazywa eventOnDate jest nil (the EKEventStore nie jest nil). Nie wiem, czy to oznacza, że ​​po prostu nie znalazł żadnych pasujących wydarzeń lub jeśli coś innego się dzieje.

Co robię źle, że nie pozwoli to na identyfikację istniejących wydarzeń w kalendarzu? Dziękuję Ci!

Odpowiedz

5

Problem wydaje się być z zakresem dat wybranym dla predykatu.

predicateForEventOnDate = [store predicateForEventsWithStartDate:date endDate:date calendars:nil]; 

to będzie wyglądać na imprezy w ramach „0” drugim zakresie, ponieważ termin rozpoczęcia i zakończenia Twojego zapytania kwantyfikatorów jest identyczna.

predicateForEventOnDate = [store predicateForEventsWithStartDate:date endDate:[date dateByAddingTimeInterval:60*60] calendars:nil]; 

Spowoduje to tylko wyszukiwanie zdarzeń, które będą się znajdować w ciągu godziny od podanej daty.

NSCalendar *const calendar = NSCalendar.currentCalendar; 
NSCalendarUnit const preservedComponents = (NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay); 

//strip away hours, minutes and seconds to find date - at start of day 
NSDateComponents *startComponents = [calendar components:preservedComponents fromDate:self.date]; 
//set finished date to 1 full day later 
NSDateComponents *offset = [[NSDateComponents alloc] init]; 
[offset setDay:1]; 

NSDate *start = [calendar dateFromComponents:startComponents]; 
NSDate *finish = [calendar dateByAddingComponents:offset toDate:self.date options:0]; 

NSPredicate *predicateForEventOnDate = [[NSPredicate alloc] init]; 

if (isAllDay) 
    predicateForEventOnDate = [store predicateForEventsWithStartDate:start endDate:finish calendars:nil]; 

NSArray *eventOnDate = [store eventsMatchingPredicate:predicateForEventOnDate]; 

W ten sposób powstanie tablica obejmująca wydarzenia przez cały dzień od początku do końca.

+0

Dobry połów. Myślałem, że muszę mieć dokładne dopasowania na czasy rozpoczęcia i zakończenia. Dziękuję Ci bardzo! – Alex