如何在Swift 4中将JSON数据保存到UserDefaults?

4
这是我的模型类:

enter image description here

class UserRoot : Mappable {
    var success : Bool!
    var user : UserDetails!
    var error = ""

    required init?(map: Map) {

    }
    func mapping(map: Map) {
        success <- map["success"]
        user <- map["user"]
        error <- map["error"]

    }
}

成功登录后,我希望将这些数据保存在用户默认设置中,以便用户下次不需要再提供登录凭据。以下是我的代码:

class Default : NSObject{
    static func saveToSharedPrefs(user: UserDetails!) {
        let d = UserDefaults.standard
        if user != nil {
            d.set(Mapper().toJSONString(user, prettyPrint: false) , forKey: "USERDETAILS")
        } else {
            d.set(nil, forKey: "USERDETAILS")
        }
        d.synchronize()
    }
}

Mappable是什么?根据初步搜索,似乎有几个不同的第三方框架使用了该协议/类名称。每当您使用第三方框架时,都应在问题标题中包含其名称,以便其他具有该框架知识的人看到问题,并更有可能阅读/回答它。 - Duncan C
1
请注意,不应将大型/复杂数据存储到UserDefaults中。它适用于小的用户设置。您可以轻松地将数据写入文档目录中的plist中,这将是更好的方法。 - Duncan C
好的,谢谢您宝贵的建议,我会记在心里的。 - Gorib Developer
我可以将用户列表保存在plist文件中吗,DuncanC先生? - Gorib Developer
4个回答

3
请确保您的模型类继承自NSObject类,否则在运行时会崩溃。
存储数据的方法:
let data = NSKeyedArchiver.archivedData(withRootObject: <Your model class>)
UserDefaults.standard.set(data, forKey: "userDetails")

为了检索和转换数据,您可以执行以下操作:
if let data = UserDefaults.standard.value(forKey: "userDetails") as? Data {
    if let dict = NSKeyedUnarchiver.unarchiveObject(with: data) as? <Your model class> {
           print(dict)
     }
}

但它没有运行,先生。 - Gorib Developer
在获取数据时,您需要根据您的模型类将其转换为 as? [String: Any] - Mahendra
转换成什么,先生? - Gorib Developer
你的模型类将会是 UserDetails 类,并且请确保它继承自 NSObject,就像这样 class UserDetails: NSObject { .... } - Mahendra
让我们在聊天中继续这个讨论 - Mahendra
显示剩余2条评论

3

在Swift 4中,最好使用JSONEncoder将您的Swift对象编码为JSON,并使用JSONDecoder将您的JSON解码为Swift对象,在进行编码和解码之前,请确认将Codable协议应用于您的模型类。 您可以遵循来自Stack Overflow的此答案


先生,我不知道可编码的相关内容。 - Gorib Developer
开始学习和使用它,它将节省您JSON解析的时间和精力。 它非常容易学习和实现。 Swift 4中关于Codable的一切使用Swift Codable轻松解析JSON - Kazi Abdullah Al Mamun
好的,@Kazi Abdullah Al Mamun。 - Gorib Developer
2
我同意Kazi的观点。Swift 4内置支持将对象图与JSON相互映射。如果你在Google上搜索“Swift 4 Codable”,你会找到几页教程。Ray Wenderlich的网站通常有很好的内容。例如,可以尝试这个链接:https://www.raywenderlich.com/172145/encoding-decoding-and-serialization-in-swift-4 - Duncan C
好的,DuncanC先生。 - Gorib Developer

1
你可以使用Data将此JSON存储在用户默认设置中,如下所示:
let myData = NSKeyedArchiver.archivedData(withRootObject: myJson)
UserDefaults.standard.set(myData, forKey: "userJson")

let recovedUserJsonData = UserDefaults.standard.object(forKey: "userJson")
let recovedUserJson = NSKeyedUnarchiver.unarchiveObject(with: recovedUserJsonData)

编辑

你不能在NSUserDefault中存储映射器,你只能存储NSData,NSString,NSNumber,NSDate,NSArray或NSDictionary

NSKeyedArchiver将你的映射器转换为NSData,你可以将其存储到userdefault中。


好的,我会相应地进行。 - Gorib Developer
现在我写的是 let myData = NSKeyedArchiver.archivedData(withRootObject: json) 和 UserDefaults.standard.set(myData, forKey: "userJson"),而不是 'Default.saveToSharedPrefs(user: self.userDetails)'。这样可以吗? - Gorib Developer
假设userDetailsUserRoot对象,并且UserRoot继承自NSObject - dahiya_boy
让我们在聊天中继续这个讨论 - Gorib Developer

0

使用ObjectMapper pod。

class GooglePlace : Mappable {

    var id = ""
    var addressTitle = ""
    var formattedAddress = ""
    var latitude : Double?
    var longitude : Double?

 required init?(map: Map) {

    }

    func mapping(map: Map) {
        addressTitle <- map["name"]
        formattedAddress <- map["formatted_address"]
        latitude <- map["geometry.location.lat"]
        longitude <- map["geometry.location.lng"]
        id <- map["id"]
    }

}

var placesesSearchHistory : [GooglePlace]? = []

if let jsonString = placesesSearchHistory?.toJSONString(prettyPrint: true) {
//Store in UserDefaults
      UserDefaults.standard.set(jsonString, forKey: "addressSearchHistory")

} 


//retrieve from UserDefaults
 if let dataArrayString = (UserDefaults.standard.string(forKey: "addressSearchHistory")) as? String {

 if let dataObject = Mapper<GooglePlace>().mapArray(JSONString: dataArrayString)  {
                placesesSearchHistory = dataObject
            }
        }

在Swift 4+中,所有第三方JSON解析库都已经过时,取而代之的是内置的Codable协议。而且string(forKey确实返回一个可选字符串,条件downcast是多余的。 - vadian

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