Saving Swifty JSON Array to User Defaults

saving swifty json array to user defaults

You cannot save SwiftyJSON's custom type JSON to UserDefaults but you can save the raw array because a deserialized JSON collection type is property list compliant.

Just call arrayObject on the JSON object:

GlobalVar.defaults.set(json.arrayObject, forKey: "questionArray")

how to save and retrieve json array to user default in swift?

You can store all id in UserDefaults as like below.

func fetchData(){
Alamofire.request("https://jsonplaceholder.typicode.com/users", encoding: URLEncoding.default).responseJSON {
response in
switch response.result {
case .success(let value):
let json = JSON(value)
print(json)

let ids = json.arrayValue.map { $0["id"].stringValue }
UserDefaults.standard.set(ids, forKey: "id")
case .failure(let error):
print(error)
}
}
}

Now you can access all ids as like below. wherever you want to use.

guard let ids = UserDefaults.standard.stringArray(forKey: "id") else {
print(ids)
return
}

How to save the JSON data to UserDefault in Swift?

Create a model, a struct conforming to Codable

struct Auth: Codable {
let accessToken, role: String
let auth: Bool
}

and extend UserDefaults

extension UserDefaults {
func auth(forKey defaultName: String) -> Auth? {
guard let data = data(forKey: defaultName) else { return nil }
do {
return try JSONDecoder().decode(Auth.self, from: data)
} catch { print(error); return nil }
}

func set(_ value: Auth, forKey defaultName: String) {
let data = try? JSONEncoder().encode(value)
set(data, forKey: defaultName)
}
}

Now you can use auth(forKey:) and set(_:forKey:) to read and write an Auth instance directly.

Drop SwiftyJSON and change the Alamofire part to decode the JSON into the struct with JSONDecoder

Alamofire.request("http://192.168.80.21:3204/api/auth/signin", method: .post, parameters: parameters).responseData {
response in
switch response.result {
case .success(let data):
do {
let auth = try JSONDecoder().decode(Auth.self, from: data)
print(auth)
UserDefaults.standard.set(auth, forKey: "Auth")
} catch { print(error) }

case .failure(let error):
print("Error :- \(error)")
}
}

To read the instance write

let auth = UserDefaults.standard.auth(forKey: "Auth")

Save array from JSON in user default and read array values back

I would recommend using a model object and Codable to avoid all those casts:

struct Model: Codable {
let sites: [Site]

enum CodingKeys: String, CodingKey {
case sites = "SITES"
}
}

struct Site: Codable {
let name, websiteAppid: String

enum CodingKeys: String, CodingKey {
case name = "NAME"
case websiteAppid = "WEBSITEAPPID"
}
}

// write to defaults
let model = Model(sites: [Site(name: "foo", websiteAppid: "bar")])
do {
let siteData = try JSONEncoder().encode(model)
UserDefaults.standard.set(siteData, forKey: "adminSites")
} catch {
print(error)
}

// read from defaults
if let siteData = UserDefaults.standard.data(forKey: "adminSites") {
do {
let model = try JSONDecoder().decode(Model.self, from: siteData)
for site in model.sites {
print(site.name, site.websiteAppid)
}
} catch {
print(error)
}
}

Set array of objects in UserDefaults

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) }

Save json in userDefaults

i think this line of code is wrong

if let json = self.userDefaults.value(forKey: "selectedDivisions") as? Array<Dictionary<String, Any>> 

first you need to convert json string into array object , like follows

let data = (self.userDefaults.value(forKey: "selectedDivisions") as! String).data(using: String.Encoding.utf8) as NSData?
if data == nil || data!.length == 0 {
return
} else {
do {
let resultJSON = try JSONSerialization.jsonObject(with: data! as Data, options: .mutableContainers)
if let json = resultJSON as? Array<Dictionary<String, Any>> {
// do something
}
} catch _ {
print("exception ")
}

How to save json data on userdefaults in swift 4

Make sure your model class is inherited from NSObject class otherwise it will crash at run time.

To store data:

let data = NSKeyedArchiver.archivedData(withRootObject: <Your model class>)
UserDefaults.standard.set(data, forKey: "userDetails")

To retrive and convert data back

if let data = UserDefaults.standard.value(forKey: "userDetails") as? Data {
if let dict = NSKeyedUnarchiver.unarchiveObject(with: data) as? <Your model class> {
print(dict)
}
}

How to save the JSON data in User-Defaults

if your json object parameter nil so you can not store because null is not primitive types so it can not store in user default



Related Topics



Leave a reply



Submit