我正在读取XML feed以填充tableView,我正在使用NSXMLParser来解析XML。第一次解析数据时,一切正常,我得到的表格就像我期望的那样填充。然后我设置一个计时器来定期更新服务器中的数据。当计时器触发时,我使用完全相同的方法再次解析相同的XML提要,然后它总是失败:parser.parse()返回false,但没有报告错误。我可以获得它失败的行号和列,但数据通常与它第一次解析XML时没有什么不同(并且它在那时工作)。
我在TableViewController中声明了解析器:
var parser = NSXMLParser()
在ViewDidLoad中我配置它:
let url: String = "http://www.deltatao.com/clanlord/status/cldata.xml"
let urlToSend: NSURL = NSURL(string: url)!
parser = NSXMLParser(contentsOfURL: urlToSend)!
parser.delegate = self
在ViewWillAppear中,我调用它并设置计时器:
parseClanlordInformation()
// this will remove the previous timer
timer?.invalidate()
// now start a timer to regularly update the data from the server
startTimer()
这是调用parse()的函数:
func parseClanlordInformation() {
// reset players list
players.removeAll()
// Stop the previous parsing operation in case it was still running
parser.abortParsing()
// rebuild the list from scratch
let success: Bool = parser.parse()
if !success {
let error = parser.parserError
let line = parser.lineNumber
let col = parser.columnNumber
print("XML parsing failed at \(line):\(col): \(error?.localizedDescription)")
print(players.count)
}
if parser.parserError != nil {
print("Error: parse failure!")
print(parser.parserError)
}
myTableView.reloadData()
}
定时器调用相同的功能:
func startTimer() {
timer = NSTimer.scheduledTimerWithTimeInterval(updateInterval, target: self, selector: #selector(TableViewController.parseClanlordInformation), userInfo: nil, repeats: true)
}
XML Parser代理的设置如下:
func parser(parser: NSXMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String]) {
currentElement = elementName
if elementName=="exile" || elementName=="race" || elementName=="name" || elementName=="sex" || elementName=="profession" || elementName=="clan" {
if elementName == "exile" {
foundNewPlayer = true
currentPlayer.reset()
}
passData = true
}
}
func parser(parser: NSXMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) {
currentElement = ""
if elementName=="exile" || elementName=="race" || elementName=="name" || elementName=="cost" || elementName=="description" {
if elementName == "exile" {
foundNewPlayer=false
players.append(currentPlayer)
}
passData=false
}
}
func parser(parser: NSXMLParser, foundCharacters string: String) {
if foundNewPlayer {
switch currentElement {
case "name":
currentPlayer.name = string
case "race":
var race: String
if string == "of the People" {
race = "Fen'neko"
} else {
race = String(string.characters.dropFirst(2))
}
currentPlayer.race = race
case "sex":
currentPlayer.genre = string
case "profession":
let prof = String(string.characters.dropFirst(2))
currentPlayer.profession = prof
case "clan":
currentPlayer.clan = string
default: break
}
}
}
func parser(parser: NSXMLParser, parseErrorOccurred parseError: NSError) {
print(parseError.description)
NSLog("failure error: %@", parseError)
}
当我运行应用程序时,表正常填充数据,然后当第一次更新触发时,parser.parse()在第80行,第1列或其附近返回false。
为什么它只能运作一次?是否有一些我应该做的重置,我忘了?
感谢您的帮助。
答案 0 :(得分:0)
我很确定NSXMLParser
的给定实例只能使用一次。每次要再次解析时都创建一个新实例。
func parseClanlordInformation() {
// reset players list
players.removeAll()
// Stop the previous parsing operation in case it was still running
parser.abortParsing()
// Setup new parser
let url: String = "http://www.deltatao.com/clanlord/status/cldata.xml"
let urlToSend: NSURL = NSURL(string: url)!
parser = NSXMLParser(contentsOfURL: urlToSend)!
parser.delegate = self
// rebuild the list from scratch
let success: Bool = parser.parse()
if !success {
let error = parser.parserError
let line = parser.lineNumber
let col = parser.columnNumber
print("XML parsing failed at \(line):\(col): \(error?.localizedDescription)")
print(players.count)
}
if parser.parserError != nil {
print("Error: parse failure!")
print(parser.parserError)
}
myTableView.reloadData()
}
这也意味着您可以删除viewDidLoad
中的解析器设置。