2014-01-14 42 views
3

我一直在測試此代碼以將日曆添加到IOS Cal App,並且還將一些事件添加到應用中的特定日曆。EKEvent將相同的事件添加到日曆中

我有一個Ipad IOS7,iCloud禁用。

第一個問題是,當我創建日曆我無法在iPad的iCal應用程序中看到新創建的日曆,即使它們沒有添加到iCloud,該應用是否應該顯示所有日曆?

第二個問題是我的代碼每次調用該代碼時不斷添加相同的事件。

可以說我調用了add函數,並且它在第一次成功添加了3個事件,下次調用該函數時它應該跳過添加,但它再次將3個事件添加到日曆現在我有重複的事件,並且等等...

-(void) initCalendar:(NSDictionary *)dataDict 
{ 
    self.eventStore = [[EKEventStore alloc] init]; 
    if([self.eventStore respondsToSelector:@selector(requestAccessToEntityType:completion:)]) { 
     // iOS 6 and later 
     [self.eventStore requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted, NSError *error) { 
      if (granted){ 
       //---- codes here when user allow your app to access theirs' calendar. 
       NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; 
       self.isCalendarAccepted=YES; 
       NSLog(@"self.isCalendarAccepted=YES;"); 
       if ([defaults objectForKey:@"Calendar"] == nil) // Create Calendar if Needed 
       { 
        EKSource *theSource = nil; 

        for (EKSource *source in self.eventStore.sources) { 
         if (source.sourceType == EKSourceTypeCalDAV && [source.title isEqualToString:@"iCloud"]) { 
          theSource = source; 
          NSLog(@"iCloud Store Source"); 
          break; 
         } else { 
          for (EKSource *source in self.eventStore.sources) { 
           if (source.sourceType == EKSourceTypeLocal) { 
            theSource = source; 
            NSLog(@"ios Local Store Source"); 
            break; 
           } 
          } 
         } 
        } 


        //EKCalendar *calendar = [EKCalendar calendarWithEventStore:self.eventStore]; 
        EKCalendar *calendar =[EKCalendar calendarForEntityType:EKEntityTypeEvent eventStore:self.eventStore]; 
        calendar.title = @"My App Name"; 
        if (theSource) { 
         calendar.source = theSource; 
        } else { 
         NSLog(@"Error: Local source not available"); 
         return; 
        } 
        NSError *errorCalendar = nil; 
        BOOL result = [self.eventStore saveCalendar:calendar commit:YES error:&errorCalendar]; 
        if (result) { 
         NSLog(@"Saved calendar to event store."); 
         [[NSUserDefaults standardUserDefaults] setObject:calendar.calendarIdentifier forKey:@"Calendar"]; 
         [[NSUserDefaults standardUserDefaults] synchronize]; 


        } else { 
         NSLog(@"Error saving calendar: %@.", errorCalendar); 
        } 

       } 
       //start adding event to calendar 
       [self addSelectedOwnEventsToCalendar:dataDict]; 
      } 
     }]; 
    } 


} 

