【问题标题】:XMLMapper not showing result in UITableViewXMLMapper 未在 UITableView 中显示结果
【发布时间】:2021-04-11 00:54:06
【问题描述】:

我遇到了一个问题,我无法将响应数据从 XMLMapper(objectmapper)获取到 UITableView。 Tableview 显示 5 个空单元格。谁能帮我解决这个问题?

我正在尝试完成一个表格视图,其中 IDNR(字符串)显示为标签,有效性显示为 DetailTextView

最好的问候,

帕特里克

class PersonDetailsView: UITableViewController {
    
    let redirector = Redirector(behavior: .doNotFollow)
    let RequestUrl = "https://apiurlexample.com/api" 
    var personID:String = ""
    
    var schedules: [cardResult]?
    @IBOutlet weak var tableViewData: UITableView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        GetCardNumbers()
    }
    
    class cardResult: XMLMappable {
        
        var nodeName: String!
        
        var error: String?
        var cardrowset: cardRowset?
        
        required init?(map: XMLMap) {}
        
        func mapping(map: XMLMap) {
            error <- map.attributes["error"]
            cardrowset <- map["ROWSET"]
        }
    }
    //
    
    class cardRowset: XMLMappable {
        var nodeName: String!
        
        var cardrows: [cardRow]?
        
        required init?(map: XMLMap) {}
        
        func mapping(map: XMLMap) {
            cardrows <- map["ROW"]
        }
    }
    
    class cardRow: XMLMappable {
        var nodeName: String!
        
        var rcn: String?
        var valid: String?
        
        required init?(map: XMLMap) {}
        
        func mapping(map: XMLMap) {
            rcn <- map["IDNR"]
            valid <- map["VALIDITY"]
        }
    }
    
    func GetCardNumbers() {
        
        //
        class personDetails: XMLMappable {
            var nodeName: String!
            var sql: String?
            
            init() {}
            
            required init?(map: XMLMap) {}
            
            func mapping(map: XMLMap) {
                sql <- (map["sql"], XMLCDATATransform())
            }
        }
        
        let persondetails = personDetails()
        persondetails.nodeName = "query"
        persondetails.sql = "select IDNR, Validity from accesskey WHERE personid=\(personID)"
        
        
        AF.request(RequestUrl, method: .post, parameters: persondetails.toXML(), encoding: XMLEncoding.default)
            .redirect(using: redirector)
            .responseXMLObject { (response: DataResponse<cardResult, AFError>) in
                
                
                switch response.result {
                
                case .success(let value):
                    
                    debugPrint(value)
                    print("AF-Success")
                    
                case .failure(let error):
                    
                    print("AF-Error")
                    print(error)
                    
                }
            }
    }
    
    override func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }
    
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        // return the number of rows
        return 5
    }
    
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)

        let person = schedules?[indexPath.row].cardrowset?.cardrows
        cell.textLabel?.text = person?[indexPath.row].valid

        return cell
    }

【问题讨论】:

  • 收到xml数据后不就是少了一个tableViewData.reloadData()吗?
  • 我在重新加载数据时收到致命错误:线程 1:致命错误:在隐式展开可选值时意外发现 nil
  • 很确定这是因为单元格数量固定(返回 5),而您可能并不总是有数据显示 5 行。应该是return schedules?.count ?? 0

标签: swift uitableview mapping alamofire xmlmapper


【解决方案1】:

首先,最好关注 Swift 的API Design Guidelines

遵循大小写约定。类型和协议的名称是 UpperCamelCase。其他都是lowerCamelCase

此外,要在您的UITableView 中显示CardRow 元素的数组,您需要将该数组保存在视图控制器中。相反,您声明了一组 CardResult 元素,这是不正确的,因为只有一个 CardResult 对象。

话虽如此,你的视图控制器应该是这样的:

class PersonDetailsView: UITableViewController {
    
    let redirector = Redirector(behavior: .doNotFollow)
    let requestUrl = "https://apiurlexample.com/api"
    var personID: String = ""
    
    var cardRows: [CardRow] = []
    @IBOutlet weak var tableViewData: UITableView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        getCardNumbers()
    }
    
    class CardResult: XMLMappable {
        var nodeName: String!
        
        var error: String?
        var cardrowset: CardRowset?
        
        required init?(map: XMLMap) {}
        
        func mapping(map: XMLMap) {
            error <- map.attributes["error"]
            cardrowset <- map["ROWSET"]
        }
    }
    
    class CardRowset: XMLMappable {
        var nodeName: String!
        
        var cardrows: [CardRow]?
        
        required init?(map: XMLMap) {}
        
        func mapping(map: XMLMap) {
            cardrows <- map["ROW"]
        }
    }
    
    class CardRow: XMLMappable {
        var nodeName: String!
        
        var rcn: String?
        var valid: String?
        
        required init?(map: XMLMap) {}
        
        func mapping(map: XMLMap) {
            rcn <- map["IDNR"]
            valid <- map["VALIDITY"]
        }
    }
    
    func getCardNumbers() {
        class PersonDetails: XMLMappable {
            var nodeName: String!
            var sql: String?
            
            init() {}
            
            required init?(map: XMLMap) {}
            
            func mapping(map: XMLMap) {
                sql <- (map["sql"], XMLCDATATransform())
            }
        }
        
        let persondetails = PersonDetails()
        persondetails.nodeName = "query"
        persondetails.sql = "select IDNR, Validity from accesskey WHERE personid=\(personID)"
        
        
        AF.request(requestUrl, method: .post, parameters: persondetails.toXML(), encoding: XMLEncoding.default)
            .redirect(using: redirector)
            .responseXMLObject { (response: DataResponse<CardResult, AFError>) in
                switch response.result {
                case .success(let value):
                    debugPrint(value)
                    print("AF-Success")
                    
                    self.cardRows = value.cardrowset?.cardrows ?? []
                    self.tableView.reloadData()
                case .failure(let error):
                    print("AF-Error")
                    print(error)
                }
            }
    }
    
    // numberOfSections(in:) doesn't actually needed here since by default UITableView has one section
    
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        // Here you need to return the count of the cardRows array
        return cardRows.count
    }
    
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)

        let person = cardRows[indexPath.row]
        cell.textLabel?.text = person.valid

        return cell
    }
}

【讨论】:

  • 嗨@Gcharita,感谢您的回复。这会导致 indexPath.row *thread 1 上出现致命错误:致命错误:索引超出范围。
  • @patrickb100 确保在tableView(_:numberOfRowsInSection:) 函数中返回cardRows 数组的count。我认为这是你的问题。
  • 非常感谢!现在问题解决了
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-19
  • 1970-01-01
  • 2014-12-28
  • 1970-01-01
  • 2013-12-22
相关资源
最近更新 更多