[swift4] Read XML via XMLparser and Reflect with TableView
Code For Read XML via XMLparser and Reflect with TableView is below
Install XMLParserDelegate & Create array on Delegete Response
Once complete to read XML, Reload TableView
import UIKit
class testTableViewContoller: UIViewController, UITableViewDelegate, UITableViewDataSource,XMLParserDelegate{
@IBOutlet weak var tableView: UITableView!
//XML Feed URL
let feedUrl : NSURL = NSURL(string:"xxxxx.xml")!
//for current Element
var currentElementName : String!
//First Element name
let itemElementName : String = "item"
//Element name under item element
let nameElementName : String = "name"
let makerElementName : String = "maker"
let priceElementName : String = "price"
let typeElementName : String = "type"
let urlElementName : String = "url"
let imageElementName : String = "image"
//variable for each element
var posts:[Dictionary]!
var elements:Dictionary = [String: String]()
var element:String!
var name:String!
var maker:String!
var price:String!
var type:String!
var url:String!
var image:String!
//MARK: didload
override func viewDidLoad() {
super.viewDidLoad()
tableView.dataSource = self
tableView.delegate = self
posts = []
}
override func viewDidAppear(_ animated: Bool) {
//XMLParser Class
let parser : XMLParser = XMLParser(contentsOf: feedUrl as URL)!
if parser != nil {
// XMLParserDelegate setup
parser.delegate = self;
parser.parse()
//print("parser.parse")
} else {
// Fail to parse
print("failed to parse XML")
}
}
//Start to read XML
func parserDidStartDocument(_ parser: XMLParser) {
//print("parserDidStartDocument")
}
//Complete to read XML
func parserDidEndDocument(_ parser: XMLParser!)
{
print("reload table")
self.tableView.reloadData() //TableViewをReload
}
//Start to read each element
func parser(_ parser: XMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String]) {
self.element = elementName as String
//Initiate each variable for element once find "item" element
if (elementName as NSString).isEqual(to: self.itemElementName){
self.elements = [:]
self.name = ""
self.maker = ""
self.price = ""
self.type = ""
self.url = ""
self.image = ""
}
}
//Method when find each element on "item" element
func parser(_ parser: XMLParser, foundCharacters string: String){
if self.element.isEqual(self.nameElementName) {
self.name.append(
strip(str:string)
)
}
if self.element.isEqual(self.makerElementName) {
self.maker.append(
strip(str:string)
)
}
if self.element.isEqual(self.priceElementName) {
self.price.append(
strip(str:string)
)
}
if self.element.isEqual(self.typeElementName) {
self.type.append(
strip(str:string)
)
}
if self.element.isEqual(self.urlElementName) {
self.url.append(
strip(str:string)
)
}
if self.element.isEqual(self.imageElementName) {
self.image.append(
strip(str:string)
)
}
}
//Remove space & line break
func strip(str: String) -> String {
var strBr: String
var strSp: String
//Remove line break
strBr = str.replacingOccurrences(of:"\n", with: "")
//remove space
strSp = strBr.replacingOccurrences(of:" ", with: "")
return strSp
}
//Complete to read element
func parser(_ parser: XMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) {
if (elementName as NSString).isEqual(to: self.itemElementName) {
//set "key"&"value" into variable for element if each element is not nil
if !self.name.isEqual(nil) {
self.elements[nameElementName] = self.name
}
if !self.maker.isEqual(nil) {
self.elements[makerElementName] = self.maker
}
if !self.price.isEqual(nil) {
self.elements[priceElementName] = self.price
}
if !self.type.isEqual(nil) {
self.elements[typeElementName] = self.type
}
if !self.url.isEqual(nil) {
self.elements[urlElementName] = self.url
}
if !self.image.isEqual(nil) {
self.elements[imageElementName] = self.image
}
self.posts.append(self.elements)
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
//Amount of Cell
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if posts.count > 0{
return posts.count
}
return 10 //if posts count is 0
}
// section
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 50
}
//TableView Cell Setting
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "tableCell", for: indexPath)
let imageView = cell.contentView.viewWithTag(1) as! UIImageView
imageView.image = nil //imageView initiate
let label = cell.contentView.viewWithTag(2) as! UILabel
//Indicator for loading image
let indicator = cell.contentView.viewWithTag(3) as! UIActivityIndicatorView
indicator.startAnimating()
indicator.isHidden = true
//if posts count is not 0
if(posts.count>0){
if let name = posts[indexPath.row]["name"] {
label.text = name as? String
} else {
label.text = ""
}
//Asymmetrical image download (but need to setup cache method)
if let imageURL:String = posts[indexPath.row]["image"] {
if(!imageURL.isEmpty){
indicator.isHidden = false
let catPictureURL = URL(string: imageURL)
let session = URLSession(configuration: .default)
let downloadPicTask = session.dataTask(with: catPictureURL!) { (data, response, error) in
// The download has finished.
indicator.isHidden = true
if let e = error {
print("Error downloading cat picture: \(e)")
} else {
if let res = response as? HTTPURLResponse {
print("Downloaded cat picture with response code \(res.statusCode)")
if let imageData = data {
imageView.image = UIImage(data: imageData)
} else {
print("Couldn't get image: Image is nil")
}
} else {
print("Couldn't get response code for some reason")
}
}
}
downloadPicTask.resume()
}
}else{
//if no image
}
}
return cell
}
}