我最近发布了一个应用程序,并立即发现了一个烦人的错误。有一个按钮可以将事件添加到 iCal。按下时,系统会要求用户允许应用程序访问日历。如果用户单击确定,则会显示一条错误消息(代码中的 if(!saved))。但是,如果用户随后重新启动应用程序,那么一切正常(即项目被添加到 iCal 而无需请求许可)。
该错误特别令人讨厌的是它不会出现在模拟器中,也不会出现在之前安装了该应用程序的任何设备中(包括在删除应用程序和重置隐私设置之后)。这使得复制变得困难。
- (IBAction)addToCal:(id)sender{
EKEventStore *eventStore = self.filmController.eventStore;
/* I have moved this code to a new method, called after access is requested. See the edit...
EKEvent *event = [EKEvent eventWithEventStore:eventStore];
event.title = self.film.title;
event.startDate = self.show.date;
event.endDate = [[NSDate alloc] initWithTimeInterval:(60*[self.film.length integerValue]) sinceDate:event.startDate];
event.location = @"Cinema";
[event setCalendar:[eventStore defaultCalendarForNewEvents]];
*/
if([eventStore respondsToSelector:@selector(requestAccessToEntityType:completion:)]){
[eventStore requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted, NSError *error) {
if(granted) {
BOOL saved = [self saveEventToEventStore:eventStore];
NSString *msg;
NSString *title;
if(!saved) {
title = @"Sorry: We can't access your calendar";
msg = @"Please check your access settings for the app in Settings>>Privacy>>Calendars (and try turning permissions 'Off' then 'On'). If you still can't save events then please let us know.";
}
else {
title = @"Added";
msg = @"Item added to calendar";
}
UIAlertView *eventAlert = [[UIAlertView alloc] initWithTitle:title message:msg delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:nil];
[eventAlert performSelectorOnMainThread:@selector(show) withObject:nil waitUntilDone:YES];
}
else {
UIAlertView *errorAlert = [[UIAlertView alloc] initWithTitle:@"Sorry: We can't access your calendar" message:@"You must change the setting for the app in Settings>>Privacy>>Calendars." delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:nil];
[errorAlert performSelectorOnMainThread:@selector(show) withObject:nil waitUntilDone:YES];
}
}];
}
else {
[self saveEventToEventStore:eventStore];
}
}
-(BOOL) saveEventToEventStore:(EKEventStore *)eventStore {
//Set event details
EKEvent *event = [EKEvent eventWithEventStore:eventStore];
event.title = self.film.title;
event.startDate = self.show.date;
event.endDate = [[NSDate alloc] initWithTimeInterval:(60*[self.film.length integerValue]) sinceDate:event.startDate];
event.location = @"Cinema";
[event setCalendar:[eventStore defaultCalendarForNewEvents]];
//event details end
NSError *err;
return [eventStore saveEvent:event span:EKSpanThisEvent error:&err];
}
任何帮助将不胜感激....
缺口
编辑:我一直在考虑这个问题,但仍然不明显出了什么问题。我唯一的猜测是我在 requestAccess 之前设置了我的事件详细信息。这可能会引发一些错误(可能是在设置日历时),从而导致保存失败。重新启动应用程序会从已授予访问权限的状态启动它,从而避免错误。我仍然对这个猜测并不完全满意,因为我认为它只会在第一次按下“添加到 iCal”按钮时引起问题,而我的问题发生在后续按下时。
我在上面添加了新的(更完整的)代码,它将事件创建放在 requestAccess 之后。可悲的是,我已经用完了设备来测试它,但如果我找到了一个,我会更新它是否有效。