ios – 保持对日历的同步证明引用

对于我的应用程序,我必须在用户的iCloud帐户中创建一个日历,并将事件添加到该日历.

我用这个创建日历:

let newCalendar = EKCalendar(forEntityType: EKEntityTypeEvent, eventStore: EventManager.sharedInstance.eventStore)
    newCalendar.title = "MyAppCalendar"
    let color = UIColor(red: CGFloat(arc4random_uniform(255))/255, green: CGFloat(arc4random_uniform(255))/255, blue: CGFloat(arc4random_uniform(255))/255, alpha: 1)
    newCalendar.CGColor = color.CGColor

    var mySource:EKSource?
    for source in EventManager.sharedInstance.eventStore?.sources() as! [EKSource] {
        if source.sourceType.value == EKSourceTypeCalDAV.value && source.title == "iCloud" {
            mySource = source
            break
        }
    }
    if mySource == nil {
        //crearting alert and displaying to user
        return
    }
    else {
        newCalendar.source = mySource!
    }

    var error:NSError?
    if EventManager.sharedInstance.eventStore!.saveCalendar(newCalendar, commit: true, error: &error) {
        let calendarName = newCalendar.title
        let calendarIdentifier = newCalendar.calendarIdentifier
        //save these in db and server
    }else {
        SharedConstants.handleErrors(error!)
    }

其中EventManager是我的类,用于维护对EKEventStore对象实例的引用.

但在Apple文档中,它表示calendarIdentifier会在同步时发生变化.

所以我的问题是如何保持对这个日历的引用?

最佳答案 没有解决方案可以在100%的情况下工作,因为您知道calendarIdentifier可以更改.因此,没有任何唯一标识符将始终引用特定日历.

但是,有可能制定出适用于大多数情况的解决方案.我建议使用这种算法来引用特定的日历:

我认为你已经缓存了日历的calendarIdentifier和title.

>遍历所有日历.
>检查是否有任何日历的标识符等于缓存的标识符.
>如果标识符相同,那么您找到了日历.
>在其他情况下,检查是否有任何日历的标题等于缓存的标识符.
>如果标题相同,那么你可能找到了你的日历.如果用户替换了日历和另一个日历的标题,则可能不是这样.我认为这种情况的可能性非常小.
>在其他情况下,您将无法找到您的日历.如果用户删除您的日历,可能会发生这种情况.

以下是上述算法的代码段:

func eventsCalendarWithIdentifier(identifier: String!, title: String!) -> EKCalendar? {
    var calendarWithIdentifier: EKCalendar? = nil
    var calendarWithTitle: EKCalendar? = nil

    let eventStore = EventManager.sharedInstance.eventStore!
    for aCalendar in eventStore.calendarsForEntityType(EKEntityTypeEvent) as! [EKCalendar] {
        if var anIdentifier = aCalendar.calendarIdentifier {
            if anIdentifier == identifier {
                calendarWithIdentifier = aCalendar
                break
            }
        }

        if var aTitle = aCalendar.title {
            if aTitle == title {
                calendarWithTitle = aCalendar
            }
        }

    }

    return calendarWithIdentifier ?? calendarWithTitle
}

此外,在发生潜在的完全同步时处理事件并重新创建日历实例也很重要.这很重要,因为用户可以在您的应用程序处于后台时删除您的日历,在这种情况下,日历将无效.
以下是处理此类事件的代码段:

func registerObserver() {
    NSNotificationCenter.defaultCenter().addObserver(self,
        selector: "storeChanged",
        name: EKEventStoreChangedNotification,
        object: nil)
}

func unregisterObserver() {
    NSNotificationCenter.defaultCenter().removeObserver(self,
        name: EKEventStoreChangedNotification,
        object: nil)
}

func storeChanged() {
    let myCalendar = self.eventsCalendarWithIdentifier(cachedIdentifier, title: cachedTitle)
    if myCalendar == nil {
        // Calendar lost.
    }
    // Updated UI if needed.
}
点赞