KDM*_*KDM 5 ios ekeventkit ekeventstore
我有一个奇怪的问题EKEventStore,iCloud和本地日历.如果启用了iCloud,则会创建日历并将事件保存到日历中,如您所料.如果iCloud关闭并且您尝试保存事件没有任何反应,则设备会每隔3-5秒继续创建一个循环中的iCloud日历,直到iCloud重新打开,然后所有这些日历都会作为重复内容涌入iCloud.我正在使用几乎所有在这里引用的确切代码以及Apples Docs.我完全难以理解为什么它不起作用,而且一般来说EKEventStore上的文档似乎很少.
//••••••••••••••••••••••••••••••••••••••• pragma mark - 保存事件//•••••••••••••••••••••••••••••••••••••••••• ••••
-(void)saveEventWithDate:(NSDate *)startDate endDate:(NSDate *)endDate
{
    AppData *theData = [self theAppData];
    if([self checkIsDeviceVersionHigherThanRequiredVersion:@"6.0"]) {
        [eventStore requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted, NSError *error) { // iOS 6 Support
            if (granted){
                NSLog(@"Access Granted");
            } else {
                NSLog(@"Access Not Granted");
            }
        }];
    }
    EKEvent *event  = [EKEvent eventWithEventStore:eventStore];
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    if ([eventStore calendarWithIdentifier:[defaults objectForKey:@"My Calendar"]] != nil) // Calendar Existed
    {
        event.calendar  = [eventStore calendarWithIdentifier:[defaults objectForKey:@"My Calendar"]];
        NSLog(@"Calendar Existed");
    } else { // Create Calendar
        EKSource *theSource = nil;
        for (EKSource* src in eventStore.sources) {
            if ([src.title isEqualToString:@"iCloud"]) {
                theSource = src;
                break;
            }
            if (src.sourceType == EKSourceTypeLocal && theSource==nil) {
                theSource = src;
                break;
            }
        }
        [self setupCalendarWithSource:theSource withEvent:event];
    }
    NSLog(@"Type of Event:%@",typeOfEvent);
    if ([typeOfEvent isEqualToString:@"Hello"]) {
        event.title     = [NSString stringWithFormat:@"%@ Hello",[theData.hello_info objectForKey:@"customer_name"]];
        event.location  = [NSString stringWithFormat:@"Phone #%@",[theData.hello_info objectForKey:@"customer_phone_number"]];
        event.notes     = [NSString stringWithFormat:@"Hello Issue: %@",[theData.hello_info objectForKey:@"hello_issue"]];
        NSLog(@"Hello");
    }
    event.startDate = startDate;
    event.endDate   = endDate;
    event.allDay    = NO;
    EKAlarm *alarm = [EKAlarm alarmWithRelativeOffset:-1800]; // Half Hour Before
    event.alarms = [NSArray arrayWithObject:alarm];
    [eventStore saveEvent:event span:EKSpanThisEvent error:nil];
    SAFE_PERFORM_WITH_ARG(_delegate, @selector(wasScheduled), nil);
}
-(void)setupCalendarWithSource:(EKSource *)theSource withEvent:(EKEvent *)event {
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    EKCalendar *cal;
    cal = [EKCalendar calendarWithEventStore:eventStore];
    cal.title = @"My Appointments";
    cal.source = theSource;
    [eventStore saveCalendar:cal commit:YES error:nil];
    NSLog(@"cal id = %@", cal.calendarIdentifier);
    NSString *calendar_id = cal.calendarIdentifier;
    [defaults setObject:calendar_id forKey:@"My Calendar"];
    event.calendar  = cal;
}
Ale*_*x75 10
我不确定你为什么会遇到这种行为,但我认为由于禁用了iCloud这一事实,系统无法对其进行查询,然后在唤醒iCloud时解决了队列创建请求(但我假设).
无论如何,我想到的第一个解决方案是以这种方式检查iCloud是否处于活动状态
EKSource *defaultSource = [eventStore defaultCalendarForNewEvents].source;
if (defaultSource.sourceType == EKSourceTypeCalDAV)
    NSLog(@"iCloud Enable");
