使用 API 中的 JSON 填充单元格
Posted
技术标签:
【中文标题】使用 API 中的 JSON 填充单元格【英文标题】:Populate cells with JSON from API 【发布时间】:2019-06-07 01:36:48 【问题描述】:我有 2 个来自不同 API 的 JSON。
这个(活动):
"oldest": "2019-01-24T00:00:00+00:00",
"activities": [
"message": "<strong>Henrik</strong> didn't resist a guilty pleasure at <strong>Starbucks</strong>.",
"amount": 2.5,
"userId": 2,
"timestamp": "2019-05-23T00:00:00+00:00"
,
"message": "<strong>You</strong> made a manual transfer.",
"amount": 10,
"userId": 1,
"timestamp": "2019-01-24T00:00:00+00:00"
]
还有这个(用户):
[
"userId": 1,
"displayName": "Mikael",
"avatarUrl": "http://qapital-ios-testtask.herokuapp.com/avatars/mikael.jpg"
,
"userId": 6,
"displayName": "Daniel",
"avatarUrl": "http://qapital-ios-testtask.herokuapp.com/avatars/daniel.jpg"
]
里面有更多的活动和用户,但我删除了它们以使其更短。
现在,目标将是这样的:example。
我已经设置了一个MainViewController
和一个MainViewControllerCell
主视图控制器:
struct Activities: Decodable
let oldest: String
let activities: [Activity]
struct Activity: Decodable
let message: String
let amount: Float
let userId: Int
let timestamp: String
struct Users: Decodable
let avatarUrl: String
let displayName: String
let userId: Int
class MainTableViewController: UITableViewController
override func viewDidLoad()
super.viewDidLoad()
// let userJSONURLString = "https://qapital-ios-testtask.herokuapp.com/users"
let activitiesJSONURLString = "https://qapital-ios-testtask.herokuapp.com/activities?from=2016-05-23T00:00:00+00:00&to=2019-05-23T00:00:00+00:00"
// guard let userURL = URL(string: userJSONURLString) else return
guard let activitiesURL = URL(string: activitiesJSONURLString) else return
URLSession.shared.dataTask(with: activitiesURL) (data, response, err) in
guard let data = data else return
do
// Activities
let activities = try JSONDecoder().decode(Activities.self, from: data)
print(activities)
// Users
// let users = try JSONDecoder().decode([Users].self, from: data)
// print(users)
catch let jsonErr
print("Error serializing json: ", jsonErr)
.resume()
// MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int
// #warning Incomplete implementation, return the number of sections
return 0
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
// #warning Incomplete implementation, return the number of rows
return 0
MainControllerViewCell
class MainTableViewCell: UITableViewCell
@IBOutlet weak var descriptionLabel: UILabel!
@IBOutlet weak var imgView: UIImageView!
@IBOutlet weak var dateLabel: UILabel!
@IBOutlet weak var amountLabel: UILabel!
override func awakeFromNib()
super.awakeFromNib()
// Initialization code
override func setSelected(_ selected: Bool, animated: Bool)
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
如您所见,我已经可以读取 JSON。现在,我以前从未这样做过,所以我不知道哪种方法最好。
如何将userId
从Activity
连接到userId
从Users
?
如何将amount
、message
和头像连接到标签?
基本上如何使用 JSON 填充单元格以使其像示例一样?
【问题讨论】:
在你的VC中创建activities
一个属性,并返回numberOfRowsInSection
中的计数。然后实现cellforrowatindexpath
并填充每个单元格。您可以在网上找到大量示例如何做到这一点。例如:***.com/questions/33234180/…
嘿!感谢您的回复。像这样? var activities: [Activities] = []
在这种情况下,您需要访问activities.activities
以获取每个单元格的计数和数据。但是你真的需要oldest
吗?否则,您可以跳过Activities
结构,并将数据存储在Activity
结构的数组中。无论如何,每个都有时间戳,因此您始终可以从 activities
数组中提取 oldest
。
【参考方案1】:
你可以这样实现:
在您的MainControllerViewCell
中为User
添加属性
class MainTableViewCell: UITableViewCell
@IBOutlet weak var descriptionLabel: UILabel!
@IBOutlet weak var imgView: UIImageView!
@IBOutlet weak var dateLabel: UILabel!
@IBOutlet weak var amountLabel: UILabel!
var user: User?
didSet
descriptionLabel.text = user?.displayName
// etc... you set your cell's outlets in accordance to `user`s infos
然后在您的MainTableViewController
中注册已解码的用户并重新加载 tableView
class MainTableViewController: UITableViewController
var userList: [User] = []
override func viewDidLoad()
super.viewDidLoad()
let activitiesJSONURLString = "https://qapital-ios-testtask.herokuapp.com/activities?from=2016-05-23T00:00:00+00:00&to=2019-05-23T00:00:00+00:00"
guard let activitiesURL = URL(string: activitiesJSONURLString) else return
URLSession.shared.dataTask(with: activitiesURL) (data, response, err) in
guard let data = data else return
do
// Activities
let activities = try JSONDecoder().decode(Activities.self, from: data)
print(activities)
// Users
let users = try JSONDecoder().decode([Users].self, from: data)
userList = []
userList.append(users)
tableView.reloadData // reload
catch let jsonErr
print("Error serializing json: ", jsonErr)
.resume()
// MARK: - Table view data source
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
return userList.count
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
cell = dequeueReusableCell(withIdentifier: "MyCellIdentifier", for: indexPath) as! MainTableViewCell
cell.user = userList[indexPath.row]
return cell
您将您的 userList 绑定到 TableView 数据源,并且每次 URLSession 完成并且解码器工作时重新加载数据
【讨论】:
嘿!谢谢您的答复。我有一些问题:1)您为User
添加了一个属性,您的意思是Users
吗? 2) 我不需要Activity
属性吗? 3)userList.append(users)
抛出Cannot convert value of type '[Users]' to expected argument type 'Users'
1) 是的,我的意思是用户。 2)当然是你想在你的单元格中显示的任何东西。这是一个展示,您必须使其适应您的需求。 3)有一种方法可以附加两个列表。您甚至可以尝试 userList = users,它可以工作以上是关于使用 API 中的 JSON 填充单元格的主要内容,如果未能解决你的问题,请参考以下文章