在Today小部件和主机应用程序之间从UserDefaults中选择数据时,NSKeyedUnarchiver.unarchiveObject失败并显示错误

时间:2017-05-09 08:23:44

标签: ios swift

我正在尝试在Today小部件和主机应用之间传递自定义类。我正在使用NSKeyArchiver / NSKeyUnarchiver类。我的类符合NSCoding协议。存档:

widgetStorage = UserDefaults(suiteName: "group.my")! //value is [ListModel] let rawData = NSKeyedArchiver.archivedData(withRootObject: value) widgetStorage.set(rawData, forKey: "myList")

取消归档:

if let rawData = widgetStorage.data(forKey: "myList") { if let array = NSKeyedUnarchiver.unarchiveObject(with: rawData) as? [ListModel]

这在小部件和主机应用程序中完全独立,但不会跨越。如果数据在主机应用程序中存档,则今天小部件会抛出错误,反之亦然。

错误报告: '无法解码密钥(NS.objects)的类对象(ShoppingListToday.ListModel);该类可以在源代码或未链接的库中定义。

我无法得到是错的,以及该如何处理。

1 个答案:

答案 0 :(得分:3)

您遇到的问题是由于使用modulename.classname快速引用类而引起的。解决这个问题的方法是告诉NSKeyedArchiver和NSKeyedUnarchiver为类型使用不同的类名,我使用以下扩展名:

extension NSCoding {
    func registerClassName() {
        let className = String(describing: type(of: self))
        NSKeyedArchiver.setClassName(className, for: type(of: self))
        NSKeyedUnarchiver.setClass(type(of: self), forClassName: className)
    }
}

在归档或取消归档对象之前,您只需要调用registerClassName

以下是静态版本:

extension NSCoding {    
    static func registerClassName() {
        let className = NSStringFromClass(self).components(separatedBy: ".").last!
        NSKeyedArchiver.setClassName(className, for: self)
        NSKeyedUnarchiver.setClass(self, forClassName: className)
    }
}

这样你就可以用YourClassName.registerClassName()

来调用它