尝试使用swift将XML从URL解析为PickerView

时间:2017-10-13 16:36:20

标签: ios swift xml nsxmlparser

我正在尝试使用XMLParser解析XML并将其放在PickerView上。这是我的代码:

主要代码:

import UIKit

class ViewController: UIViewController, XMLParserDelegate {
    @IBOutlet weak var containerView: UIView!
    @IBOutlet weak var pickerView: UIPickerView!
    @IBOutlet weak var Image: UIImageView!
    @IBOutlet weak var Button: UIButton!

    var arrayCategorias = [Categories]()

    var parser = XMLParser()

    override func viewDidLoad() {
        super.viewDidLoad()

        let urlString = URL(string: "http://thecatapi.com/api/categories/list")
        self.parser = XMLParser(contentsOf: urlString!)!
        let success:Bool = self.parser.parse()
        parser.delegate = self
        if success {
            print("success")
        } else {
            print("parse failure!")
        }

        print(arrayCategorias.count)
    }

    @IBAction func botonPulsado(_ sender: Any) {
    }

    func parser(_ parser: XMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String]) {
        if(elementName=="category")
        {
            let categoria = Categories()
            for string in attributeDict {
                let strvalue = string.value as NSString
                switch string.key {
                case "id":
                    categoria.id = strvalue.integerValue
                    break
                case "name":
                    categoria.name = strvalue as String
                    break
                default:
                    break
                }
            }
            arrayCategorias.append(categoria)
        }

        func parser(_ parser: XMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) {
        }

        func parser(_ parser: XMLParser, foundCharacters string: String) {
        }

        func parser(_ parser: XMLParser, parseErrorOccurred parseError: Error) {
            print("failure error: ", parseError)
        }
    }
}        

班级类别代码:

import Foundation

class Categories{
     var id: Int = 0
     var name: String = ""
 }        

我不知道究竟是什么问题,但是当我尝试阅读arrayCategorias()只是为了查看是否有任何数据时,它只显示我0.我在哪里发现错误,它显示我:“解析失败”。

如果有人可以帮助我,我只是一个Android程序员而且我不知道它为什么不起作用。

我需要帮助将数据放在PickerView上。

1 个答案:

答案 0 :(得分:0)

有很多问题:

  1. 您在解析后设置了delegate,而在拨打parse()之前必须这样做。

  2. 您在didStartElement内部实施了一些委托方法。这些必须是解析器委托的顶级方法。

  3. 轻微不相关的问题,但您的班级名称Categories不太正确,因为它代表一个“类别”,而不是很多。所以我将其重命名为Category。 (我个人也认为它是struct,但这取决于你。)

  4. 您的idname值不是category元素的属性。它们是自己的元素,因此您必须单独解析它们(使用foundCharacters并在Category的{​​{1}}上构建didEndElement对象。

  5. 类别的category似乎是一个整数,因此我将id id改为Category

    < / LI>
  6. 您正在使用主线程中的网址Int调用parse()。这是不可取的,因为你在执行请求时阻塞了主线程。就个人而言,我使用XMLParser异步请求数据,在后台队列上处理数据,并仅将模型对象和UI更新的最终更新分派给主队列。

    就个人而言,我自己采用异步模式与URLSession完成处理程序,以帮助隔离在解析自身解析后触发的UI更新

  7. 风格问题,但我不会将所有这些@escaping代码放在视图控制器中。至少,把它放在一个扩展中,以便组织得很好。更好的是,在single responsibility principle的精神中定义一个独立的解析器委托对象,并确保在UI可能引用它时不会意外更新视图控制器模型对象。它可以更安全地确保线程安全,并使代码更好地封装。

  8. 将这些全部拉到一起,你可以做类似的事情:

    XMLParserDelegate