Разбор XML-данных в массиве словарей и отображение в TableView - PullRequest
0 голосов
/ 24 августа 2018

В течение последних двух дней я пытался загрузить свои проанализированные данные XML в таблицу.Я успешно разбирал данные и отображал их в консоли.Однако я не смог загрузить данные в свою таблицу.Я сделал две отдельные попытки до сих пор.

Метод 1: Анализировать функции непосредственно в контроллере представления - Успешно отображенные проанализированные данные в консоли.Обратите внимание, что мои функции просмотра таблиц в настоящее время не настроены для соответствия этому методу.

Метод 2. Создайте отдельный файл .swift (XMLParse.swift) для анализа данных и (regionTableViewCell.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": "Los Angeles", "zindex": "485600"], ["id": "2841) "," name ":" San Diego "," zindex ":" 463800 "], [" id ":" 1286 "," name ":" Orange "," zindex ":" 627200 "], [" id " : "2832", "name": "Riverside", "zindex": "298200"], ["id": "3250", "name": "San Bernardino", "zindex": "257400"], [ "id": "3136", "name": "Santa Clara", "zindex": "830300"], ["id": "1510", "name": "Alameda", "zindex": "614500" ], ["id": "3017", "name": "Sacramento", "zindex": "283200"], ["id": "3159", "name": "Contra Costa", "zindex": "469500"], ["id": "1018", "name": "Fresno", "zindex": "184900"], ["id": "204", "name": "Kern", "zindex ":" 166800 "], [" id ":" 3227 "," name ":" San Francisco "," zindex ":" 983200 "], [" id ":" 2061 "," name ":" Ventura " , "zindex": "499400"], ["id": "2842", "name": "San Mateo", "zindex": "882700"], ["id": "3134", "name": "Сан-Хоакин", "zindex": "240500"], ["id": "3033", "name": "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": "Monterey", "zindex": "420400"], ["id": "1395", "name": "Solano", "zindex": "314800"] , ["id": "1325", "name": "Placer", "zindex": "393500"], ["id": "3261", "name": "San Luis Obispo", "zindex": "487400"], ["id": "3025", "name": "Santa Cruz", "zindex": "627100"], ["id": "1196", "name": "Merced"], ["id": "625", "name": "Marin", "zindex": "897500"], ["id": "418", "name": "Butte", "zindex": "222500" ], ["id": "340", "name": "Yolo", "zindex": "335800"], ["id": "2691", "name": "El Dorado", "zindex": "353900"], ["id": "1380", "name": "Shasta", "zindex": "206900"], ["id": "2354", "name": "Imperial", "zindex ":" 155500 "], [" id ":" 1156 "," name ":" Madera "," zindex ":" 187300 "], [" id ":" 580 "," name ":" Kings ", "zindex": "155100"], ["id": "255", "name": "Napa", "zindex": "490800"], ["id": "2351", "name": "Humboldt "," zindex ":" 245400 "], [" id ":" 1261 "," name ":" Nevada "," zi ndex ":" 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 "," name ":" Tehama "," zindex ":" 144300 "], [" id ":" 3020 "," name " : "San Benito", "zindex": "410100"], ["id": "2584", "name": "Tuolumne", "zindex": "205100"], ["id": "2643", "name": "Calaveras", "zindex": "248300"], ["id": "2548", "name": "Siskiyou", "zindex": "167600"], ["id": "829 "," name ":" Amador "], [" id ":" 1143 "," name ":" Lassen "," zindex ":" 117300 "], [" id ":" 524 "," name ": "Гленн"], ["id": "2678", "name": "Del Norte"], ["id": "952", "name": "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 "]])

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...