2

I have a web service which give xml response. I want to parse and show in table. But my XMLParser delegate not called. I am newer in swift. Please help any help would be apperciated,

class ViewController: UIViewController,NSXMLParserDelegate,UITableViewDelegate {
        var element:String?
        var titles:NSMutableString?
        var link:NSMutableString?
        var tableData:NSMutableArray?
        var dict:NSMutableDictionary?
     @IBOutlet weak var table: UITableView?
        override func viewDidLoad() {
            super.viewDidLoad()
            dict = NSMutableDictionary()
            tableData = NSMutableArray()
            let url = NSURL(string: "hp?keytext=s")
            let theRequest = NSURLRequest(URL: url)

            NSURLConnection.sendAsynchronousRequest(theRequest, queue: nil, completionHandler: {(response: NSURLResponse!, data: NSData!, error: NSError!) -> Void in
                if data.length > 0 && error == nil {

                 //var   parser=NSXMLParser(data: data)
               var parser = NSXMLParser(contentsOfURL: url)
                    parser.delegate=self
                    parser.shouldResolveExternalEntities=false
                 parser.parse()
                }
            })
            // Do any additional setup after loading the view.




        }

        override func didReceiveMemoryWarning() {
            super.didReceiveMemoryWarning()
            // Dispose of any resources that can be recreated.
        }

        func tableView(tableView: UITableView?, numberOfRowsInSection section: Int) -> Int {

            // Return the number of rows in the section.
            return tableData!.count
        }

        func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! {

                  var cell = tableView.dequeueReusableCellWithIdentifier("CELL") as? UITableViewCell


            if !(cell != nil) {
                       cell = UITableViewCell(style: UITableViewCellStyle.Value1, reuseIdentifier: "CELL")}



            var a:NSString
            var b:String

            a = tableData?.objectAtIndex(indexPath.row).objectForKey("title") as NSString
            b = tableData?.objectAtIndex(indexPath.row).objectForKey("city") as NSString

            cell?.textLabel?.text=a;
             cell?.detailTextLabel?.text=b




            return cell




        }

        func tableView(tableView:UITableView, heightForRowAtIndexPath indexPath:NSIndexPath)->CGFloat

        {

            return 78;

        }


        func parser(parser: NSXMLParser, didStartElement elementName: String, namespaceURI: String, qualifiedName qName: String, attributes attributeDict: [NSObject : AnyObject]) {
            element=elementName
            if element=="restaurant"
            {
                titles=NSMutableString()
                link=NSMutableString()
            }

        }

        func parser(parser: NSXMLParser, foundCharacters string: String) {
            if element=="title"
            {
                titles?.appendString(string)
            }
            else if element=="city"
            {
                link!.appendString(string)
            }
        }


        func parser(parser: NSXMLParser, didEndElement elementName: String, namespaceURI: String, qualifiedName qName: String) {
            if elementName == "restaurant"
            {
                dict?.setValue(titles, forKeyPath: "title")
                dict?.setValue(link, forKeyPath: "city")
                tableData?.addObject(dict!)

            }
        }

        func parserDidEndDocument(parser: NSXMLParser!){

            table?.reloadData()

        }

    }

2 Answers 2

1

You don't need to use sendAsynchronousRequest in your viewDidLoad method instead of that use this code:

Declare parser variable outside of all function.

Then in your viewDidLoad method replace your code with this code:

override func viewDidLoad() {
    super.viewDidLoad()

    let url = NSURL(string: "http://images.apple.com/main/rss/hotnews/hotnews.rss")  //this is example URL

    parser = NSXMLParser(contentsOfURL: url)!
    parser.delegate = self
    parser.parse()

}

And your full code will be:

import UIKit

class ViewController: UIViewController,NSXMLParserDelegate,UITableViewDelegate, UITableViewDataSource {    //You will need UITableViewDataSource here.

    var parser : NSXMLParser = NSXMLParser()
    var element:String?
    var titles:NSMutableString?
    var link:NSMutableString?
    var tableData:NSMutableArray?
    var dict:NSMutableDictionary?

    @IBOutlet weak var table: UITableView?

    override func viewDidLoad() {
        super.viewDidLoad()

        let url = NSURL(string: "http://images.apple.com/main/rss/hotnews/hotnews.rss")

        parser = NSXMLParser(contentsOfURL: url)!
        parser.delegate = self
        parser.parse()

    }

    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

        // Return the number of rows in the section.
        return tableData!.count
    }

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

        var cell = tableView.dequeueReusableCellWithIdentifier("CELL") as? UITableViewCell


        if !(cell != nil) {
            cell = UITableViewCell(style: UITableViewCellStyle.Value1, reuseIdentifier: "CELL")}
        var a:NSString
        var b:String

        a = tableData?.objectAtIndex(indexPath.row).objectForKey("title") as! NSString
        b = tableData?.objectAtIndex(indexPath.row).objectForKey("city") as! NSString as String

        cell?.textLabel?.text = a as String;
        cell?.detailTextLabel?.text = b

        return cell!

    }

    func tableView(tableView:UITableView, heightForRowAtIndexPath indexPath:NSIndexPath)->CGFloat

    {

        return 78;

    }

    func parser(parser: NSXMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [NSObject : AnyObject]) {
        element=elementName
        if element=="restaurant"
        {
            titles=NSMutableString()
            link=NSMutableString()
        }

    }

    func parser(parser: NSXMLParser, foundCharacters string: String?) {
        if element=="title"
        {
            titles?.appendString(string!)
        }
        else if element=="city"
        {
            link!.appendString(string!)
        }
    }


    func parser(parser: NSXMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) {
        if elementName == "restaurant"
        {
            dict?.setValue(titles, forKeyPath: "title")
            dict?.setValue(link, forKeyPath: "city")
            tableData?.addObject(dict!)

        }
    }

    func parserDidEndDocument(parser: NSXMLParser){

        table?.reloadData()

    }

}

I have updated your delegate functions too.

And check that you are getting data from your URL or not.

And I suggest you to follow THIS tutorial first which will help you to understand everything.

Sign up to request clarification or add additional context in comments.

Comments

1

First thing your url is not valid url, you are passing only this string as a URL "hp?keytext=s".

Second thing put this method it will call when your parse fail.

func parser(parser: NSXMLParser, parseErrorOccurred parseError: NSError) {
        NSLog("failure error: %@", parseError)
    }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.