defaultCalendarForNewEvents失败

当我尝试调用[newEventStore defaultCalendarForNewEvents]时,它会返回一条错误消息:

[707:907] defaultCalendarForNewEvents failed: Error Domain=EKCADErrorDomain Code=1013 "The operation couldn't be completed. (EKCADErrorDomain error 1013.)" [707:907] Error!Failed to save appointment. Description:Error Domain=EKErrorDomain Code=1 "No calendar has been set." UserInfo=0x1fc679f0 {NSLocalizedDescription=No calendar has been set.} 

该应用程序运行了很长时间。 这个问题第一次来了。 手机运行IOS6 Beta4。 模型是iPhone 4.有没有人知道什么时候defaultCalendarForNewEvents方法会失败? 我无法从Google上获得任何有用的信息。

在iOS6上,苹果引入了新的隐私控制,允许用户控制每个应用的联系人和日历的可访问性。 所以,在代码方面,你需要添加一些方法来请求权限。 在iOS5或之前,我们可以随时致电

 EKEventStore *eventStore = [[[EKEventStore alloc] init] autorelease]; if ([eventStore respondsToSelector:@selector(requestAccessToEntityType:completion:)]) { // iOS 6 and later [eventStore requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted, NSError *error) { if (granted) { // code here for when the user allows your app to access the calendar [self performCalendarActivity:eventStore]; } else { // code here for when the user does NOT allow your app to access the calendar } }]; } else { // code here for iOS < 6.0 [self performCalendarActivity:eventStore]; } 

如果您不调用– requestAccessToEntityType:completion:函数来提示对话框要求您的用户授予您的应用程序访问日历/提醒的权限,则iOS应用程序将无法从iOS6系统上的日历中获取任何数据。 代码将如下所示:

 //CalendarEventHandler.h @interface CalendarEventHandler : NSObject { EKEventStore *eventStore; } @property (nonatomic, strong) EKEventStore *eventStore; //CalendarEventHandler.m self.eventStore =[[EKEventStore alloc] init]; if([self checkIsDeviceVersionHigherThanRequiredVersion:@"6.0"]) { [self.eventStore requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted, NSError *error) { if (granted){ //---- codes here when user allow your app to access theirs' calendar. }else { //----- codes here when user NOT allow your app to access the calendar. } }]; }else { //---- codes here for IOS < 6.0. } 

//下面是用于检查的块是当前版本高于所需版本的ios版本。

  - (BOOL)checkIsDeviceVersionHigherThanRequiredVersion:(NSString *)requiredVersion { NSString *currSysVer = [[UIDevice currentDevice] systemVersion]; if ([currSysVer compare:requiredVersion options:NSNumericSearch] != NSOrderedAscending) { return YES; } return NO; } 

iOS6+需要用户身份validation才能将事件保存到他的设备日历中。 这是一个代码snippt:

  // save to iphone calendar EKEventStore *eventStore = [[EKEventStore alloc] init]; if([eventStore respondsToSelector:@selector(requestAccessToEntityType:completion:)]) { // iOS 6 and later // This line asks user's permission to access his calendar [eventStore requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted, NSError *error) { if (granted) // user user is ok with it { EKEvent *event = [EKEvent eventWithEventStore:eventStore]; event.title = aTitle; event.allDay = YES; NSDateFormatter *dateFormat = [[UIApplicationSingleton sharedManager] aDateFormatter]; [dateFormat setDateFormat:@"MMM dd, yyyy hh:mm aaa"]; event.startDate = event.endDate = //put here if start and end dates are same [event setCalendar:[eventStore defaultCalendarForNewEvents]]; NSError *err; [eventStore saveEvent:event span:EKSpanThisEvent error:&err]; if(err) NSLog(@"unable to save event to the calendar!: Error= %@", err); } else // if he does not allow { [[[UIAlertView alloc]initWithTitle:nil message:alertTitle delegate:nil cancelButtonTitle:NSLocalizedString(@"plzAlowCalendar", nil) otherButtonTitles: nil] show]; return; } }]; } // iOS < 6 else { EKEvent *event = [EKEvent eventWithEventStore:eventStore]; event.title = aTitle; event.allDay = YES; NSDateFormatter *dateFormat = [[UIApplicationSingleton sharedManager] aDateFormatter]; [dateFormat setDateFormat:@"MMM dd, yyyy hh:mm aaa"]; event.startDate = event.endDate = //put here if start and end dates are same [event setCalendar:[eventStore defaultCalendarForNewEvents]]; NSError *err; [eventStore saveEvent:event span:EKSpanThisEvent error:&err]; if(err) NSLog(@"unable to save event to the calendar!: Error= %@", err); } 

如果您在为应用程序设置闹钟时遇到问题,请查看我的this post

解决了。 我不小心closures了应用程序访问IOS6上的设置 – >隐私日历

Swiftforms

(基于@yunas答案)

 _estore = EKEventStore() _estore.reset() _estore.requestAccessToEntityType(EKEntityTypeEvent) { (granted, error) in if granted { println("allowed") /* ... */ } else { println("not allowed") } } 

它将打开“访问”popup窗口

我有同样的问题,但终于find原因。

我的情况是添加我的提醒和日历事件,但我正在使用一个EKEventStore 。 最后我把它们分开,问题消失了:

 private static let calendarEventStore = EKEventStore() private static let remindersEventStore = EKEventStore() 

所以,现在我使用calendarEventStore来处理与日历事件相关的所有事情,并使用remindersEventStore提醒一个事件。

在我看来,这与我在一个EKEventStore实体中请求defaultCalendarForNewEventsdefaultCalendarForNewReminders() EKEventStore

EKEventStore这个文档也是这样的:

从事件存储中检索的事件,提醒和日历对象不能与任何其他事件存储一起使用

转到模拟器/设备设置/隐私/日历/你的应用程序点击开允许日历访问。 然后重试你的代码。它会工作。

对于Xamarin用户:

 EKEventStore eventStore = new EKEventStore(); eventStore.RequestAccess(EKEntityType.Event, (bool granted, NSError e) => { if (granted) { //Your code here when user gief permissions } });