Ios EKEvent将相同的事件添加到日历中
我一直在测试这段代码,以便将日历添加到IOS Cal应用程序中,并将一些事件添加到应用程序中的特定日历中 我有一台IOS7的Ipad,iCloud已禁用 第一个问题是,当我创建日历时,我在iPad的iCal应用程序中看不到新创建的日历,即使这些日历没有添加到iCloud中,该应用程序难道不应该显示所有日历吗 第二个问题是,每次调用代码时,代码都会不断添加相同的事件 假设我调用add函数,它第一次成功添加了3个事件,下一次调用该函数时,它应该跳过添加相同的事件,但它再次将3个事件添加到日历中,现在我有重复的事件,依此类推Ios EKEvent将相同的事件添加到日历中,ios,objective-c,calendar,ekevent,Ios,Objective C,Calendar,Ekevent,我一直在测试这段代码,以便将日历添加到IOS Cal应用程序中,并将一些事件添加到应用程序中的特定日历中 我有一台IOS7的Ipad,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本地存储源”)代码>
我错过了什么
注意:大部分时间代码都在模拟器(iPadiOS7)上运行,我假设[NSUserDefaults]
有问题 首先,查看文档中关于重复项的讨论要点,并确定其中是否适用
然后,看看以下建议:
世界可以改变。确保nsserdefaults
中的键日历的保存版本与addSelectedOwnEventsToCalendar:
中访问的版本相同
从NSUserDefaults中检索日历标识符时,请确保其有效
尝试使用不带commit
参数的saveEvent:span:error:
方法。我以前在使用save event方法时遇到过问题,该方法接受commit参数
最后,我认为iOS日历访问授权只能在iOS设备上进行测试,这可能是它在模拟器中工作的原因。注意是内存泄漏。我注意到,每次都将startDate
设置为当前日期,这可能会删除已从谓词开始的事件(尝试将日期设置为一天的最开始?)。此外,我会避免对唯一标识符使用title
属性——使用eventIdentifier
。另一个注意事项是,@johnnieb,如果self
保留块(保留周期),则访问块中的self
只会导致内存泄漏--这一块似乎没有被任何东西强烈保留。是的,日历测试需要在iOS设备上进行。这真是一件痛苦的事,让我发疯,但这是苹果支持的唯一方式。