NSUserDefaults для пользовательского объекта с другими пользовательскими переменными класса
Я попытался посмотреть на другие ответы, касающиеся NSUserDefaults, но пока они не помогли.
Я пытаюсь сохранить Player в NSUserDefaults, но класс Player также имеет две переменные для пользовательских классов Pokemon и Items.
Как мне сохранить и загрузить плеер? Нужно ли отдельно кодировать каждую переменную пользовательского класса и декодировать их? Я не уверен, как это будет работать.
Вот мои классы:Класс игрока
import Foundation
class Player : NSCoder {
private var steps = Int()
private var money = Int()
private var items = [Item]()
private var pokemon = [Pokemon]()
var eggArray = [Int]()
struct User {
static var Gold = Player()
}
override init(){
steps = 0
money = 0
items = [Item]()
pokemon = [Pokemon]()
eggArray = [1, 4, 7, 10, 13, 16, 19, 21, 23, 27, 29, 32, 37, 41, 43, 43, 46, 48, 50, 52, 54, 56, 58, 60, 60, 63, 66, 69, 72, 74, 77, 79, 79, 81, 83, 84, 86, 88, 90, 92, 95, 96, 98, 100, 102, 104, 108, 109, 111, 113, 114, 115, 116, 118, 120, 122, 123, 127, 128, 129, 131, 133, 133, 133, 133, 133, 137, 138, 140, 142, 143, 147, 152, 155, 158, 161, 163, 165, 167, 170, 172, 173, 174, 175, 177, 179, 183, 185, 187, 190, 191, 193, 194, 198, 200, 201, 202, 203, 204, 206, 207, 209, 211, 213, 214, 215, 216, 218, 220, 222, 223, 225, 226, 227, 228, 231, 234, 235, 236, 236, 236, 238, 239, 240, 241, 246]
}
init(steps: Int, money: Int, items: [Item], pokemon: [Pokemon], eggArray: [Int]){
self.steps = steps
self.money = money
self.items = items
self.pokemon = pokemon
self.eggArray = eggArray
}
required convenience init(coder aDecoder: NSCoder) {
let steps = aDecoder.decodeIntegerForKey("steps")
let money = aDecoder.decodeIntegerForKey("money")
let items = aDecoder.decodeObjectForKey("items") as! [Item]
let pokemon = aDecoder.decodeObjectForKey("pokemon") as! [Pokemon]
let eggArray = aDecoder.decodeObjectForKey("eggArray") as! [Int]
self.init(steps: steps, money: money, items: items, pokemon: pokemon, eggArray: eggArray)
}
func encodeWithCoder(aCoder: NSCoder) {
aCoder.encodeInteger(steps, forKey: "steps")
aCoder.encodeInteger(money, forKey: "money")
aCoder.encodeObject(items, forKey: "items")
aCoder.encodeObject(pokemon, forKey: "pokemon")
aCoder.encodeObject(eggArray, forKey: "eggArray")
}
}
Класс изделия
import Foundation
import CoreData
class Item : NSObject{
var name : String
var price : Int
init(item: NSManagedObject){
name = item.valueForKey("name") as! String
price = item.valueForKey("price") as! Int
super.init()
}
init(name: String, price: Int){
self.name = name
self.price = price
super.init()
}
}
Покемон Класс
import Foundation
import SwiftyJSON
class Pokemon : NSObject {
var dexNo = Int()
var name = String()
var type1 = String()
var type2 = String()
var hp = Int()
var atk = Int()
var def = Int()
var spatk = Int()
var spdef = Int()
var spd = Int()
var move1 = String()
var move2 = String()
var move3 = String()
var move4 = String()
var evolves = String()
var method = String()
var detail = String()
var happiness = Int()
var MAXHAPPINESS = Int()
var currentEXP = Double()
var MAXEXP = Double()
var level = Double()
var isEgg = Bool()
var stepsToHatch = Int()
override init(){
}
init(jsonNumber: Int){
let path : String = NSBundle.mainBundle().pathForResource("PKMNdata", ofType: "json") as String!
let jsonData = NSData(contentsOfFile: path) as NSData!
let readableJSON = JSON(data: jsonData, options: NSJSONReadingOptions.MutableContainers, error: nil)
currentEXP = 0
MAXEXP = 1000000
level = 1
happiness = 0
MAXHAPPINESS = 255
isEgg = true
stepsToHatch = 10000
self.dexNo = readableJSON["Pokemon"]["Pokemon\(jsonNumber)"]["DEXNO"].int!
self.name = readableJSON["Pokemon"]["Pokemon\(jsonNumber)"]["NAME"].string!
self.type1 = readableJSON["Pokemon"]["Pokemon\(jsonNumber)"]["TYPE1"].string!
self.type2 = readableJSON["Pokemon"]["Pokemon\(jsonNumber)"]["TYPE2"].string!
self.evolves = readableJSON["Pokemon"]["Pokemon\(jsonNumber)"]["EVOLVES"].string!
self.method = readableJSON["Pokemon"]["Pokemon\(jsonNumber)"]["METHOD"].string!
self.detail = readableJSON["Pokemon"]["Pokemon\(jsonNumber)"]["DETAIL"].string!
self.hp = readableJSON["Pokemon"]["Pokemon\(jsonNumber)"]["HP"].int!
self.atk = readableJSON["Pokemon"]["Pokemon\(jsonNumber)"]["ATK"].int!
self.def = readableJSON["Pokemon"]["Pokemon\(jsonNumber)"]["DEF"].int!
self.spatk = readableJSON["Pokemon"]["Pokemon\(jsonNumber)"]["SPATK"].int!
self.spdef = readableJSON["Pokemon"]["Pokemon\(jsonNumber)"]["SPDEF"].int!
self.spd = readableJSON["Pokemon"]["Pokemon\(jsonNumber)"]["SPD"].int!
self.move1 = readableJSON["Pokemon"]["Pokemon\(jsonNumber)"]["MOVE1"].string!
self.move2 = readableJSON["Pokemon"]["Pokemon\(jsonNumber)"]["MOVE2"].string!
self.move3 = readableJSON["Pokemon"]["Pokemon\(jsonNumber)"]["MOVE3"].string!
self.move4 = readableJSON["Pokemon"]["Pokemon\(jsonNumber)"]["MOVE4"].string!
}
init(dexNo: Int, name: String, type1: String, type2: String, evolves: String, method: String, detail: String, hp: Int, atk: Int, def: Int, spatk: Int, spdef: Int, spd: Int, move1: String, move2: String, move3: String, move4: String){
currentEXP = 0
MAXEXP = 1000000
level = 1
happiness = 0
MAXHAPPINESS = 255
isEgg = true
stepsToHatch = 10000
self.dexNo = dexNo
self.name = name
self.type1 = type1
self.type2 = type2
self.evolves = evolves
self.method = method
self.detail = detail
self.hp = hp
self.atk = atk
self.def = def
self.spatk = spatk
self.spdef = spdef
self.spd = spd
self.move1 = move1
self.move2 = move2
self.move3 = move3
self.move4 = move4
}
}
и две кнопки, которые я использую для вызова сохранения и загрузки (только для тестирования), есть глобальная переменная: var userDefaults = NSUserDefaults.standardUserDefaults()
если это имеет значение.
@IBAction func savePlayer(sender: UIButton) {
print("save")
userDefaults = NSUserDefaults.standardUserDefaults()
let encodedData = NSKeyedArchiver.archivedDataWithRootObject(Player.User.Gold)
userDefaults.setObject(encodedData, forKey: "player")
userDefaults.synchronize()
}
@IBAction func loadPlayer(sender: UIButton) {
print("load")
let decoded = userDefaults.objectForKey("player") as! NSData
let decodedPlayer = NSKeyedUnarchiver.unarchiveObjectWithData(decoded) as! Player
Player.User.Gold = decodedPlayer
}
Прямо сейчас я получаю сообщение об ошибке при сохранении, которое, как я полагаю, относится к сохранению переменных item и Pokemon в классе Player.
1 ответ
На самом деле, вы должны сделать Player
, Item
а также Pokemon
соответствовать NSCoding
не NSCoder
,
В соответствии с NSCoding
в основном позволяет определить способ кодирования и декодирования объекта соответствующего класса, в то время как NSCoder
Подкласс выполняет фактическое кодирование и / или декодирование.
Вы хотите заархивировать Player
:
let encodedData = NSKeyedArchiver.archivedDataWithRootObject(Player.User.Gold)
Тем не менее, так как Player
, Item
а также Pokemon
не соответствуют NSCoding
, NSKeyedUnarchiver
понятия не имеет, как их кодировать! В результате появляется ошибка.