How can I save and then load a JSON in NSUserDefaults with SwiftyJSON?

15,652

Solution 1

Thank you for your answers but they didn't solve my problem. I finally found the solution, which was really simple in facts:

public func loadJSON() -> JSON {
    let defaults = NSUserDefaults.standardUserDefaults()
    return JSON.parse(defaults.valueForKey("json") as! String))
    // JSON from string must be initialized using .parse()
}

Really simple but not documented well.

Solution 2

Swift 5+

 func saveJSON(json: JSON, key:String){
   if let jsonString = json.rawString() {
      UserDefaults.standard.setValue(jsonString, forKey: key)
   }
}

    func getJSON(_ key: String)-> JSON? {
    var p = ""
    if let result = UserDefaults.standard.string(forKey: key) {
        p = result
    }
    if p != "" {
        if let json = p.data(using: String.Encoding.utf8, allowLossyConversion: false) {
            do {
                return try JSON(data: json)
            } catch {
                return nil
            }
        } else {
            return nil
        }
    } else {
        return nil
    }
}

Use this if you using SwiftyJSON.

Solution 3

I used the following code and it works like a charm!

NSString *json = @"{\"person\":{\"first_name\":\"Jim\", \"last_name\":\"Bell\"}} ";
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];

if([defaults objectForKey:@"json"]== nil){
    [defaults setObject:json forKey:@"json"];
    //[defaults synchronize];
}
else{
    NSLog(@"JSON %@", [defaults objectForKey:@"json"]);
}

First try to see whether you can save a hard-coded string to the NSUserDefaults first.

Also try to call a [defaults synchronize]; call when you want to save the data. Although that is NOT required, it might be needed in extreme conditions such as if the app is about to terminate.

Solution 4

to retrieve from UserDefaults

func get(_ key: String)-> JSON? {
    
    if let standard = UserDefaults.standard.data(forKey: key), let data = try? standard.toData() {
        return JSON(data)
    } else {
        return nil
    }
}

You should parse everything to Data, in order to save model (Better from JSON / JSONSerialization) to UserDefaults

Coded In Swift 5.x

Solution 5

Swift 4+

A cleaner version to the one provided by Alfi up above, for any else that might need this.

func addUserJSONDataToUserDefaults(userData: JSON) {
    guard let jsonString = userData.rawString() else { return }
    userDefaults.set(jsonString, forKey: "user")
}

func getCachedUserJSONData() -> JSON? {
    let jsonString = userDefaults.string(forKey: "user") ?? ""
    guard let jsonData = jsonString.data(using: .utf8, allowLossyConversion: false) else { return nil }
    return try? JSON(data: jsonData)
}
Share:
15,652
Michele Bontorno
Author by

Michele Bontorno

I love to find coincidences and to match details. The greatest expression of this characteristic is somehow the fact that the two things I am most passionate about share the same word: writing. When I need something, I write a software for fulfilling it, when I have a problem, I jot down a few lines for explicating it. I couldn't imagine a life without characters. My style is clean and straight, my approach is proactive. I learned programming 16 years ago, reading the handbook of a computer which worked only with commands in BASIC language. As time passed by, I bought a real PC and I started writing software for Windows. Following trends I switched to web development. But this was just training, no big products were born out of my hands at those times. I worked last 5 years as an Android developer. In a company, for myself, for various customers. And I helped giving life to some very nice projects. In the last year I worked on iOS too, this enhanced my abilities in mobile development.

Updated on June 30, 2022

Comments

  • Michele Bontorno
    Michele Bontorno almost 2 years

    in my iOS project I need to save an entire JSON as user data and then reload it on next app launch. Squashing it into many values and then recreate the JSON is not an option, I just need some serializable way of saving the entire raw JSON. I tried to convert it to String by doing json.rawString() and recreate it by passing the obtained string to JSON(string), but it doesn't work.

    I'm both astonished by the difficulty of making such a simple thing and by the lack of informations about a thing like this online, so I can not wait to discover how to do that :)

    Example:

    public func saveJSON(j: JSON) {
        let defaults = NSUserDefaults.standardUserDefaults()
        defaults.setValue(j.rawString()!, forKey: "json")
        // here I save my JSON as a string
    }
    
    public func loadJSON() -> JSON {
        let defaults = NSUserDefaults.standardUserDefaults()
        return JSON(defaults.valueForKey("json") as! String))
        // here the returned value doesn't contain a valid JSON
    }