【问题标题】:I show an error message when I parse XML解析 XML 时显示错误消息
【发布时间】:2018-02-18 06:36:42
【问题描述】:

我是 Swift 编程的新手。我有 2 个类来解析 RSS 并显示数据。它被命名为ParseRSSFeedDetailVC。但是当我想解析时,我看不到TableView 中的数据。

但是如果我在DetailVC 中调用XMLParserDelegate 的方法,它就可以工作。可能是我在调用另一个类的方法时犯了一个错误。

我的代码如下。

我忽略了什么?

ParseRSSFeeds 类解析 XML

import UIKit

class ParseRSSFeeds: XMLParser, XMLParserDelegate{
    var parser = XMLParser()
    var news = NSMutableArray()
    var elements = NSMutableDictionary()
    var element = NSString()
    var header = NSMutableString()
    var link = NSMutableString()
    var desc = NSMutableString()
    var date = NSMutableString()

    func parseFromUrl(){
        news = []
        parser = XMLParser(contentsOf: NSURL(string: "https://www.wired.com/feed/rss")! as URL)!
        parser.delegate = self
        parser.parse()
    }

    func parser(_ parser: XMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String] = [:]) {
        element = elementName as NSString

        if (elementName as NSString) .isEqual(to: "item") {
            elements = NSMutableDictionary()
            elements = [:]
            header = NSMutableString()
            header = ""
            link = NSMutableString()
            link = ""
            desc = NSMutableString()
            desc = ""
            date = NSMutableString()
            date = ""
        }
    }

    func parser(_ parser: XMLParser, foundCharacters string: String) {
        if element .isEqual(to: "title"){
            header.append(string)
        }else if element .isEqual(to: "link"){
            link.append(string)
        }else if element .isEqual(to: "description"){
            desc.append(string)
        }else if element .isEqual(to: "pubDate") {
            date.append(string)
        }
    }

    func parser(_ parser: XMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) {
        if (elementName as NSString) .isEqual(to: "item") {
            if !header .isEqual(nil) {
                elements.setObject(header, forKey: "title" as NSCopying)
            }
            if !link .isEqual(nil) {
                elements.setObject(link, forKey: "link" as NSCopying)
            }
            if !desc .isEqual(nil) {
                elements.setObject(desc, forKey: "description" as NSCopying)
            }
            if !date .isEqual(nil) {
                elements.setObject(date, forKey: "pubDate" as NSCopying)
            }

            news.add(elements)
        }
    }
}

DetailVC(它包括显示 RSS 提要的表格视图。)

import UIKit

class DetailVC: UIViewController, UITableViewDelegate, UITableViewDataSource {
    @IBOutlet weak var tblNews: UITableView!

    let parser = ParseRSSFeeds()

    override func viewDidLoad() {
        super.viewDidLoad()

        ParseRSSFeeds().parseFromUrl()
        tblNews.reloadData()
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return parser.news.count - parser.news.count + 5
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        var cell = tblNews.dequeueReusableCell(withIdentifier: "cell", for: indexPath)

        if cell .isEqual(NSNull.self) {
            cell = Bundle.main.loadNibNamed("cell", owner: self, options: nil)?[0] as! UITableViewCell
        }

        cell.textLabel?.text = (parser.news.object(at: indexPath.row) as AnyObject).value!(forKey: "title") as? String
        cell.detailTextLabel?.text = (parser.news.object(at: indexPath.row) as AnyObject).value!(forKey: "description") as? String

        return cell
    }
}

【问题讨论】:

  • 这个声明parser.news.count - parser.news.count + 5的目的是什么?它永远是 5
  • 将其更改为仅parser.news.count
  • 这段代码存在一些不相关的问题: 1. 不要从URL解析,因为它会执行同步网络请求,在请求进行时阻塞主线程。您应该使用URLSession 异步检索数据,然后从Data 解析它。或者,如果您应该在后台线程上执行此操作,然后将 UI 更新分派到主线程。 2. 您应该删除删除所有这些对NS 类的引用并使用它们的 Swift 等价物。例如。将if (elementName as NSString) .isEqual(to: "item") { ... } 替换为if elementName == "item" { ... }

标签: ios swift xml-parsing


【解决方案1】:

您有两个ParseRSSFeeds 实例,一个是parser 属性,另一个是您在viewDidLoad 中创建的。因此,viewDidLoad 正在创建 ParseRSSFeeds 的第二个实例,请求并解析响应,然后丢弃这些结果,保持单独的 parser 属性不变。

您应该让viewDidLoad 引用parser 属性,而不是创建ParseRSSFeeds 的新实例:

override func viewDidLoad() {
    super.viewDidLoad()

    parser.parseFromUrl()
    ...
}

【讨论】:

  • 小小不同,大不同 :) 谢谢。
猜你喜欢
  • 1970-01-01
  • 2016-06-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-12
相关资源
最近更新 更多