【问题标题】:How to identify an EKCalendar to store a user calendar selection如何识别 EKCalendar 以存储用户日历选择
【发布时间】:2021-01-17 21:41:54
【问题描述】:

在使用用户日历时,我实现了一个 EKCalendarChooser,它允许用户选择他的多个日历。选定的日历实例被检索得很好。现在我稍后想使用此选择,但如何永久存储它?

我的第一种方法是使用日历标识符并将它们作为字符串数组存储到 UserDefaults 之类的

@State private var calendarSelection: [EKCalendar]

// my approach to convert the calendar selection into a storable format (string array of ids)
var selectedIds = [String]()
for calendar in calendarSelection {
    selectedIds.append(calendar.calendarIdentifier)
}

// now store the string-array, eg. to user defaults:
UserDefaults.standard.set(selectedIds, forKey: "cids")

不幸的是,这不起作用,因为calendarIdentifier 不是永久标识符,因此会随着时间而改变。正如苹果在其文档中所述:

与日历完全同步将丢失此标识符。你应该有一个计划来处理一个日历,它的标识符不再可以通过缓存它的其他属性来获取。

那么如何存储用户对其日历的选择呢?

【问题讨论】:

  • 我目前也在为此苦苦挣扎。你喜欢这个解决方案吗?
  • 我花了很多时间在这里搜索解决方案,但不幸的是,我最终感到非常惊讶,这似乎是不可能的。如果存在不同的方法,通常就是这种情况,但我也找不到。所以剩下的就是存储一个不太可能改变但仍然可能发生的日历的名称,并且根据用例可能会导致重大问题。

标签: ios swift uniqueidentifier eventkit ekcalendar


【解决方案1】:

好的,现在这对我有用。
我存储日历标识符...

func calendarChooserDidFinish(_ calendarChooser: EKCalendarChooser) {
    ...
    // store selected calendar identifier
    selectedCalendar = calendarChooser.selectedCalendars.first?.calendarIdentifier
    ...
}

...然后恢复它。

func showCalendarChooser() {
    ...
    // check if calendar identifier still exists
    if let selectedCalendarIdentifier = eventStore.calendar(withIdentifier: selectedCalendar) {
        //select stored calendar
        calendarChooser.selectedCalendars = [selectedCalendarIdentifier]
    }
    ...
}

这仅适用于 1 个选定的日历 (selectionStyle: .single)。
将此代码更改为多个日历应该很简单。

我还测试了日历标识符是否会改变……到目前为止还没有什么乐趣。在所有测试期间它保持不变。如果它应该更改 (nil),将不会选择日历并且应用不会崩溃。

HTH

【讨论】:

  • 好吧,我的标识符经常更改,但并非所有日历都更改。您是否为日历启用了 iCloud 同步?除了本地/iCloud 日历之外,还有其他的吗?由于文档不能保证它不会改变,我认为依赖它可能是个坏主意。但当然取决于用例。
  • 是的,我为日历启用了 iCloud 同步。除此之外,我大量使用本地日历和谷歌日历(包括一些具有 RW 访问权限的人)。我没有在 Apple 文档中找到关于您提到的不断变化的标识符的参考。对我来说,上述解决方案现在是完美的(没有更改标识符)并且在更改标识符的情况下是可以接受的,因为我相信这不会定期发生。无论如何,如果发生这种情况,最糟糕的是需要再次选择日历(不会崩溃!)。
  • mm 就我而言,它变化如此频繁以至于它完全没用,但很高兴它对你有用。对 Apple 文档的引用:developer.apple.com/documentation/eventkit/ekcalendar/…,其中说:“与日历完全同步将丢失此标识符。您应该制定一个计划,通过缓存其其他属性来处理其标识符不再可获取的日历。 "
  • 感谢您的链接。我会报告日历标识符是否应该更改。但是我真的不明白为什么完全同步需要更改日历标识符(从技术上讲)。
【解决方案2】:

我也有同样的问题。坏事是你无法判断标识符何时会改变。这是我的工作...

  • 我将日历标识符、日历标题、日历源存储在 userDefaults 中

  • 我首先通过比较标识符来获取一组日历。如果 eventStore 中不存在标识符,则比较标题和来源。

  • 当然,您可以添加更多属性,但我认为标题 + 来源就足够了。

  • 我的代码中有另一部分更新了 userDefaults 中的新标识符。

    if userSettings.selectedCalID != [] { //检查数组是否为空。如果为空,则不要使用预选日历。

              var selectedCalendarIdentifier : [EKCalendar] = []
    
              for i in userSettings.selectedCalID{
                  print(i)
    
                  if let eventStoreID = eventStore.calendar(withIdentifier: i){
                      selectedCalendarIdentifier.append(eventStoreID)
                  } else {
                      //This is part where calendar identifier has changed or not present in eventstore. Retrive new identifier by checking calendar title AND calendar source.
    
                      if userSettings.selectedCalTitle != [] && userSettings.selectedCalSource != [] {
                          let calTitle =  userSettings.selectedCalTitle[userSettings.selectedCalID.firstIndex(of: i) ?? 0]
                          let calSource = userSettings.selectedCalSource[userSettings.selectedCalID.firstIndex(of: i) ?? 0]
                          print("\(calTitle) - \(calSource)")
    
    
                          if let eventStoreCalNewID = eventStore.calendars(for: .event).filter({($0.title == calTitle) && ($0.source.title == calSource)}).first?.calendarIdentifier{
    
                              if let eventStoreID = eventStore.calendar(withIdentifier: eventStoreCalNewID){
                                  selectedCalendarIdentifier.append(eventStoreID)
                              }
                          }
    
                      }
    
                  }
              }
    
              chooser.selectedCalendars = Set(selectedCalendarIdentifier)
          }
    

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多