如何将 json 字典解码为我想要的结构并使用该数据填充我的表视图

How do I decode json Dictionary into a struct that I want and use that data to populate my Table View

提问人:bumblebee 提问时间:9/19/2023 最后编辑:Brian Tompsett - 汤莱恩bumblebee 更新时间:11/22/2023 访问量:40

问:

我有一个数据模型,它是一个结构体,我有一个具有 JSON 字典的 API。我需要用字典中的值填充我的表视图单元格。我已经创建了一个包含键值的数组,以将其传递给视图控制器中的一个标签。我有一个文本字段和一个标签,我希望显示来自 API 的数据与包含键的数组中的数组元素相对应。

这是我的视图控制器 [已编辑] ;

import UIKit

class FirstViewController: UIViewController {
    
    
    @IBOutlet weak var DataTable: UITableView!
    
    var UserArr = ["ID", "UID", "Password", "First Name", "Last Name", "Username", "Email", "Avatar", "Gender", "Phone Number", "Social Insurance Number", "Date Of Birth", "Employment", "Address", "Zip Code", "State", "Country", "Coordinates", "CC Number", "Subscription"]
    
    var userDataFromApi = [UserData]()
    
    
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        NetworkManager.sharedInstance.fetchData{
            apiData in
            self.userDataFromApi = apiData
            DispatchQueue.main.async { [self] in
                DataTable.reloadData()
            }
        }
        
        DataTable.dataSource = self
        DataTable.delegate = self
                       
        
    }
            
}

extension FirstViewController : UITableViewDelegate,UITableViewDataSource {
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return userDataFromApi.count
    }
   
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        
        let cell = DataTable.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! DataTableViewCell
        
        let rowdata = userDataFromApi[indexPath.row]
        cell.txtLabel.text = UserArr[indexPath.row]
        cell.txtField.text = rowdata.first_name
        return cell
    }
    
    
}

我的数据模型

import Foundation

struct UserData : Codable {        
    let id : Int
    let uid : String
    let password : String
    let first_name : String
    let last_name : String
    let username : String
    let email : String
    let avatar : String
    let gender : String
    let phone_number : String
    let social_insurance_number : String
    let date_of_birth : String
    let employment : Employment
    
    
    struct Employment : Codable {
        let title : String
        let key_skill: String
    }
    
    
    let address : Address
    struct Address : Codable {
        let city : String
        let street_name : String
        let street_address : String
        let zip_code : String
        let state : String
        let country : String
        let coordinates : Coordinates
        struct Coordinates : Codable {
            let lat : Double
            let lng : Double
        }
    }
    
    
    let credit_card : Credit_card
    struct Credit_card : Codable {
        let cc_number : String
    }
    
    let subscription : Subscription?
    struct Subscription : Codable {
        let plan : String
        let status : String
        let payment_method : String
        let term : String
    }
            
}

我在哪里发出 API 请求

import Foundation
import Alamofire

class NetworkManager {
    static let sharedInstance = NetworkManager()
    private init() {
        
    }
    
    func fetchData(handler: @escaping (_ apiData :[UserData]) -> (Void)){
        guard let url = URL(string: "https://random-data-api.com/api/v2/users")
        else {
            return
            
        }
        AF.request(url, method: .get, parameters: nil, encoding: URLEncoding.default, headers: nil, interceptor: nil) .response  { resp in
            switch resp.result {
            case  .success(let data) :
                do {
                    let json = try JSONDecoder().decode([UserData].self, from: data!)
                    print("Data is : \(json)")
                    print(type(of: json))
                    handler(json)
                }
                catch{
                    print(error)
                }
            case .failure(let error) :
                print(error.localizedDescription)
            }
                                                
        }
    }
                
}

起初我试图将其解析为数组,但它没有加载任何内容。请随时提出改进建议,因为我是学习 Swift 的初学者。

Swift UIKité alamofire jsonparser

评论

0赞 Larme 9/19/2023
您的代码似乎没有使用 .另外,你应该在得到.不相关,但是:您应该以小写字母开头命名您的 var(即使是 IBOutlets),您可以使用代替它为您进行解析。userDataFromApireloadData()userDataFromApi.responseDecodable(of:).response()
0赞 Fahim Parkar 9/19/2023
cell.txtLabel.text = UserArr[indexPath.row]. first_name这将打印名字。.休息吧,你随心所欲地处理......
0赞 bumblebee 9/19/2023
@Larme很抱歉问,但是.responseDecodable(of:)与.response()有何不同。我在 api 端有一个 json 字典,它说错误,因为它在解析时找到了字典而不是数组
0赞 Zeeshan Ahmad II 9/19/2023
首先,它是一个对象(UserData),而不是一个数组([UserData])。并在分配后在最后一行的 NetworkManager.sharedInstance.fetchData{ } 闭包内重新加载表。最后,如果仍然不起作用,请使用 json 仔细检查模型的属性名称,并键入
0赞 Larme 9/19/2023
不是打印什么吗?它应该而且你应该把它包含在你的问题中,因为现在你的错误甚至与UITableView无关,但解析......print(error)

答:

0赞 Shabnam Siddiqui 11/22/2023 #1

起初我试图将其解析为数组,但它没有加载任何内容。请随时提出改进建议,因为我是学习 Swift 的初学者。

这是因为从您的 api 中,您正在获取字典,并且您正在尝试将其存储在数组中。

您需要稍微更改您的 API 调用函数。

func fetchData(handler: @escaping (_ apiData :UserData) -> (Void)){
        guard let url = URL(string: "https://random-data-api.com/api/v2/users")
        else {
            return
            
        }
        AF.request(url, method: .get, parameters: nil, encoding: URLEncoding.default, headers: nil, interceptor: nil) .response  { resp in
            switch resp.result {
            case  .success(let data) :
                do {
                    let json = try JSONDecoder().decode(UserData.self, from: data!)
                    print("Data is : \(json)")
                    print(type(of: json))
                    handler(json)
                }
                catch{
                    print(error)
                }
            case .failure(let error) :
                print(error.localizedDescription)
            }
            
        }
    }
NetworkManager.sharedInstance.fetchData{
    apiData in
    print("api data - ",apiData)
    // you can save your data in array accordingly
}