-(void)addSelectedOwnEventsToCalendar:(NSDictionary *)dataDict 
{ 

      // Create a new event... save and commit 
      NSError *error = nil; 

      EKEvent *myEvent = [EKEvent eventWithEventStore:self.eventStore]; 


      myEvent.allDay = NO; 
      myEvent.availability = EKEventAvailabilityFree; 
      NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; 
      [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"]; 
      NSDate *startDate = [[NSDate alloc] init]; 
      NSString *startDateFormatted=[NSString stringWithFormat:@"%@ %@",[dataDict objectForKey:@"start_date"],[dataDict objectForKey:@"starts"]]; 
      startDate = [dateFormatter dateFromString:startDateFormatted]; 

      NSDateFormatter *dateFormatter1 = [[NSDateFormatter alloc] init]; 
      [dateFormatter1 setDateFormat:@"yyyy-MM-dd HH:mm:ss"]; 
      NSDate *endDate = [[NSDate alloc] init]; 
      NSString *endDateFormatted=[NSString stringWithFormat:@"%@ %@",[dataDict objectForKey:@"end_date"],[dataDict objectForKey:@"ends"]]; 
      endDate = [dateFormatter1 dateFromString:endDateFormatted]; 

      //compare dates 
      NSComparisonResult result = [startDate compare:endDate]; 
      if (result == NSOrderedAscending) { 
      } else if (result == NSOrderedDescending) { 
      } else { 
       //the same 
       endDate=[startDate dateByAddingTimeInterval:60]; 
      } 

      myEvent.startDate=startDate; 
      myEvent.endDate = endDate; 
      myEvent.title = [dataDict objectForKey:@"event_id"]; 
      myEvent.calendar = [self.eventStore calendarWithIdentifier:[[NSUserDefaults standardUserDefaults] objectForKey:@"Calendar"]]; 
      myEvent.location=[dataDict objectForKey:@"location"]; 



      NSArray *cals = [self.eventStore calendarsForEntityType: EKEntityTypeEvent]; 
      NSPredicate *predicateForEventsOnHolidayDate = [self.eventStore predicateForEventsWithStartDate:startDate endDate:endDate calendars:cals]; // nil will search through all calendars 

      NSArray *eventsOnHolidayDate = [self.eventStore eventsMatchingPredicate:predicateForEventsOnHolidayDate]; 
      //NSLog(@"eventsOnHolidayDate %@",eventsOnHolidayDate); 

      BOOL eventExists = NO; 

      for (EKEvent *eventToCheck in eventsOnHolidayDate) { 
       NSLog(@"eventToCheck.title %@",eventToCheck.title); 
       NSLog(@"event_id %@",[dataDict objectForKey:@"event_id"]); 
       if ([eventToCheck.title isEqualToString:[dataDict objectForKey:@"event_id"]]) { 
        eventExists = YES; 
        NSLog(@"Event Already Exists"); 
       } 
      } 
      //save eventts 
      if (eventExists == NO) { 
       [self.eventStore saveEvent:myEvent span:EKSpanThisEvent commit:YES error:&error]; 
       if (!error) { 
        // NSLog(@"the event saved and committed correctly with identifier %@", myEvent.eventIdentifier); 

       } else { 
        NSLog(@"there was an error saving and committing the event"); 
        NSLog(@"Error %@",error); 
        error = nil; 

       } 


      } 
} 

當我第一次運行該代碼的NSLog說(@"ios Local Store Source");

我缺少什麼?

注意:代碼在模擬器(Ipad ios 7)上大部分時間都在工作,我假設錯誤[NSUserDefaults]

+0

注意[在塊中訪問'self'](https://developer.apple.com/library/ios/documentation/cocoa/conceptual/ProgrammingWithObjectiveC/WorkingwithBlocks/WorkingwithBlocks.html#//apple_ref/doc/uid/ TP40011210-CH8-SW16)是內存泄漏。 – johnnieb

+0

我注意到每次你將'startDate'設置爲當前日期,這可能會刪除已經從謂詞開始的事件(嘗試將日期設置爲一天的開始?)。此外,我會避免使用'title'屬性來設置唯一標識符 - 使用'eventIdentifier'。在另一個說明中,@johnnieb在塊中訪問'self'只會導致內存泄漏,如果'self'保留該塊(保留週期) - 這個塊似乎沒有被任何東西強烈保留。 – John

回答

2

首先,查看有關calendarItemExternalIdentifier文檔中重複項的討論要點,並確定它們是否適用。

然後,看看以下的建議:

  1. calendar identifier可以改變。確保NSUserDefaults中的密鑰Calendar的已保存版本與addSelectedOwnEventsToCalendar:中正在訪問的版本相同。
  2. 當從NSUserDefaults檢索到日曆標識時,請確保它是有效的。
  3. 嘗試使用saveEvent:span:error:方法,而不使用commit參數。我在使用save事件方法時遇到了問題,該方法在過去採用提交參數。

最後,我相信iOS日曆訪問授權只能在iOS設備上測試,這可能是爲什麼它在模擬器中工作。

+1

是的,日曆測試需要在iOS設備上完成。這是一個真正的痛苦,讓我瘋狂,但它是蘋果支持的唯一方式。 –