iosxmlxml-parsingnsstringnsstringencoding

iOS: NSString(data: NSData, encoding: UInt) fails at some characters


I'm pulling an XML file over the network in my XML app. I know that the file should be encoded using ISO-8859-1.

So I try to decode it when I pull it:

func extractXMLFromHttpResponse(data: NSData) -> XMLIndexer {

    let xmlContent = NSString(data: data, encoding: NSISOLatin1StringEncoding)!

    print(xmlContent)
    return SWXMLHash.parse(xmlContent as String) 
}

Note: The XMLIndexer is from from the SWXMLHash library that makes XML parsing easier.

However when printing the NSString to my debug console, I notice that some special characters (Spanish) such as

'ñ' or 'é'

are not properly decoded.

As a result of the decoding process, I see the text instead of bytes. The first line is:

<?xml version="1.0" encoding="ISO-8859-1"?>

So I guess, I've picked the right encoding. However I don't understand why some characters can't be decoded. Am I doing something wrong when I decode the data?

The weird thing is that if I'm doing the GET request manually and view the file in the browser there are no decoding errors.

EDIT:

As TwoStraws suggested in his comment, I made the curl request. It returns me the following:

HTTP/1.1 200 OK

Cache-Control: private

Content-Length: 75030

Content-Type: text/xml

Expires: Wed, 16 Dec 2015 09:13:05 GMT

Server: Microsoft-IIS/7.5

Set-Cookie: ...; path=/

X-Powered-By: ASP.NET

Date: Wed, 16 Dec 2015 09:13:05 GMT

Even if i I do

curl -v "http://www.example.com/webserviceGetCall"

it does not state how the xml file is encoded. What does that mean? I thought that it should return the encoding as well at the Content-type description.


Solution

  • So, with some diagnosis we discovered the problem was that the server was saying one character set encoding and the XML was saying another, and iOS was struggling to reconcile this.

    The solution we used in the end was this:

    if let url = NSURL(string: "http://example.com/path/to/xml/file") {
        do {
            let str = try NSString(contentsOfURL: url, encoding: NSISOLatin1StringEncoding)
            print(str)
        } catch let e as NSError {
            print(e.localizedDescription)
        }
    }
    

    …and that worked. It's a bit of a corner case, but hopefully this will help some other poor soul who hits the same problem.