具有其他自定义类变量的自定义对象的NSUserDefaults

时间:2016-09-25 06:09:59

标签: ios swift xcode nsuserdefaults nscoder

我试过看看有关NSUserDefaults的其他答案,但到目前为止他们还没有帮助。

我试图将播放器保存到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
}

现在我在保存时出错,我假设是在Player类中保存项目和Pokemon变量。

1 个答案:

答案 0 :(得分:2)

实际上,您必须PlayerItemPokemon符合NSCoding,而不是NSCoder

符合NSCoding基本上允许您定义编码和解码符合类的对象的方法,而NSCoder子类执行实际的编码和/或解码。

您要归档Player

let encodedData = NSKeyedArchiver.archivedDataWithRootObject(Player.User.Gold)

但是,由于PlayerItemPokemon不符合NSCodingNSKeyedUnarchiver不知道如何编码它们!结果,出现错误。