How do I parse XML web service in Swift?
Asked Answered
S

3

12

I don't know how to parse in my below code.. Can someone

func callService(usr: String, pwdCode: String) {

    let url = NSURL(string: "http://inspect.dev.cbre.eu/SyncServices/api/jobmanagement/PlusContactAuthenticationPost")
    var xmlParse:NSString  = ""
    var data : NSData!
    let request = NSMutableURLRequest(URL: url!)
    request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
     request.HTTPMethod = "POST"
    let dictionary = ["email": usr, "userPwd": pwdCode]
    var error: NSError?
    if let body = NSJSONSerialization.dataWithJSONObject(dictionary, options: nil, error: &error) {
        request.HTTPBody = body
    } else {
        println("JSON error: \(error)")
    }

    let task = NSURLSession.sharedSession().dataTaskWithRequest(request) {
        (data, response, error) in
        println(NSString(data: data, encoding: NSUTF8StringEncoding))

        // xmlParse=NSString(data: data, encoding: NSUTF8StringEncoding)!
        // let data = (xmlParse as NSString).dataUsingEncoding(NSUTF8StringEncoding)
        // NSXMLParser(data : NSData)

        // xmlParse=NSString(data: data, encoding: NSUTF8StringEncoding)!
        // xmlParse=response
        // println(xmlParse)
    }
    task.resume()

}
Shellbark answered 23/11, 2014 at 8:26 Comment(4)
BTW, it's a little unusual to see JSON request and XML response. Are you sure about that? Also, does the data returned look like valid XML?Exegetic
yes, it is ...but we need to call third party webservice from our app..so we can't change it..@rob , I am pasting me xml response below..Can you please check what could be done?Shellbark
My Xml response will be like this: <?xml version="1.0" encoding="utf-8"?><serviceresult><success>false</success><resultmessage>User not found in the system.</resultmessage></serviceresult>Shellbark
Check out my project for parsing XML easily in Swift: github.com/borchero/WebParsingCryan
E
7

You should use the NSXMLParser in your completion handler for the request:

let task = NSURLSession.sharedSession().dataTaskWithRequest(request) {
    (data, response, error) in

    if data == nil {
        println("dataTaskWithRequest error: \(error)")
        return
    }

    let parser = NSXMLParser(data: data)
    parser.delegate = self
    parser.parse()

    // you can now check the value of the `success` variable here
}
task.resume()

// but obviously don't try to use it here here

Clearly, the above assumes that you have (a) defined your view controller to conform to NSXMLParserDelegate and (b) have implemented the NSXMLParserDelegate methods, e.g. something like:

var elementValue: String?
var success = false

func parser(parser: NSXMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [NSObject : AnyObject]) {
    if elementName == "success" {
        elementValue = String()
    }
}

func parser(parser: NSXMLParser, foundCharacters string: String?) {
    if elementValue != nil {
        elementValue! += string
    }
}

func parser(parser: NSXMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) {
    if elementName == "success" {
        if elementValue == "true" {
            success = true
        }
        elementValue = nil
    }
}

func parser(parser: NSXMLParser, parseErrorOccurred parseError: NSError) {
    println("parseErrorOccurred: \(parseError)")
}
Exegetic answered 24/11, 2014 at 12:27 Comment(5)
thanks Rob..I will have a look today and let you know.Shellbark
thanks @Rob...it has resolved my issue..Just one more question..when i am printing this value on my regular function 'callService' it is giving me 'nil' ..how can i access elementValue in my method?Shellbark
Well, I nil the elementValue (so that foundCharacters will only be appending characters between the <success> and </success> tags). If you want to save it, you could theoretically create another variable, and save a copy of elementValue inside that if elementName == success statement of didEndElement. (Note, do not just remove the line that sets elementValue to nil, as that will break my routine: Save the value as I outlined above.) But I don't know why you'd feel like you need to save the value, as the success variable captures whether true was found or not...Exegetic
hi rob.Can u please give me ur email address..I wanted to give my whole code to you and check if i am missing something or not..Because when i am declaring the "success" as a global variable than it is giving me wronge resultShellbark
Put it out on gist.github.com or pastie.org or similar site…Exegetic
U
9

