how to set and later get array of json objects in UserDefaults
?
My application crashes when i try to set it as follow:
import SwiftyJSON
var finalArray = [JSON]()
UserDefaults.standard.set(finalArray, forKey: "attemptedArray")
my data looks like:
[{
"marked" : 3,
"attempted" : true,
"correct" : 3,
"subject" : 1,
"status" : true,
"question" : 219,
"answer" : 32931,
"time" : 15,
"score" : 5,
"chapter" : 26
}, {
"marked" : 4,
"attempted" : true,
"correct" : 4,
"subject" : 1,
"status" : true,
"question" : 550,
"answer" : 34256,
"time" : 23,
"score" : 10,
"chapter" : 26
}, {
"marked" : 1,
"attempted" : true,
"correct" : 1,
"subject" : 1,
"status" : true,
"question" : 566,
"answer" : 34317,
"time" : 33,
"score" : 14,
"chapter" : 26
}]
UserDefaults
can't save SwiftyJSON's JSON
type. You have to save some type which they supports, in this case, you're looking for Data
.
Anyway, for saving Data
to UserDefaults
aren’t the best and you should save your Data
to file somewhere else. To achieve this, you can use FileManager
.
So, create custom model for your data instead of using JSON
and adopt Codable
to your custom model
struct Model: Codable {
var marked, correct, subject, question, answer, time, score, chapter: Int
var attempted, status: Bool
}
Then you should use this Model
as type of element inside your array (note that then you’ll need to decode your response from Data
using JSONDecoder
(see below))
var finalArray = [Model]()
then you can use JSONEncoder
for encoding your array of models to Data
which you can write to some file
do {
let encoded = try JSONEncoder().encode(finalArray)
let preferencesDirectoryURL = FileManager.default.urls(for: .libraryDirectory, in: .userDomainMask).first!.appendingPathComponent("Preferences", isDirectory: true)
let fileURL = preferencesDirectoryURL.appendingPathComponent("fileName.json")
try encoded.write(to: fileURL)
} catch { print(error) }
and JSONDecoder
for decoding Data
from saved file
do {
let preferencesDirectoryURL = FileManager.default.urls(for: .libraryDirectory, in: .userDomainMask).first!.appendingPathComponent("Preferences", isDirectory: true)
let fileURL = preferencesDirectoryURL.appendingPathComponent("fileName.json")
if let data = try? Data(contentsOf: fileURL) {
let decoded = try JSONDecoder().decode([Model].self, from: data)
}
} catch { print(error) }