究竟什么构成了EKCalendar中的“完整日历同步”?

时间:2013-04-09 20:43:58

标签: ios objective-c calendar eventkit

EKCalendar类的文档为calendarIdentifier属性声明了这一点:

  

与日历的完全同步将丢失此标识符。你应该   有一个处理标识符为no的日历的计划   通过缓存其他属性来获取更长的时间。

何时发生“完全同步”以及除calendarIdentifier之外哪些属性可能会发生变化?

3 个答案:

答案 0 :(得分:3)

完全同步"完全同步"发生吗
Calendar and Reminders Programming Guide以这种方式解释了这些问题:

  

如果从应用外部发生对日历数据库的更改,   事件工具包能够通过通知检测更改,以便您的应用可以   行为恰当。使用Event Kit对日历项目所做的更改是   自动同步到关联的日历(CalDAV,Exchange和   等等。)

我看到了"完全同步"应用程序打开时发生的事件:
  1。用户将您的应用发送到后台并打开日历应用。他更改日历名称,添加/编辑/删除事件甚至删除某些日历   2。用户在Mac上对iCloud日历应用了一些更改。通知iOS设备iCloud日历已更改,因此必须同步   3。第三方应用收到无声通知,iOS在后台启动,应用根据通知创建一些日历事件。

一般来说,这意味着"完全同步"事件可以随时发生。

如何检测和处理"完全同步"事件吗
Observing External Changes to the Calendar Database以这种方式解释了这些问题:

  

另一个进程或应用程序可以修改日历   应用程序运行时的数据库。如果您的应用提取日历   事件或提醒,您应该注册以获得有关更改的通知   到日历数据库。通过这样做,您可以确保日历   您向用户显示的提醒信息是最新的。

以下是注册此类通知的代码示例:

[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(storeChanged:)
                                             name:EKEventStoreChangedNotification
                                           object:eventStore];

我认为重新创建EKCalendar类的实例并在需要时重新缓存calendarIdentifier是有意义的。

除calendarIdentifier外,哪些属性可能会发生变化?
我无法找到有关此问题的任何文档。但由于日历在某些时刻甚至不存在(例如用户在日历应用程序中手动删除它),因此{< {1}}对象的任何属性在"完全同步"之后可能无效。事件发生了。

阅读以上链接以获取更多信息和详细信息也是有意义的。

答案 1 :(得分:1)

添加日历时会发生完全同步。所有添加的日历都缓存在系统(iOS或MacOS)上并接收唯一ID。这可以在MacOS上轻松查看 - 如果您转到目录~/Library/Calendars/,您将看到一个包含以下目录的列表:

3CC21C9A-0B3C-4A76-B2B0-8D3643CF2992.exchange/

45EF644F-672A-453A-ACC9-A565F017F766.calendar/

这些是可以使用calendarIdentifier检查的唯一ID。

为了测试iOS上calendarIdentifier的更改方式,您可以在名为testcal的iCloud中创建日历,并使用以下代码获取标识符:

EKEventStore *eventStore = [[EKEventStore alloc] init];
NSArray *cal = [eventStore calendarsForEntityType:EKEntityTypeEvent];
for (EKCalendar *i in cal) {
    if([i.title isEqualToString:@"testcal"]) {
        NSLog(@"%@", i.calendarIdentifier);
    }
}

之后,请停用日历(设置 - > iCloud - >日历,选择"从我的iPhone删除")并启用它。当您再次执行代码时,您将看到不同的标识符,尽管日历是相同的。

我发现将执行完全同步的另一种情况是本地缓存是否已损坏。在这种情况下,日历应尝试重建它。

因此,按标识符查找日历并不是一个好主意,您可以使用标题,类型,颜色等来唯一标识它。

答案 2 :(得分:0)

基于iTunes论坛,当它没有指定完全同步时,取决于它们:

http://www.openradar.appspot.com/15671424

https://idmsa.apple.com/IDMSWebAuth/login?appIdKey=4a75046cda87eab6386a9eae8caabb9824e328b9abc988119b39296495ec184c&path=/login.jspa#926856

与易于更改的属性相关的是所有可以被其他线程访问的属性(与calendarIdentifier相同),因此那些非原子的并且可以更改,这里是我可以发现:

allowsContentModifications, CGColor, immutable,title,type,allowedEntityTypes,source,subscribed,supportedEventAvailabilities