В течение последних двух дней я пытался загрузить свои проанализированные данные 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 "]])