I’m trying to save a nested Map in Swift, and it’s not working as expected. The Map structure looks something like this:
[
"racesMap": [
32904: "Races(bestTime: 1, bonusRanking: 0, countryID: 0, ...)",
32905: "Races(bestTime: 1, bonusRanking: 0, countryID: 0, ...)",
],
"userName": "Alpha",
]
let inputMap: [String: Any] = above map
defaults.set(inputMap, forKey: "keyFormapSaving")
Saving username works, but encountering an error when attempting to save the “racesMap” key. Seeking assistance to identify and resolve the issue.
Error by XCODE:
Thread 1: “Attempt to insert non-property list object {\n
32904 = “app.Races(bestTime: 1, bonusRanking: 0, countryID:
0)”;\n} for key keyFormapSaving”
Thanks @Joakim Danielson
I’ve achived it by just converting the model class to Data object and reverse it for getting
splitting my map to save like below:
func saveUserRaceData(inputMap: [String: Any]) {
do {
var mInputMap = inputMap
saveRacesMapToUserDefaults(racesMap: mInputMap["racesMap"] as! [String : Races])
mInputMap.removeValue(forKey: "racesMap")
defaults.set(mInputMap, forKey: "toud")
} catch {
print("Error: \(error)")
}
}
func saveRacesMapToUserDefaults(racesMap: [String: Races]) {
var racesData: [String: Data] = [:]
for (key, racesObject) in racesMap {
do {
let racesObjectData = try JSONEncoder().encode(racesObject)
racesData[key] = racesObjectData
} catch {
print("Error encoding Races object for key \(key): \(error)")
}
}
defaults.set(racesData, forKey: "racesMapKey")
}
To load/get data from default as one map:
func loadRacesMapFromUserDefaults() -> [String: Races] {
var racesMap: [String: Races] = [:]
// Retrieve Data from UserDefaults
if let racesData = defaults.dictionary(forKey: "racesMapKey") as? [String: Data] {
// Convert Data back to Races objects
racesMap = racesData.reduce(into: [:]) { (result, pair) in
do {
let racesObject = try JSONDecoder().decode(Races.self, from: pair.value)
result[pair.key] = racesObject
} catch {
print("Error decoding Races object for key \(pair.key): \(error)")
}
}
}
return racesMap
}
func getUserRaceData() -> [String: Any] {
var outputMap: [String: Any] = [:]
if let jsonString = defaults.dictionary(forKey: "toud") as? [String: Any] {
for (key, value) in jsonString {
outputMap[key] = value
}
outputMap["racesMap"] = loadRacesMapFromUserDefaults()
}
return outputMap
}
“…encountering an error”, what error is that? Please include it in the question.
@JoakimDanielson I’ve added that could you please look into it?
Convert the map to a custom type (struct) that conforms to Codable and convert it into Data before saving it to UserDefaults.
could you please write it as it’s difficult to get that!!!
Another option is to modify the map so it can be stored as a property list object by changing the keys for “racesMap” to strings,
"32904": "Races(...
. Then you can use the code you have as is.Show 2 more comments