0

在使用用户日历时,我实现了一个 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它不是永久标识符,因此会随着时间而改变。正如苹果在其文档中所述:

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

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

4

2 回答 2

0

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

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),则不会选择日历并且应用程序不会崩溃。

高温高压

于 2020-10-31T13:44:57.847 回答
0

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

  • 我在 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)
          }
    
于 2021-12-05T08:42:49.667 回答