Как я могу сохранить, а затем загрузить 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!)
}