json - 将字典(JSON)反序列化为快速对象

标签 json swift swift3 deserialization

我正在尝试构建一个登录函数(POST 方法),结果是一个包含用户详细信息和其他一些详细信息的 JSON。我已经创建了一个类,其中包含我需要从 POST 调用的结果中使用的所有字段。但是我遇到了将 json 反序列化为类对象的问题。有人可以帮我弄这个吗。 (我在 SO 上看到过类似的问题,并尝试使用该解决方案解决。我尝试将 json 转换为字符串,然后使用 var UserDetails = UserDetails(json:jsonString) 转换为 swift 对象 )

我的代码:

class UserDetails {
    let token:String
    let agent_id: Int
    let user_id:Int
    let company_id:Int
    let affliate_Id:Int
    let role_id:Int
    let username: String
    let surname:String
    let lastname:String

    init(token:String,agent_id: Int,user_id:Int,company_id:Int,affliate_Id:Int,role_id:Int,username: String,surname:String,lastname:String) {
        self.token = token;
        self.agent_id = agent_id;
        self.user_id = user_id;
        self.company_id = company_id;
        self.affliate_Id = affliate_Id;
        self.role_id = role_id;
        self.username = username;
        self.surname = surname;
        self.lastname = lastname;
    } }

我的 Controller 类:

let task = session.dataTask(with: request as URLRequest) { data, response, error in
                guard data != nil else {
                    print("no data found: \(error)")
                    return
                }

                do {
                    if let json = try JSONSerialization.jsonObject(with: data!, options: []) as? NSDictionary {
                        NSLog("Login SUCCESS");
                        let prefs:UserDefaults = UserDefaults.standard
                        prefs.set(username, forKey: "USERNAME")
                        prefs.set(udid, forKey: "UDID")
                        prefs.synchronize()
                        print("Response: \(json)")

                        //var jsonString = NSString(data: json, encoding: String.Encoding.utf8)! as String
//when I tried to do the above statement, an error is thrown. Cannot convert value of type NSDictionary to expected argument type Data
                        //var person:UserDetails = UserDetails(json: jsonString)

                        self.dismiss(animated: true, completion: nil)
                    } else {
                        let jsonStr = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)// No error thrown, but not NSDictionary
                        print("Error could not parse JSON: \(jsonStr)")
                    }
                } catch let parseError {
                    print(parseError)// Log the error thrown by `JSONObjectWithData`
                    let jsonStr = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)
                    print("Error could not parse JSON: '\(jsonStr)'")
                }
            }

            task.resume()

JSON 响应:

{
  "user": {
    "token": "ABCDEFGHI",
    "agent_id": 0,
    "user_id": 151,
    "company_id": 1,
    "affiliate_Id": 0,
    "role_id": 1,
    "username": "testman1",
    "surname": "Test",
    "lastname": "man",
  },
  "menu": [
    { .....

谁能帮我解决这个问题。蒂亚

最佳答案

您应该避免使用基础类(NSDictionary 等)并使用 Swift 类型。

我还建议您向接受字典的 UserDetails 类添加一个可失败的初始化器:

class UserDetails {
    let token: String
    let agentId: Int
    let userId: Int
    let companyId: Int
    let affliateId: Int
    let roleId: Int
    let username: String
    let surname: String
    let lastname: String

    init?(dictionary: [String:Any]) {

        guard let token = dictionary["token"] as? String,
            let agentId = dictionary["agent_id"] as? Int,
            let userId = dictionary["user_id"] as? Int,
            ...  // And so on 
        else {
            return nil
        }

        self.token = token;
        self.agentId = agentId;
        self.userId = userId;
        self.companyId = companyId;
        self.affliateId = affliateId;
        self.roleId = roleId;
        self.username = username;
        self.surname = surname;
        self.lastname = lastname;
    } 
}

在你的完成 block 中:

 do {
     if let json = try JSONSerialization.jsonObject(with: data!, options: []) as? [String:Any] {

         if let userDict = json["user"] as [String:Any] {
              guard let userObject = UserDetails(dictionary:userDict) else {
                  print("Failed to create user from dictionary")
                  return
              }
              // Do something with userObject
         }
     }

  } catch let parseError {

我还冒昧地从您的属性中删除了 _,因为 _ 很恶心

关于json - 将字典(JSON)反序列化为快速对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40858642/

相关文章:

ios - View Controller 透明背景

ios - 以编程方式创建的按钮在 iPhone (Swift 3) 上弹出

java - org.apache.struts2.json.JSONException : org. hibernate.LazyInitializationException:未能延迟初始化集合

Python 请求模块 JSON 格式

ios - 寻找可扩展的 TableView 来转换我的 JSON 树结构

swift - 如何首先加载缓存数据,然后从网络加载数据

python - StremListener 在 tweepy 中不返回 JSON 数据

javascript - Angular : How to filter in views with JSON values

ios - 添加到 View 时,约束项必须是该 View (或 View 本身)的后代。

ios - UNUserNotificationCenter 不是 swift 3 中图标应用程序的干净通知?