Search code examples
swiftalamofire

swift3 Alamofire xml data


here is data

Data: <?xml version="1.0" encoding="utf-8"?>
<string xmlns="http://192.168.80.41:8081/WebServiceTest.asmx">[
  {
    "NonCID": "n10909",
    "Name": "aaaa",
    "ClassType": "aa",
    "City": "aaa",
    "Area": "aaa",
    "Address": "aaaa",
    "TelArea": "02",
    "Tel": "29857456",
    "Latitude": 25.062047000000000,
    "Longitude": 121.495241000000000
  },
  {
    "NonCID": "n10957",
    "Name": "xxxx",
    "ClassType": "xx",
    "City": "xxx",
    "Area": "xxx",
    "Address": "xxxxx",
    "TelArea": "02",
    "Tel": "29736693",
    "Latitude": 25.061227100000000,
    "Longitude": 121.495149900000000
  },
  {
    "NonCID": "n10958",
    "Name": "xxxx",
    "ClassType": "xx",
    "City": "xxx",
    "Area": "xxx",
    "Address": "xxxx",
    "TelArea": "02",
    "Tel": "29821024",
    "Latitude": 25.061812900000000,
    "Longitude": 121.495274000000000
  }]</string>

Here is my code

Alamofire.request("http://localhost/WebServiceTest.asmx/") .responseData { response in
            debugPrint("All Response Info: \(response)")
              if let data = response.result.value, let utf8Text = String(data: data, encoding: .utf8) {
                print("Data: \(utf8Text)")

            }
        }

when I run this code get the data like i post, and i can't get the data form [{"noncid":"xxxx","Name":"bbb", ........etc }] to dictionary.

Does anyone know how can i get the data to dictionary that I can use. or have another way can do that. thanks all cheers


Solution

  • Use NSXMLParser to parse the text associated with the string XML element name. Then, once you have that text, which appears to be JSON, use NSJSONSerialization to parse the contents out of the JSON string.

    func parse(data: Data) {
        // parse the xml
    
        let parser = XMLParser(data: data)
        parser.delegate = self
        guard parser.parse() else {
            print("xml parse error: \(parser.parserError?.localizedDescription)")
            return
        }
    
        // get the parsedXMLString from
    
        guard let value = parsedXMLString, let jsonData = value.data(using: .utf8) else {
            print("cannot convert to data")
            print("string: \(parsedElementValue)")
            return
        }
    
        // try now parsing the JSON body 
    
        do {
            guard let responseObject = try JSONSerialization.jsonObject(with: jsonData) as? [[String: Any]] else {
                print("Unable to parse array of dictionaries from JSON")
                print(value)
                return
            }
    
            // use responseObject here
    
            print(responseObject)
        } catch let jsonError {
            print("Unable to parse json: \(jsonError)")
        }
    }
    

    Where you have a few properties:

    fileprivate var parsedXMLString: String?
    fileprivate var parsedElementValue: String?
    

    And you implement an extension for the XML Parser:

    extension ViewController: XMLParserDelegate {
    
        func parser(_ parser: XMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String] = [:]) {
            if elementName == "string" {
                parsedElementValue = ""
            }
        }
        func parser(_ parser: XMLParser, foundCharacters string: String) {
            parsedElementValue?.append(string)
        }
    
        func parser(_ parser: XMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) {
            if elementName == "string" {
                parsedXMLString = parsedElementValue
                parsedElementValue = nil
            }
        }
    }
    

    I must be said, though, that this is a very strange format, to see JSON inside XML. Usually you have one or the other...