我正在尝试使用NSCoding将自定义对象编码为用户默认值。
我实例化"联盟"对象,然后尝试将其保存为默认值,并在另一个区域中解码和检索它。从用户默认值中检索解码的对象时,只有"顶级"该对象的恢复(团队名单只是团队的名称和联盟的名称)和联盟下面的继承参数没有数据(即名单或团队中有一系列的球员和那些球员姓名)。
这些课程定义如下。类结构在应用程序的单个实例中正确交互,但它没有将联盟对象的所有参数保存在用户默认值中。
我在哪里搞砸了?
class player: NSObject, NSCoding {
var first = ""
var last = ""
var parent1 = ""
var parent2 = ""
var position = ""
var shoots = ""
var goals = 0
var assists = 0
var points = 0
func encode(with aCoder: NSCoder) {
aCoder.encode(first, forKey: "first")
aCoder.encode(last, forKey: "last")
}
required convenience init?(coder aDecoder: NSCoder) {
let first = aDecoder.decodeObject(forKey: "first")
let last = aDecoder.decodeObject(forKey: "last")
self.init(first: first as! String, last: last as! String)
}
init(first: String, last: String) {
self.first = first
self.last = last
}
}
class team: NSObject, NSCoding {
var roster: [player] = []
var gameList: [game] = []
var name: String = ""
init(name: String, roster: [player]) {
self.roster = roster
// self.gameList = gameList
self.name = name
}
func encode(with aCoder: NSCoder) {
aCoder.encode(roster, forKey: "roster")
//aCoder.encode(gameList, forKey: "gameList")
aCoder.encode(name, forKey: "name")
}
required convenience init?(coder aDecoder: NSCoder) {
let roster = aDecoder.decodeObject(forKey: "roster") as! [player]
//self.gameList = aDecoder.decodeObject(forKey: "gameList") as! [game]
let name = aDecoder.decodeObject(forKey: "name") as! String
self.init(name: name, roster: roster)
}
}
class game: NSObject, NSCoding {
var datePlayed = 0.0
var graphLabel = ""
var shotsFor = 0
var shotsAgainst = 0
var goalsFor = 0
var goalsAgainst = 0
var opponent = ""
var location = ""
var goalie1Time = 0
var goalie1Shots = 0
var goalie1Goals = 0
var goalie2Time = 0
var goalie2Shots = 0
var goalie2Goals = 0
func encode(with aCoder: NSCoder) {
aCoder.encode(datePlayed, forKey: "datePlayed")
aCoder.encode(opponent, forKey: "opponent")
aCoder.encode(shotsFor, forKey: "shotsFor")
}
required convenience init?(coder aDecoder: NSCoder) {
let datePlayed = aDecoder.decodeObject(forKey: "datePlayed")
let opponent = aDecoder.decodeObject(forKey: "opponent")
let shotsFor = aDecoder.decodeObject(forKey: "shotsFor")
self.init(datePlayed: datePlayed as! Double, opponent: opponent as! String, shotsFor: shotsFor as! Int)
}
init(datePlayed: Double, opponent: String, shotsFor: Int) {
self.datePlayed = datePlayed
self.opponent = opponent
self.shotsFor = shotsFor
}
}
class league: NSObject, NSCoding {
var teamList = [team]()
var name = String()
var currentTeam = team(name: "", roster: [])
init(teamList: [team], name: String) {
self.teamList = teamList
self.name = name
}
required convenience init(coder aDecoder: NSCoder) {
let teamList = aDecoder.decodeObject(forKey: "teamList")
let name = aDecoder.decodeObject(forKey: "name")
self.init(teamList: teamList as! [team], name: name as! String)
}
func encode(with aCoder: NSCoder) {
aCoder.encode(name, forKey: "name")
aCoder.encode(teamList, forKey: "teamList")
}
}
在另一个文件中,我实例化一个联盟对象,然后尝试使用以下内容保存到用户默认值:
let newTeam = team(name: newTeamNameInput.text!, roster: [])
newTeam.name = newTeamNameInput.text!
variables.currentLeague.teamList.append(newTeam)
let userDefaults = UserDefaults.standard
let encodedData: Data = NSKeyedArchiver.archivedData(withRootObject: variables.currentLeague)
userDefaults.set(encodedData, forKey: "league")
userDefaults.synchronize()
_ = navigationController?.popViewController(animated: true)
然后尝试使用以下内容检索它:
if UserDefaults.standard.object(forKey: "league") != nil{
let decoded = userDefaults.object(forKey: "league") as! Data
variables.currentLeague = NSKeyedUnarchiver.unarchiveObject(with: decoded ) as! league
} else {
print("league does not exist")
}