Reputation: 613
How can I parse an XML response from a network request using swift 5
and alamofire 5
?
This is the response I get:
<?xml version="1.0" encoding="utf-8"?>
<DataSet xmlns="http://www.bnr.ro/xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.bnr.ro/xsd nbrfxrates.xsd">
<Header>
<Publisher>National Bank of Romania</Publisher>
<PublishingDate>2020-08-12</PublishingDate>
<MessageType>DR</MessageType>
</Header>
<Body>
<Subject>Reference rates</Subject>
<OrigCurrency>RON</OrigCurrency>
<Cube date="2020-08-12">
<Rate currency="AED">1.1186</Rate>
<Rate currency="AUD">2.9324</Rate>
<Rate currency="BGN">2.4724</Rate>
<Rate currency="BRL">0.7634</Rate>
<Rate currency="CAD">3.0904</Rate>
<Rate currency="CHF">4.4964</Rate>
<Rate currency="CNY">0.5916</Rate>
<Rate currency="CZK">0.1846</Rate>
<Rate currency="DKK">0.6494</Rate>
<Rate currency="EGP">0.2566</Rate>
<Rate currency="EUR">4.8357</Rate>
<Rate currency="GBP">5.3638</Rate>
<Rate currency="HRK">0.6466</Rate>
<Rate currency="HUF" multiplier="100">1.3994</Rate>
<Rate currency="INR">0.0549</Rate>
<Rate currency="JPY" multiplier="100">3.8470</Rate>
<Rate currency="KRW" multiplier="100">0.3470</Rate>
<Rate currency="MDL">0.2478</Rate>
<Rate currency="MXN">0.1842</Rate>
<Rate currency="NOK">0.4582</Rate>
<Rate currency="NZD">2.6941</Rate>
<Rate currency="PLN">1.0966</Rate>
<Rate currency="RSD">0.0411</Rate>
<Rate currency="RUB">0.0562</Rate>
<Rate currency="SEK">0.4710</Rate>
<Rate currency="THB">0.1321</Rate>
<Rate currency="TRY">0.5637</Rate>
<Rate currency="UAH">0.1493</Rate>
<Rate currency="USD">4.1087</Rate>
<Rate currency="XAU">255.0694</Rate>
<Rate currency="XDR">5.7841</Rate>
<Rate currency="ZAR">0.2361</Rate>
</Cube>
</Body>
</DataSet>
What I need is the currency symbol and the value to be saved into an array of objects
struct CursValutar: Codable {
let curs: [Currency]
}
struct Currency: Codable {
let symbol: String
let value: Double
}
I have tried some pods, but with no success.
Upvotes: 1
Views: 601
Reputation: 12770
I suggest using a library like XMLCoder, which you can then use with Alamofire's responseDecodable
:
// Make XMLDecoder conform to Alamofire's DataDecoder protocol.
extension XMLDecoder: DataDecoder {}
// Then you can use it to decode responses.
AF.request(...).responseDecodable(of: SomeType.self, decoder: XMLDecoder()) { response in
//...
}
Upvotes: 1
Reputation: 8327
You can use XMLMapper. Your model will look like this:
struct DataSet: XMLMappable {
var nodeName: String!
var cursValutar: CursValutar?
init?(map: XMLMap) {}
mutating func mapping(map: XMLMap) {
cursValutar <- map["Body.Cube"]
}
}
struct CursValutar: XMLMappable {
var nodeName: String!
var curs: [Currency]?
init?(map: XMLMap) {}
mutating func mapping(map: XMLMap) {
curs <- map["Rate"]
}
}
struct Currency: XMLMappable {
var nodeName: String!
var symbol: String?
var value: Double?
init?(map: XMLMap) {}
mutating func mapping(map: XMLMap) {
symbol <- map.attributes["currency"]
value <- map.innerText
}
}
You can fetch and map this XML like that:
AF.request(url).responseString { (dataResponse: AFDataResponse<String>) in
switch dataResponse.result {
case .success(let xmlString):
let dataSet = XMLMapper<DataSet>().map(XMLString: xmlString)
print(dataSet?.cursValutar?.curs?.first?.value)
case .failure(let error):
print(error)
}
}
Upvotes: 2