如何使用SwiftyJSON在NSUserDefaults中保存并加载JSON?

21
在我的iOS项目中,我需要将整个JSON作为用户数据保存起来,在下一次应用程序启动时重新加载它。 将其压缩为许多值,然后重新创建JSON不是一个选项,我只需要一些可序列化的方式来保存整个原始JSON。 我尝试通过执行json.rawString()将其转换为String并通过将获得的string传递给JSON(string)来重新创建它,但它不起作用。
我对制作这样一个简单的事情的困难感到惊讶,并对在线上关于这样一件事缺乏信息感到惊讶,所以我迫不及待地想要发现如何做到这一点:)
示例:
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
}

你确定要将它保存到NSUserDefaults吗?将JSON反序列化为数组或字典,然后将其保存到文档目录中的plist文件中,在应用程序启动时加载该文件可能会更好。 - Abizern
问题在于数据可能会发生变化,不过这是一个非常小的JSON,对我来说没问题。 - Michele Bontorno
你的 saveJSON 函数可用吗? - Nikola Lukic
是的,它能够正常工作。但是 Swift 可能已经发生了变化,我没有再尝试它是否还能正常工作。您有遇到任何问题吗? - Michele Bontorno
8个回答

24

感谢您的回答,但它们没有解决我的问题。最终我找到了解决方案,实际上非常简单:

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

非常简单,但文档不太完善。


12

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

如果您正在使用SwiftyJSON,请使用此选项。


1
非常感谢。运行得很完美。 - S.S.D

2
我使用了以下代码,它非常有效!
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"]);
}

首先尝试将硬编码字符串存储到NSUserDefaults中。

在保存数据时,也尝试调用[defaults synchronize];。虽然这不是必需的,但在极端情况下可能需要,例如应用程序即将终止。


2
从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
    }
}

为了将模型(最好使用JSON / JSONSerialization)保存到UserDefaults中,您应将所有内容解析为Data。

使用Swift 5.x编写


1

Swift 4+

这是一个更简洁的版本,适用于需要此代码的其他人。

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

0

这里有一个可行的 Swift 示例

import SwiftyJSON
class Users{

    init(){
        let yourJSON = {"name":"Deeznuts"}
        let response = JSON(yourJSON)

        // Store your 
        let httpMessage = response["name"].stringValue 

    }
}

0

我扩展了UserDefaults并添加了一个新的变量,以便更轻松地使用和保持我的键的一致性。以下是我的代码:

extension UserDefaults {
    var downloadedMarkersInfo : JSON? {
        get {
            if let jsonString = defaults.value(forKey: "markers") as? String {
                if let json = jsonString.data(using: String.Encoding.utf8, allowLossyConversion: false) {
                    return try! JSON(data: json)
                }
            }
            return nil
        }
        set {
            if let json = newValue {
                let jsonString = json.rawString()!
                defaults.setValue(jsonString, forKey: "markers")
            }
        }
    }
}

在我的视图控制器中的使用:

if let jsonData = defaults.downloadedMarkersInfo {
// Your code here.
}

请不要使用.synchronize()。它已经过时,无用,并且甚至可能会创建问题,例如如果默认域很大,则会出现滞后。您不需要它来保存,它是自动完成的并由系统完成。 - Eric Aya

-1

使用 SwiftyJSON - SWIFT 5

    var data = JSON()

    if(CustomDefaults().checkObject(key: "list2")){
        data = JSON.init(parseJSON: CustomDefaults().getObject(key: "list2") as? String ?? "")
    }
    else{
        var bomb = [JSON]()
        bomb.append(["name":"Happy","url":"google.com"])
        let finalData = JSON(bomb).rawString() ?? ""  //data.rawString() ?? ""
        CustomDefaults().setObject(value: finalData, key: "list2")
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接