Как я могу сохранить, а затем загрузить JSON в NSUserDefaults с SwiftyJSON?

В моем проекте iOS мне нужно сохранить весь JSON как пользовательские данные, а затем перезагрузить его при следующем запуске приложения. Сократить его во множество значений, а затем воссоздать JSON - не вариант, мне просто нужен какой-то сериализуемый способ сохранения всего необработанного JSON. Я пытался преобразовать его в String при выполнении json.rawString() и воссоздать его, передав полученный 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
}

7 ответов

Решение

Спасибо за ваши ответы, но они не решили мою проблему. Я наконец нашел решение, которое было действительно простым в фактах:

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

Действительно просто, но не задокументировано хорошо.

Свифт 4+

 func saveJSON(json: JSON, key:String){
    let jsonString = json.rawString()!
    defaults.setValue(jsonString, forKey: key)
    defaults.synchronize()
}

func getJSON(_ key: String)->JSON {
    var p = ""
    if let buildNumber = defaults.value(forKey: key) as? String {
        p = buildNumber
    }else {
        p = ""
    }
    if  p != "" {
        if let json = p.data(using: String.Encoding.utf8, allowLossyConversion: false) {
            return try! JSON(data: json)
        } else {
            return JSON("nil")
        }
    } else {
        return JSON("nil")
    }
}

Используйте это, если вы используете SwiftyJSON.

Я использовал следующий код, и он работает как шарм!

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]; звоните, когда хотите сохранить данные. Хотя это НЕ требуется, это может быть необходимо в экстремальных условиях, например, если приложение собирается завершить работу.

Получить из 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
    }
}

Вы должны разобрать все на Data, чтобы сохранить модель (лучше от JSON / JSONSerialization) до UserDefaults

Закодировано в Swift 5.x

Свифт 4+

Более чистая версия, предоставленная Alfi выше, для всех, кому это может понадобиться.

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

Вот быстрый пример, который работает

import SwiftyJSON
class Users{

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

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

    }
}

Я расширил Userdefaults и добавил новый var для простоты использования и согласованности моих ключей. Вот мой код:

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

Использование в моем View Controller:

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

Свифт 3

 func setObject(value:JSON ,key:String){
        let pref = UserDefaults.standard
        pref.set(value.rawString(), forKey: key)
        pref.synchronize()
 }

func getObject(key:String) -> JSON{
    let pref = UserDefaults.standard
    let string = pref.value(forKey: key) as! String
    let dataFromString = string.data(using: String.Encoding.utf8, allowLossyConversion: false)
    return JSON(data: dataFromString!)
}
Другие вопросы по тегам