else
    NSLog(@"iCloud Disable");
这样做可以将您的事件正确保存到默认源,然后让2个日历(本地日历和云日历)保持同步...
仍会提示重新激活iCloud以添加所有本地日历.
另请参阅第二个答案在iOS设备上访问以编程方式创建的日历(这是我的想法;))
我希望我能提供帮助.
编辑:可能没有必要创建第二个日历...尝试将日历源从EKSourceTypeCalDAV更改为EKSourceTypeLocal ...不要忘记保存日历与提交"是"
EDIT2:好的,刚刚测试过......
替换这个:
} else { // Create Calendar
    EKSource *theSource = nil;
    for (EKSource* src in eventStore.sources) {
        if ([src.title isEqualToString:@"iCloud"]) {
            theSource = src;
            break;
        }
        if (src.sourceType == EKSourceTypeLocal && theSource==nil) {
            theSource = src;
            break;
        }
    }
    [self setupCalendarWithSource:theSource withEvent:event];
}
有了这个 ...
} else { // Create Calendar
    EKSource *theSource = [eventStore defaultCalendarForNewEvents].source;
    [self setupCalendarWithSource:theSource withEvent:event];
}
这样你就可以在正确的源中创建日历(如果用户停用iCloud和CalDAV,则为本地日历)
然后:
1)当用户选择停用iCloud时,应在iphone上留下日历(而不是删除),以便在本地源中使用云日历
2)当用户选择激活iCloud时,他将本地日历与云合并,你去!
我希望这有帮助
如果您希望以防弹方式查找iCloud日历并在禁用iCloud时恢复为本地日历,请使用以下代码.我添加了一些可能有用的评论:
for (EKSource *source in eventStore.sources) {  //Check for iCloud
    if (source.sourceType == EKSourceTypeCalDAV && [source.title isEqualToString:@"iCloud"]) {
        NSLog(@"Found iCloud Service.");  //Found iCloud
        if([source calendarsForEntityType:EKEntityTypeEvent].count>0){     //Check to see if Calendar is enabled on iCloud
            NSLog(@"iCloud Calendar is Enabled."); //Calendar is Enabled
            if([self saveEventCalendarWithSource:source]){
                return YES;
            }
        }else{
            NSLog(@"iCloud Calendar is Disabled."); //Calendar is Disabled
        }
    }
}
//If we are here it means that we did not find iCloud Source with iCloud Name. Now trying any CalDAV type to see if we can find it
for (EKSource *source in self.reminderStore.sources) {  //Check for iCloud
    if (source.sourceType == EKSourceTypeCalDAV) {
        [self logData:@"Trying to save calendar in EKSourceTypeCalDAV Service."];
        if([self saveEventCalendarWithSource:source]){
            return YES;
        }
    }
}
//If we are here it means that we did not find iCloud and that means iCloud is not turned on. Use Local service now.
for (EKSource *source in self.reminderStore.sources) {  //Look for Local Source
    if (source.sourceType == EKSourceTypeLocal){  //Found Local Source
        NSLog(@"Found Local Source.");
        if([self saveEventCalendarWithSource:source]){
            return YES;
        }
    }
}
这是保存日历的代码:
- (Boolean) saveEventCalendarWithSource:(EKSource *)source{
EKCalendar *Calendar = nil;
MyCalendar = [EKCalendar calendarForEntityType:EKEntityTypeEvent eventStore:eventStore];
MyCalendar.title = @"XXX";
MyCalendar.CGColor = [UIColor blueColor].CGColor;
MyCalendar.source = source;
NSError *err;
if([eventStore saveCalendar:MyCalendar commit:YES error:&err]){
    if(MyCalendar.calendarIdentifier == nil){
        NSLog(@"Could not save Calendar: %@",err);
        return FALSE;
    }
    NSLog(@"Calendar Created. Here's the identifier %@",[MyCalendar calendarIdentifier]);
    return TRUE;
}
NSLog(@"Could not create calendar! Reason:%@",err.description);
return FALSE;
}
| 归档时间: | 
 | 
| 查看次数: | 4467 次 | 
| 最近记录: |