小编典典

使用NSKeyedUnarchiver unarchivedObject(ofClass:from :)取消存档数组

swift

自从升级到Swift
4.2之后,我发现许多NSKeyedUnarchiver和NSKeyedArchiver方法已被弃用,我们现在必须使用type方法static func unarchivedObject<DecodedObjectType>(ofClass: DecodedObjectType.Type, from: Data) -> DecodedObjectType?来取消归档数据。

我已经成功地成功归档了我的定制类WidgetData的数组,该数组是NSObject的子类:

private static func archiveWidgetDataArray(widgetDataArray : [WidgetData]) -> NSData {

    guard let data = try? NSKeyedArchiver.archivedData(withRootObject: widgetDataArray as Array, requiringSecureCoding: false) as NSData
        else { fatalError("Can't encode data") }

    return data

}

当我尝试取消存档这些数据时,问题就来了:

static func loadWidgetDataArray() -> [WidgetData]? {

    if isKeyPresentInUserDefaults(key: USER_DEFAULTS_KEY_WIDGET_DATA) {

        if let unarchivedObject = UserDefaults.standard.object(forKey: USER_DEFAULTS_KEY_WIDGET_DATA) as? Data {

            //THIS FUNCTION HAS NOW BEEN DEPRECATED:
            //return NSKeyedUnarchiver.unarchiveObject(with: unarchivedObject as Data) as? [WidgetData]

            guard let nsArray = try? NSKeyedUnarchiver.unarchivedObject(ofClass: NSArray.self, from: unarchivedObject as Data) else {
                fatalError("loadWidgetDataArray - Can't encode data")
            }

            guard let array = nsArray as? Array<WidgetData> else {
                fatalError("loadWidgetDataArray - Can't get Array")
            }

            return array

        }

    }

    return nil

}

但这失败了,因为不允许使用Array.self代替NSArray.self。我在做什么错,我该如何解决才能取消存档阵列?


阅读 2582

收藏
2020-07-07

共1个答案

小编典典

您可以unarchiveTopLevelObjectWithData(_:)用来取消归档由归档的数据archivedData(withRootObject:requiringSecureCoding:)。(我相信现在还不建议使用。)

但是在显示一些代码之前,您最好:

  • 避免使用NSDataData改用

  • 避免使用try?可用于调试的错误信息

  • 删除所有不需要的演员表


试试这个:

private static func archiveWidgetDataArray(widgetDataArray : [WidgetData]) -> Data {
    do {
        let data = try NSKeyedArchiver.archivedData(withRootObject: widgetDataArray, requiringSecureCoding: false)

        return data
    } catch {
        fatalError("Can't encode data: \(error)")
    }

}

static func loadWidgetDataArray() -> [WidgetData]? {
    guard
        isKeyPresentInUserDefaults(key: USER_DEFAULTS_KEY_WIDGET_DATA), //<- Do you really need this line?
        let unarchivedObject = UserDefaults.standard.data(forKey: USER_DEFAULTS_KEY_WIDGET_DATA)
    else {
        return nil
    }
    do {
        guard let array = try NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(unarchivedObject) as? [WidgetData] else {
            fatalError("loadWidgetDataArray - Can't get Array")
        }
        return array
    } catch {
        fatalError("loadWidgetDataArray - Can't encode data: \(error)")
    }
}

但是,如果您要制作新的应用,则最好考虑使用Codable

2020-07-07