【发布时间】:2020-11-03 13:54:04
【问题描述】:
我正在尝试将自定义类存储在 UserDefaults 中,但是一旦应用启动,我就会收到 "Attempt to insert non-property list" 错误。我已经成功存储了自定义类的数组,所以我遵循了相同的原则,但是出了点问题。
这是我的课:
import Foundation
public class PlanRouteFilters: NSObject, NSCoding, Codable {
var favoriteLines: Bool
var routeType: Int
var bus: Bool
var train: Bool
var subway: Bool
var electric: Bool
var sharedCar: Bool
var bike: Bool
var electricScooter: Bool
var providers: [Provider]?
override init() {
self.favoriteLines = false
self.routeType = 1
self.bus = false
self.train = false
self.subway = false
self.electric = false
self.sharedCar = false
self.bike = false
self.electricScooter = false
self.providers = []
}
init(favLines: Bool, rType: Int, bus: Bool, train: Bool, subway: Bool, electric: Bool, sCar: Bool, bike: Bool, eScooter: Bool, providers: [Provider]?) {
self.favoriteLines = favLines
self.routeType = rType
self.bus = bus
self.train = train
self.subway = subway
self.electric = electric
self.sharedCar = sCar
self.bike = bike
self.electricScooter = eScooter
self.providers = providers
}
//MARK: NSCoding protocol methods
public func encode(with aCoder: NSCoder){
aCoder.encode(self.favoriteLines, forKey: "favoriteLines")
aCoder.encode(self.routeType, forKey: "RouteType")
aCoder.encode(self.bus, forKey: "bus")
aCoder.encode(self.train, forKey: "train")
aCoder.encode(self.subway, forKey: "subway")
aCoder.encode(self.electric, forKey: "electric")
aCoder.encode(self.sharedCar, forKey: "sharedCar")
aCoder.encode(self.bike, forKey: "bike")
aCoder.encode(self.electricScooter, forKey: "electricScooter")
aCoder.encode(self.providers, forKey: "providers")
}
public required init(coder decoder: NSCoder) {
self.favoriteLines = decoder.decodeBool(forKey: "favoriteLines")
self.routeType = decoder.decodeInteger(forKey: "routeType")
self.bus = decoder.decodeBool(forKey: "bus")
self.train = decoder.decodeBool(forKey: "train")
self.subway = decoder.decodeBool(forKey: "subway")
self.electric = decoder.decodeBool(forKey: "electric")
self.sharedCar = decoder.decodeBool(forKey: "sharedCar")
self.bike = decoder.decodeBool(forKey: "bike")
self.electricScooter = decoder.decodeBool(forKey: "electricScooter")
self.providers = decoder.decodeObject(forKey: "providers") as? [Provider]
}
}
这是我设置和获取对象的方式:
var planRouteFilters: PlanRouteFilters {
get {
var filters = PlanRouteFilters()
let data = self.userSettings.settings.object(forKey: "planRouteFilters") as? Data
if nil != data {
filters = try! NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(data!) as! PlanRouteFilters
}
return filters
}
set {
let data = try! NSKeyedArchiver.archivedData(withRootObject: newValue, requiringSecureCoding: false)
self.userSettings.settings.setValue(data, forKey: "planRouteFilters")
self.objectWillChange.send()
}
}
这就是我创建 userDefaults 的方式:
import Foundation
struct UserSettings {
var settings: UserDefaults
init() {
self.settings = UserDefaults.standard
self.settings.register(
defaults: [
"userCity": "",
"showUserCityActionSheet": true,
"showTutorial": 1,
"initialPage": 1,
"favoriteStops": [Place](),
"history": [Place](), //Maximum of 10 places stored
"notifications": [MoveMeNotification](),
"planRouteFilters": PlanRouteFilters()
])
}
}
如果我删除了应用程序启动的 PlanRouteFilters 的默认值,但这些值不会在整个应用程序中使用。这是我错的地方吗?我应该以其他方式提供默认值吗?
谢谢!
我的Provider 班级:
public class Provider: NSObject, NSCoding, Codable {
let name: String
init(name: String) {
self.Name = name
}
public func encode(with aCoder: NSCoder) {
aCoder.encode(self.Name, forKey: "Name")
}
public required init(coder decoder: NSCoder) {
self.Name = decoder.decodeObject(forKey: "Name") as! String
}
}
更新:
好的,我无法解决这个问题。但是,我认为我不需要在 userSettings 中设置默认值。这让我可以继续前进。但是,这是针对我的情况的。对于没有此选项的任何人,请查看 @LeoDabus 回答。
【问题讨论】:
-
Provider 应该是一个类并且也符合 NSCoding。顺便说一句,你为什么还要确认 Codable?你不需要两者。实际上 Codable 现在是一个更好的选择
-
@LeoDabus
Provider符合 NSCoding。当我第一次开始开发时,使用两者是我让它工作的唯一方法。我还没来得及重构它。 -
在下面查看我的帖子。 stackoverflow.com/q/33192675/2303865 的可能重复项
-
已更新。感谢您的帮助。
-
我重新安装了应用程序。没有运气。
标签: ios swift nsuserdefaults swift5