在iOS開(kāi)發(fā)中,只要是涉及到網(wǎng)絡(luò)的應(yīng)用,幾乎都離不開(kāi)JSON或者XML肛著。但是目前比較常見(jiàn)的是JSON數(shù)據(jù)格式。
JSON解析
JSON解析的第三方庫(kù)有很多跺讯,我們這里只講一種第三方庫(kù)JSONKit和官方的解析方法策泣。
JSONKit
首先把JSON格式的數(shù)據(jù)轉(zhuǎn)換成String
,然后再調(diào)用JSONKit
定義的jsonStr.objectFromJSONString
方法抬吟,就可以轉(zhuǎn)換成一個(gè)字典萨咕,方便我們使用。(JSONKit
請(qǐng)自己下載)
@IBAction func extractJSONWithJSONKit() {
if let url = URL(string: urlStr) {
if let jsonStr = try? String(contentsOf: url) as NSString {
let dict = jsonStr.objectFromJSONString() as! Dictionary<String, Any>
print(dict)
show(text: "解析成功")
}
}
else {
show(text: "解析失敗")
}
}
JSONSerialization
其實(shí)官方的解析方法也非常簡(jiǎn)單火本,調(diào)用URLSession
的dataTask(with: completionHandler:)
方法危队,然后在completionHandler
回調(diào)里面就能得到我們想要的數(shù)據(jù)。如果error
不為空或者data
為nil
钙畔,意味著解析錯(cuò)誤或者服務(wù)器沒(méi)有數(shù)據(jù)茫陆,那么用return
返回∏嫖觯回調(diào)里面實(shí)在子線(xiàn)程中執(zhí)行的簿盅,所以要回到主線(xiàn)程中更新UI。
@IBAction func extractJSONWithJSONSerialization() {
if let url = URL(string: urlStr) {
let reqeust = URLRequest(url: url)
let task = URLSession.shared.dataTask(with: reqeust, completionHandler: { (data, response, error) in
if error != nil || data == nil {
DispatchQueue.main.sync { // 在主線(xiàn)程中更新UI
self.show(text: "請(qǐng)求失敗")
}
return
}
if let dict = try? JSONSerialization.jsonObject(with: data!, options: .mutableLeaves) as? Dictionary<String, Any> {
print(dict! as Any)
DispatchQueue.main.sync { // 在主線(xiàn)程中更新UI
self.show(text: "解析成功")
}
}
})
task.resume()
}
}
XML解析
XML的解析方式有兩種:1)DOM:一次性將整個(gè)文檔加載進(jìn)內(nèi)存揍魂,比較適合解析小文件桨醋,其中一個(gè)常用的第三方框架是GDataXML
;2)SAX:從根元素開(kāi)始现斋,按順序一個(gè)個(gè)元素往下解析喜最,比較適合大文件,蘋(píng)果自帶的XMLParser
就屬于這個(gè)類(lèi)型庄蹋。
XMLParser
XMLParser
是通過(guò)代理的方式實(shí)現(xiàn)的瞬内,它一邊解析迷雪,一邊通知代理。
@IBAction func extractXMLWithXMLParser() {
let path = Bundle.main.path(forResource: "info.xml", ofType: nil)!
if let data = try? NSData.init(contentsOfFile: path) as Data {
parser = XMLParser(data: data)
parser.delegate = self
parser.parse() // 開(kāi)始解析
}
}
// MARK: - XMLParserDelegate
extension ViewController: XMLParserDelegate {
// 解析到文檔開(kāi)頭調(diào)用
func parserDidStartDocument(_ parser: XMLParser) {
print("parserDidStartDocument")
}
// 解析到一個(gè)元素的開(kāi)始就會(huì)調(diào)用
func parser(_ parser: XMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String] = [:]) {
print("-------didStartElement-------")
print(elementName)
print(namespaceURI as Any)
print(attributeDict)
print("-------didStartElement-------")
}
// 解析到節(jié)點(diǎn)時(shí)調(diào)用
func parser(_ parser: XMLParser, foundCharacters string: String) {
print("-------foundCharacters-------")
print(string)
print("-------foundCharacters-------")
}
// 解析到一個(gè)元素的結(jié)尾就會(huì)調(diào)用
func parser(_ parser: XMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) {
print("-------didEndElement-------")
print(elementName)
print(namespaceURI as Any)
print(qName as Any)
print("-------didEndElement-------")
}
// 解析到文檔結(jié)尾調(diào)用
func parserDidEndDocument(_ parser: XMLParser) {
print("parserDidEndDocument")
}
}
GDataXML
我們把GDataXML
的.m
和.h
拖到項(xiàng)目中后虫蝶,需要做一下配置:
- 在
Target -> Build Phases -> Link Binary With Libraries
添加libxml2.2.tbd
- 在
Build Settings -> Header Search Paths
添加/usr/include/libxml2
- 在
Build Settings -> Other Linker Flags
添加-lxml2
- 如果
GDataXML
是MRC版本章咧,不支持ARC,需要在Build Phases -> Compile Sources
找到GDataXMLNode.m
能真,在后面的Compiler Flags
加上-fno-objc-arc
解析過(guò)程如下:
@IBAction func extractXMLWithGDataXML() {
let path = Bundle.main.path(forResource: "info.xml", ofType: nil)!
if let data = try? NSData(contentsOfFile: path) as Data {
// 加載整個(gè)XML
if let doc = try? GDataXMLDocument(data: data, options: 0) {
// 獲取根節(jié)點(diǎn)
let rootDoc = doc.rootElement()!
// 獲取所有city節(jié)點(diǎn)
if let cities = rootDoc.elements(forName: "city") as? [GDataXMLElement] {
for city in cities {
// 獲取name節(jié)點(diǎn)
let name = city.elements(forName: "name").first as! GDataXMLElement
print(name.stringValue())
}
}
}
}
}
Demo地址 >>
如果文中有錯(cuò)誤赁严,請(qǐng)指出!我們共同學(xué)習(xí)舟陆,共同進(jìn)步误澳。謝謝耻矮!