简体   繁体   English

如何使用Swift 4.2将具有可编码结构的JSON响应加载到tableview中?

[英]How to load JSON response with codable structure into tableview using Swift 4.2?

My scenario, I am trying to create Codable for my JSON response. 我的情况是,我正在尝试为JSON响应创建Codable I have done codable structure but I don't know how to load it into tableview . 我已经完成了可codable结构,但是我不知道如何将其loadtableview Here, whenever I am selecting multiple tableview cell I need to get all selected cell data username and userid. 在这里,每当我选择多个tableview单元格时,我都需要获取所有选定的单元格数据的username和用户ID。 I don't know how to start please provide me some suggestion. 我不知道如何开始,请给我一些建议。

My Response 我的回复

{
    "status": 200,
    "user_list": [
        {
            "user_id": “1234”,
            "permission": 1,
            "active": 1,
            "user": {
                "firstname": “jack”,
                "lastname": “m”
            }
        },etc,...
        ]
}

My codable formate 我的可编码伴侣

struct Welcome: Codable {
    let status: Int
    let userList: [UserList]

    enum CodingKeys: String, CodingKey {
        case status
        case userList = "user_list"
    }
}

struct UserList: Codable {
    let userID: String
    let permission, active: Int
    let user: User

    enum CodingKeys: String, CodingKey {
        case userID = "user_id"
        case permission, active, user
    }
}

struct User: Codable {
    let firstname, lastname: String
}

First, I would rename your UserList model to User and User just to Name (and rename this property just to name ... then you can rename Name 's properties) 首先,我将您的UserList模型重命名为User ,将User重命名为Name (并将此属性重命名为name……然后您可以重命名Name的属性)

struct Welcome: Codable { // you can avoid using `CodingKeys` here since you can
    let status: Int       // set `keyDecodingStrategy` of decoder which does work 
    let userList: [User]  // for you
}

struct User: Codable {
    let userId: String
    let permission, active: Int
    let name: Name

    enum CodingKeys: String, CodingKey {
        case name = "user"
        case permission, active, userId
    }
}

struct Name: Codable {
    let first, last: String
}

Then I think in your case your data source array for UITableView should contains just users, so... your User models. 然后,我认为在您的情况下, UITableView数据源数组应仅包含用户,因此...您的User模型。

var users = [User]()

then you can assign this array as your decoded response's userList property 那么您可以将此数组分配为解码后的响应的userList属性

do {
    let decoder = JSONDecoder()
    decoder.keyDecodingStrategy = .convertFromSnakeCase
    let decoded = try decoder.decode(Welcome.self, from: someData)
    self.users = decoded.userList
} catch { print(error) }

Now, for UITableView data source method which determine number of rows use count of users 现在,对于确定行数的UITableView数据源方法,使用用户数

func numberOfSections(in tableView: UITableView) -> Int {
    return users.count
}

and for cellForRowAt use certain user 对于cellForRowAt使用特定用户

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    ...
    let user = users[indexPath.row]
    // e.g. let firstname = user.name.first
    ...
}

Your API call should return a Data object. 您的API调用应返回一个Data对象。 To parse it you can use: 要解析它,您可以使用:

 func parseWelcome(dataFromServer:Data,handlerDone: @escaping (_ welcome:Welcome) ->Void) ->Void {
    do {
        let welcome = try JSONDecoder().decode(Welcome.self, from:jsonData!)
        handlerDone(welcome)
    } catch {

        // A handler could be defined here for handeling bad response from server
        print("API:An error occurred while parsing server response Welcome")
    }
}

Call the function and pass your rawData from the server. 调用该函数并从服务器传递您的rawData。 I conclude you have a User array somewhere, so let's populate it 我得出结论,您在某处有一个User数组,所以让我们填充它

parseWelcome(dataFromServer: rawData!) { parsedData in

   // Users should be an Array of Users defined by you somewhere
   users = parsedData.userList
}

Call the tableView and load the data from your users array 调用tableView并从用户数组中加载数据

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        // create a new cell if needed or reuse an old one
        let cell = tableView.dequeueReusableCell(withIdentifier: "notes", for: indexPath)

        // Construct your cell on your needs use users[indexPath.row]
        ...
}

But I agree with @Robert Dresler that you have a bad Model design. 但我同意@Robert Dresler的观点,认为您的模型设计不佳。 It is recommended to redesign it a little bit. 建议重新设计一下。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM