【问题标题】:How to load JSON response with codable structure into tableview using Swift 4.2?如何使用 Swift 4.2 将具有可编码结构的 JSON 响应加载到 tableview 中?
【发布时间】:2019-07-13 03:17:13
【问题描述】:

我的场景,我正在尝试为我的JSON 响应创建Codable。我已经完成了codable 结构,但我不知道如何将load 转换为tableview。在这里,每当我选择多个tableview 单元格时,我都需要获取所有选定的单元格数据username 和用户ID。我不知道如何开始,请给我一些建议。

我的回应

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

我的可编码格式

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
}

【问题讨论】:

  • 你能把你的tableview的代码放上来吗?

标签: ios json swift tableview


【解决方案1】:

首先,我将您的 UserList 模型重命名为 User 和 User 仅重命名为 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
}

那么我认为在您的情况下,UITableView 的数据源数组应该只包含用户,所以...您的 User 模型。

var users = [User]()

然后您可以将此数组分配为解码响应的userList 属性

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

现在,对于确定行数的UITableView 数据源方法使用用户数

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

对于cellForRowAt,使用特定用户

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

【讨论】:

  • Dresler 能否再给我添加一个如何获取状态码的方法。
  • @devmikle 我不知道你的意思,但检查编辑的答案
  • 谢谢。我会尽力并在这里更新你:)@Robert Dresler
  • getting keyNotFound(CodingKeys(stringValue: "userList", intValue: nil), Swift.DecodingError.Context(codingPath: [], debugDescription: "No value associated with key CodingKeys(stringValue: \"userList \", intValue: nil) (\"userList\").", underlyingError: nil)) @Robert Dresler
  • @devmikle 你设置了解码器的keyDecodingStrategy 吗?
【解决方案2】:

您的 API 调用应该返回一个 Data 对象。要解析它,您可以使用:

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

调用该函数并从服务器传递您的 rawData。我的结论是你在某处有一个用户数组,所以让我们填充它

parseWelcome(dataFromServer: rawData!) { parsedData in

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

调用 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]
        ...
}

但我同意@Robert Dresler 的观点,即您的模型设计很糟糕。建议稍微重新设计一下。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-12-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-16
    • 2019-01-12
    • 1970-01-01
    • 2019-02-24
    相关资源
    最近更新 更多