过去两天,我一直在尝试将我的XML解析数据加载到表中。我已经成功解析了数据并将其显示在控制台中。但是,我无法将数据加载到表中。到目前为止,我已经做了两次单独的尝试。
方法1:直接在视图控制器中解析功能-在控制台中成功显示已解析的数据。请注意,我的tableview函数当前未设置为符合此方法。
方法2:创建一个单独的.swift文件(XMLParse.swift)来解析数据,并创建(regionTableViewViewCell.swift)必要的UILabel元素。 -当前在运行应用程序时在控制台中显示nil。
下面是这三个文件中的代码。非常感谢您能帮助我的文件配置为上述两种方法之一。我现在在xCode中工作只有两个星期,所以我确定我的代码很糟糕。如果有人愿意花时间完善我的代码并告诉我正确的编写方式,我将不胜感激。
主要ViewController和方法1:ParseDataViewController.swift
import Foundation
import UIKit
import Firebase
class ParseDataViewController: UIViewController, UITableViewDelegate,
XMLParserDelegate, UISearchBarDelegate {
@IBOutlet weak var myTableView: UITableView!
@IBOutlet weak var searchBar: UISearchBar!
@IBOutlet weak var countyLabel: UILabel!
@IBOutlet weak var zindexLabel: UILabel!
@IBOutlet weak var tableView: UITableView!
private var regionItems: [RegionItem]?
var searchActive : Bool = false
let county = ""
let recordKey = "region"
let dictionaryKeys = Set<String>(["id","name","zindex"])
// a few variables to hold the results as we parse the XML
var results: [[String: String]]! // the whole array of dictionaries
var currentDictionary: [String: String]! // the current dictionary
var currentValue: String? // the current value for one of the keys in the dictionary
override func viewDidLoad() {
super .viewDidLoad()
fetchData()
print([regionItems])
searchBar.delegate = self
self.tableView.dataSource = self
self.tableView.delegate = self
let urlString = "https://www.zillow.com/webservice/GetRegionChildren.htm?<MYZILLOWKEY>&state=ca&childtype=county"
let url = URL(string: urlString)!
let task = URLSession.shared.dataTask(with: url) { data, response, error in
guard let data = data, error == nil else {
print(error ?? "Unknown error")
return
}
let parser = XMLParser(data: data)
parser.delegate = self
if parser.parse() {
//print(self.results ?? "Unknown error")
// Search 'results' array for specific county and set the index of the currentDictionary - currently set to "Los Angeles" but would like to be able to change it based on the value from the searchbar
let currentDictionary = self.results.filter { $0["name"] == "Los Angeles" }
if currentDictionary.isEmpty {
print("No results found")
print(self.county)
} else {
let currentValue = currentDictionary[0]
let zIndex = currentValue["zindex"]
let county = currentValue["name"]
print("The median price of a home in \(county!) is $\(zIndex!).")
}
}
}
task.resume()
}
private func fetchData() {
let dataParser = DataParser()
dataParser.parseData(url: "https://www.zillow.com/webservice/GetRegionChildren.htm?<MYZILLOWKEY>&state=ca&childtype=county") { (regionItems) in
self.regionItems = regionItems
OperationQueue.main.addOperation {
self.tableView.reloadSections(IndexSet(integer: 0), with: .left)
}
}
}
// Start Element
//
// If we're starting a "record" create the dictionary that will hold the results
// If we're starting one of our dictionary keys, initialize `currentValue` (otherwise leave `nil`)
func parserDidStartDocument(_ parser: XMLParser) {
results = []
}
func parser(_ parser: XMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String] = [:]) {
if elementName == recordKey {
self.currentDictionary = [String : String]()
} else if dictionaryKeys.contains(elementName) {
self.currentValue = String()
}
}
// Found Characters
//
// If this is an element we care about, append those characters.
// If 'currentValue' still 'nil', then do nothing.
func parser(_ parser: XMLParser, foundCharacters string: String) {
self.currentValue? += string
}
// End Element
//
// If we're at the end of the whole dictionary, then save that dictionary in our array
// If we're at the end of an element that belongs in the dictionary, then save that value in the dictionary
func parser(_ parser: XMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) {
if elementName == self.recordKey {
self.results.append(self.currentDictionary)
self.currentDictionary = nil
} else if dictionaryKeys.contains(elementName) {
self.currentDictionary[elementName] = currentValue
self.currentValue = nil
}
}
// If there's an error, report it.
func parser(_ parser: XMLParser, parseErrorOccurred parseError: Error) {
print(parseError)
self.currentValue = nil
self.currentDictionary = nil
}
func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
}
func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
let county = searchBar.text
countyLabel.text = searchBar.text
print("searchText \(county!)")
}
}
// Attempted to configure the below to work with method 2
extension ParseDataViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 150
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
guard let regionItems = regionItems else {
return 0
}
return regionItems.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! RegionTableViewCell
if let item = regionItems?[indexPath.item] {
cell.item = item
}
return cell
}
}
方法2:XMLParse.swift和RegionTableViewCell.swift
struct RegionItem {
var id: String
var name: String
var zindex: String
}
class DataParser: NSObject, XMLParserDelegate {
private var regionItem: [RegionItem] = []
private var currentElement = ""
private var currentId: String = "" {
didSet {
currentId = currentId.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines)
}
}
private var currentName: String = "" {
didSet {
currentName = currentName.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines)
}
}
private var currentZindex: String = ""
{
didSet {
currentZindex = currentZindex.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines)
}
}
private var parserCompletionHandler: (([RegionItem]) -> Void)?
func parseData(url: String, completionHandler: (([RegionItem]) -> Void)?)
{
self.parserCompletionHandler = completionHandler
let request = URLRequest(url: URL(string: url)!)
let urlSession = URLSession.shared
let task = urlSession.dataTask(with: request) { (data, response, error) in
guard let data = data else {
if let error = error {
print(error.localizedDescription)
}
return
}
// Parse XML Data
let parser = XMLParser(data: data)
parser.delegate = self
parser.parse()
}
task.resume()
}
// MARK: - XML Parser Delegate
func parser(_ parser: XMLParser, didStartElement elementName: String,
namespaceURI: String?, qualifiedName qName: String?, attributes
attributeDict: [String : String] = [:]) {
currentElement = elementName
if currentElement == "region" {
currentId = ""
currentName = ""
currentZindex = ""
}
}
func parser(_ parser: XMLParser, foundCharacters string: String) {
switch currentElement {
case "id": currentId += string
case "name": currentName += string
case "zindex": currentZindex += string
default: break
}
}
func parser(_ parser: XMLParser, didEndElement elementName: String,
namespaceURI: String?, qualifiedName qName: String?) {
if currentElement == "region" {
let regionItem = RegionItem(id: currentId, name: currentName,
zindex: currentZindex)
self.regionItem.append(regionItem)
}
}
func parserDidEndDocument(_ parser: XMLParser) {
parserCompletionHandler?(regionItem)
}
func parser(_ parser: XMLParser, parseErrorOccurred parseError: Error) {
print(parseError.localizedDescription)
}
}
regionTableViewCell.swift
class RegionTableViewCell: UITableViewCell {
@IBOutlet weak var idLabel: UILabel!
@IBOutlet weak var nameLabel: UILabel!
@IBOutlet weak var zindexLabel: UILabel!
var item: RegionItem! {
didSet {
idLabel.text = item.id
nameLabel.text = item.name
zindexLabel.text = item.zindex
}
}
}
来自控制台的XML数据:
some([[[“ id”:“ 9”],[“ id”:“ 3101”,“ name”:“洛杉矶”,“ zindex”:“ 485600”],[“ id”:“ 2841 “,” name“:” San Diego“,” zindex“:” 463800“],[” id“:” 1286“,” name“:” Orange“,” zindex“:” 627200“],[” id“ :“ 2832”,“ name”:“河滨”,“ zindex”:“ 298200”],[“ id”:“ 3250”,“ name”:“圣贝纳迪诺”,“ zindex”:“ 257400”],[ “ id”:“ 3136”,“ name”:“ Santa Clara”,“ zindex”:“ 830300”],[“ id”:“ 1510”,“ name”:“ Alameda”,“ zindex”:“ 614500” ],[“ id”:“ 3017”,“ name”:“萨克拉曼多”,“ zindex”:“ 283200”],[“ id”:“ 3159”,“ name”:“ Contra Costa”,“ zindex”: “ 469500”],[“ id”:“ 1018”,“名称”:“ Fresno”,“ zindex”:“ 184900”],[“ id”:“ 204”,“名称”:“ Kern”,“ zindex “:” 166800“],[” id“:” 3227“,” name“:”旧金山“,” zindex“:” 983200“],[” id“:” 2061“,” name“:” Ventura“ ,“ zindex”:“ 499400”],[“ id”:“ 2842”,“名称”:“ San Mateo”,“ zindex”:“ 882700”],[“ id”:“ 3134”,“名称”: “圣华金”,“ zindex”:“ 240500”],[“ id”:“ 3033”,“名称”:“ Stanislaus”,“ zindex”:“ 215200”],[“ id”:“ 1396”,“ name“:” Sonoma“,” zindex“:” 485000“],[” id“:” 1442“,” name“:” Tulare“,” zindex“:” 157900“],[” id“:” 3229“,” name“:” Santa Barbara“,” zindex“:” 526500“],[” id “:” 2444“,” name“:”蒙特雷“,” zindex“:” 420400“],[” id“:” 1395“,” name“:” Solano“,” zindex“:” 314800“],[ “ id”:“ 1325”,“ name”:“ Placer”,“ zindex”:“ 393500”],[“ id”:“ 3261”,“ name”:“ San Luis Obispo”,“ zindex”:“ 487400” “],[” id“:” 3025“,”名称“:” Santa Cruz“,” zindex“:” 627100“],[” id“:” 1196“,”名称“:” Merced“],[” id“:” 625“,” name“:” Marin“,” zindex“:” 897500“],[” id“:” 418“,” name“:” Butte“,” zindex“:” 222500“], [“ id”:“ 340”,“名称”:“ Yolo”,“ zindex”:“ 335800”],[“ id”:“ 2691”,“名称”:“ El Dorado”,“ zindex”:“ 353900” “],[” id“:” 1380“,” name“:” Shasta“,” zindex“:” 206900“],[” id“:” 2354“,” name“:”帝国“,” zindex“: “ 155500”],[“ id”:“ 1156”,“名称”:“ Madera”,“ zindex”:“ 187300”],[“ id”:“ 580”,“ name”:“国王”,“ zindex “:” 155100“],[” id“:” 255“,” name“:”纳帕“,” zindex“:” 490800“],[” id“:” 2351“,” name“:”洪堡“, “ zindex”:“ 245400”],[“ id”:“ 1261”,“ name”:“内华达州”,“ zinde x“:” 372100“],[” id“:” 1415“,” name“:” Sutter“,” zindex“:” 210500“],[” id“:” 2796“,” name“:” Mendocino“ ,“ zindex”:“ 323700”],[“ id”:“ 346”,“ name”:“ Yuba”,“ zindex”:“ 181200”],[“ id”:“ 217”,“ name”:“湖”,“ zindex”:“ 174800”],[“ id”:“ 1426”,“名称”:“ Tehama”,“ zindex”:“ 144300”],[“ id”:“ 3020”,“名称” :“ San Benito”,“ zindex”:“ 410100”],[“ id”:“ 2584”,“ name”:“ Tuolumne”,“ zindex”:“ 205100”],[“ id”:“ 2643”, “名称”:“ Calaveras”,“ zindex”:“ 248300”],[“ id”:“ 2548”,“ name”:“ Siskiyou”,“ zindex”:“ 167600”],[“ id”:“ 829 “,” name“:” Amador“],[” id“:” 1143“,” name“:” Lassen“,” zindex“:” 117300“],[” id“:” 524“,” name“: “” Glenn“],[” id“:” 2678“,”名称“:” Del Norte“],[” id“:” 952“,”名称“:” Colusa“,” zindex“:” 182100“], [“ id”:“ 1329”,“ name”:“ Plumas”],[“ id”:“ 188”,“ name”:“ Inyo”,“ zindex”:“ 285700”],[“ id”:“ 2403“,” name“:” Mariposa“,” zindex“:” 241800“],[” id“:” 253“,” name“:” Mono“],[” id“:” 2056“,” name“ :“ Trinity”],[“ id”:“ 647”,“ name”:“ Modoc”],[“ id”:“ 1391”,“ name”:“ Sierra”,“ zindex”: “ 134800”],[“ id”:“ 828”,“ name”:“ Alpine”]])