Save Struct to UserDefaults

Jacob Cavin picture Jacob Cavin · Jul 3, 2017 · Viewed 32.1k times · Source

I have a struct that I want to save to UserDefaults. Here's my struct

struct Song {
    var title: String
    var artist: String
}

var songs: [Song] = [
    Song(title: "Title 1", artist "Artist 1"),
    Song(title: "Title 2", artist "Artist 2"),
    Song(title: "Title 3", artist "Artist 3"),
]

In another ViewController, I have a UIButton that appends to this struct like

@IBAction func likeButtonPressed(_ sender: Any) {   
   songs.append(Song(title: songs[thisSong].title, artist: songs[thisSong].artist))
}

I want it so that whenever the user clicks on that button also, it saves the struct to UserDefaults so that whenever the user quits the app and then opens it agian, it is saved. How would I do this?

Answer

matt picture matt · Aug 27, 2017

In Swift 4 this is pretty much trivial. Make your struct codable simply by marking it as adopting the Codable protocol:

struct Song:Codable {
    var title: String
    var artist: String
}

Now let's start with some data:

var songs: [Song] = [
    Song(title: "Title 1", artist: "Artist 1"),
    Song(title: "Title 2", artist: "Artist 2"),
    Song(title: "Title 3", artist: "Artist 3"),
]

Here's how to get that into UserDefaults:

UserDefaults.standard.set(try? PropertyListEncoder().encode(songs), forKey:"songs")

And here's how to get it back out again later:

if let data = UserDefaults.standard.value(forKey:"songs") as? Data {
    let songs2 = try? PropertyListDecoder().decode(Array<Song>.self, from: data)
}