Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
488 views
in Technique[技术] by (71.8m points)

ios - How to archive and unarchive custom objects in Swift? Or how to save custom object to NSUserDefaults in Swift?

I have a class

class Player {

    var name = ""

    func encodeWithCoder(encoder: NSCoder) {
        encoder.encodeObject(name)
    }

    func initWithCoder(decoder: NSCoder) -> Player {
        self.name = decoder.decodeObjectForKey("name") as String
        return self
    }

    init(coder aDecoder: NSCoder!) {
        self.name = aDecoder.decodeObjectForKey("name") as String
    }

    init(name: String) {
        self.name = name
    }
}

and i want to serialise it and save to user defaults.

First of all I'm not sure how to correctly write encoder and decoder. So for init i wrote two methods.

When i try to execute this code:

func saveUserData() {
    let player1 = Player(name: "player1")
    let myEncodedObject = NSKeyedArchiver.archivedDataWithRootObject(player1)
    NSUserDefaults.standardUserDefaults().setObject(myEncodedObject, forKey: "player")
}

app crashes and i get this message:

*** NSForwarding: warning: object 0xebf0000 of class '_TtC6GameOn6Player' does not implement methodSignatureForSelector: -- trouble ahead

What do i do wrong?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

In Swift 4 you don't need NSCoding anymore! There is a new protocol called Codable!

class Player: Codable {

    var name = ""

    init(name: String) {
        self.name = name
    }
}

And Codable also supports Enums and Structs so you can rewrite your player class to a struct if you want!

struct Player: Codable {
    let name: String
}

To save your player in Userdefaults:

let player = Player(name: "PlayerOne")
try? UserDefaults.standard.set(PropertyListEncoder().encode(player), forKey: "player")

Note: PropertyListEncoder() is a class from the framework Foundation

To Retrieve:

let encoded = UserDefault.standard.object(forKey: "player") as! Data
let storedPlayer = try! PropertyListDecoder().decode(Player.self, from: encoded)

For more information, read https://developer.apple.com/documentation/swift/codable


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...