自从升级到Swift 4.2之后,我发现许多NSKeyedUnarchiver和NSKeyedArchiver方法已被弃用,我们现在必须使用type方法static func unarchivedObject<DecodedObjectType>(ofClass: DecodedObjectType.Type, from: Data) -> DecodedObjectType?来取消归档数据。
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。我在做什么错,我该如何解决才能取消存档阵列?
Array.self
NSArray.self
您可以unarchiveTopLevelObjectWithData(_:)用来取消归档由归档的数据archivedData(withRootObject:requiringSecureCoding:)。(我相信现在还不建议使用。)
unarchiveTopLevelObjectWithData(_:)
archivedData(withRootObject:requiringSecureCoding:)
但是在显示一些代码之前,您最好:
避免使用NSData,Data改用
NSData
Data
避免使用try?可用于调试的错误信息
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。
Codable