My scenario, I am trying to create Codable
for my JSON
response. I have done codable
structure but I don't know how to load
it into tableview
. Here, whenever I am selecting multiple tableview
cell I need to get all selected cell data username
and userid. 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)
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.
var users = [User]()
then you can assign this array as your decoded response's userList
property
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
func numberOfSections(in tableView: UITableView) -> Int {
return users.count
}
and for cellForRowAt
use certain user
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. 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. I conclude you have a User array somewhere, so let's populate it
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
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. It is recommended to redesign it a little bit.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.