使用 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。现在,我以前从未这样做过,所以我不知道哪种方法最好。

如何将userIdActivity 连接到userIdUsers

如何将amountmessage 和头像连接到标签?

基本上如何使用 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 填充单元格的主要内容,如果未能解决你的问题,请参考以下文章

从 json 填充单元格时表为空

按表格视图单元格

一个 html 表格单元格中的单元格填充

当必须使用同一列中的不同值填充单元格时,如何填写该列中的空白单元格?

如何根据多个单元格中的值自动填充

使用第一个空白上方单元格中的值填充非连续空白单元格