For anyone still looking, here is the code I used that worked quite well to convert the xml response into Dictionaries/Arrays, thanks to the SWXMLHash class...

UPDATED SWIFT 2.0

    let baseUrl = "http://www.example.com/file.xml"
    let request = NSMutableURLRequest(URL: NSURL(string: baseUrl)!)
    let session = NSURLSession.sharedSession()
    request.HTTPMethod = "GET"

    var err: NSError?

    let task = session.dataTaskWithRequest(request) {
        (data, response, error) in

        if data == nil {
            print("dataTaskWithRequest error: \(error)")
            return
        }

        let xml = SWXMLHash.parse(data)

        if let definition = xml["entry_list"]["entry"][0]["def"].element?.text {
            // ...
        }

        dispatch_async(dispatch_get_main_queue(),{
            // use main thread for UI updates
        })

    }
    task.resume()
Useless answered 31/7, 2015 at 4:57 Comment(2)
I am not able to get dictionary from xml.Mitran
Perfect solution! Only one little thing: add "!" after data in: let xml = SWXMLHash.parse(data!)Administrator
E
7

You should use the NSXMLParser in your completion handler for the request:

let task = NSURLSession.sharedSession().dataTaskWithRequest(request) {
    (data, response, error) in

    if data == nil {
        println("dataTaskWithRequest error: \(error)")
        return
    }

    let parser = NSXMLParser(data: data)
    parser.delegate = self
    parser.parse()

    // you can now check the value of the `success` variable here
}
task.resume()

// but obviously don't try to use it here here

Clearly, the above assumes that you have (a) defined your view controller to conform to NSXMLParserDelegate and (b) have implemented the NSXMLParserDelegate methods, e.g. something like:

var elementValue: String?
var success = false

func parser(parser: NSXMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [NSObject : AnyObject]) {
    if elementName == "success" {
        elementValue = String()
    }
}

func parser(parser: NSXMLParser, foundCharacters string: String?) {
    if elementValue != nil {
        elementValue! += string
    }
}

func parser(parser: NSXMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) {
    if elementName == "success" {
        if elementValue == "true" {
            success = true
        }
        elementValue = nil
    }
}

func parser(parser: NSXMLParser, parseErrorOccurred parseError: NSError) {
    println("parseErrorOccurred: \(parseError)")
}
Exegetic answered 24/11, 2014 at 12:27 Comment(5)
thanks Rob..I will have a look today and let you know.Shellbark
thanks @Rob...it has resolved my issue..Just one more question..when i am printing this value on my regular function 'callService' it is giving me 'nil' ..how can i access elementValue in my method?Shellbark
Well, I nil the elementValue (so that foundCharacters will only be appending characters between the <success> and </success> tags). If you want to save it, you could theoretically create another variable, and save a copy of elementValue inside that if elementName == success statement of didEndElement. (Note, do not just remove the line that sets elementValue to nil, as that will break my routine: Save the value as I outlined above.) But I don't know why you'd feel like you need to save the value, as the success variable captures whether true was found or not...Exegetic
hi rob.Can u please give me ur email address..I wanted to give my whole code to you and check if i am missing something or not..Because when i am declaring the "success" as a global variable than it is giving me wronge resultShellbark
Put it out on gist.github.com or pastie.org or similar site…Exegetic
R
0

I have used Class Created below To get Dictionary From XML data.

https://github.com/Bhaavik/BDXmlParser

You need To add that class and just call Below Function for Dictionary response

  let objXmlParser = BbXmlParser()
  let  dictResponse  =  objXmlParser.getdictionaryFromXmlData(data!)
                        print(dictResponse)

And here You go with dictionary. :)

Rostand answered 7/7, 2016 at 10:54 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.