这是对之前一个没有答案的问题的后续:
Swift EKCalendar not persisting
上一篇文章摘要:简而言之,我可以创建新的EKCalendars,将它们保存到EventStore,并将事件写入它们。但是,一旦应用程序进入后台,EKCalendars将被删除或从内存中删除。既然弄清楚如何使日历在EventStore中持久化似乎不是一个选择,我正在探索一些替代方案。
想法:一个想法是将EKCalendars存储在UserDefaults中,并保存到EventStore中。在研究了一下之后,我发现了一些非常有用的帖子,比如:Save custom objects into NSUserDefaults他们将一个自定义对象转换为NSData并存储它。不幸的是,对我来说,EKCalendar不符合NSCoding协议,据我所知,没有办法扩展类来这样做?
问题:是否有方法将不符合EKCalendar协议的NSCoding对象转换为NSData?或者有其他方法保存类对象的位置吗?
旁注:为了避免问题重叠,如果您有任何关于让EKCalendar持续存在于EventStore的信息,请在顶部的上一篇文章链接中发布这些回答。

最佳答案

所以我以前处理过符合NSCoding的对象,所以我想我会给你一个潜在的解决方案,看看它是否适合你。
免责声明:
请记住,我不确定这是否合法,但这在我心中是有意义的,所以我想我会分享。这个解决方案也可能会错过您的项目所需的一个需求,如果是这样,请让我知道。
好吧,基本上我的想法是你可以创建一个符合NSCoding的EKCalendar子类。看起来像这样:

class MyCalendar: EKCalendar, NSCoding {
    ...
}

现在这是信心的最大飞跃,但是之后您应该能够包含这个定制类所需的方法,以符合NSCoding。这看起来像这样。
class MyCalendar: EKCalendar, NSCoding {

    init(color: CGColor){ //you can include your own init if you want, or just use the superclass init
        super.cgColor = color
        ...
    }

    required init?(coder aDecoder: NSCoder) {
        super.init()
        super.cgColor = aDecoder.decodeObject(forKey: "Color") as! CGColor
        ...
    }

    func encode(with aCoder: NSCoder) {
        aCoder.encode(super.cgColor, forKey: "Color")
        ...
    }
}

这是一个有点迂回的方法,因为您必须对要存储的所有属性进行编码和解码,但公平地说,对于任何要使其符合NSCoding的自定义类来说,这都是正确的。
您还必须对plist的存储位置执行所有目录操作,但这只需要简单地搜索一下。
除此之外,如果这对你有用,请告诉我。
编辑
所以正如我所怀疑的,我认为上面的方法是“非法的”,所以当我试图为EKCalendar调用super.init时,它给出了一些错误。
我的下一个最好的解决方案是创建相同的自定义对象,但这次它是NSObject的一个子类。然后,此对象有一个EKCalendar属性,您可以使用它:
class MyCalendar: NSObject, NSCoding {

    var ekCalendar: EKCalendar

    init(entityType: EKEntityType, eventStore: EKEventStore){
        ekCalendar = EKCalendar(for: entityType, eventStore: eventStore)

    }

    required init?(coder aDecoder: NSCoder) {
        ekCalendar = aDecoder.decodeObject(forKey: "Calendar") as! EKCalendar

    }

    func encode(with aCoder: NSCoder) {
        aCoder.encode(ekCalendar, forKey: "Calendar")

    }
}

我想说,这种方法的好处是,您不必对它的所有属性进行编码和解码,因为您应该能够这样做:
var calendar = MyCalendar(//initialize)
calendar.ekCalendar.cgColor = UIColor.black.cgColor //just an example

07-27 13:40