In my iPhone application (develops in SWIFT) I've got to communicate with a https service (with parameters) and needs to analyse the response.
All works ok but in some cases noticed it does NOT getting the expected result… Further analysing I found it's the problem about converting server respone data to string (NSData -> NSString)…
1). When I use UTF8 Encoding I am getting nil as converted String (responseString )
let responseString = NSString(data: data, encoding: NSUTF8StringEncoding)
2). But with ASCII encoding it's fine (Gets the correct response server provides)
let responseString = NSString(data: data, encoding: NSASCIIStringEncoding)
Following is a full sample code I am trying…
let myUrl = NSURL(string: "https://myurl.com/myservice.asp")
let request = NSMutableURLRequest(URL: myUrl!)
request.HTTPMethod = "POST"
request.timeoutInterval = 55.0
let postString = "paramone=\(para1)¶mtwo=\(para2)¶mthree=\(para3)"
// NOTE: Works ok with ASCII AND UTF8 both encoding types at this point...
// request.HTTPBody = postString.dataUsingEncoding(NSASCIIStringEncoding)
request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding)
let task = NSURLSession.sharedSession().dataTaskWithRequest(request) { data, response, error in
if (error != nil)
{
println("Error: \(error)")
println("Description: \(error.description)")
println("Domain : \(error.domain)")
println("Error code : \(error.code)")
}
else
{
//???? => ENCODING PROBLEM
// let responseString = NSString(data: data, encoding: NSASCIIStringEncoding)
let responseString = NSString(data: data, encoding: NSUTF8StringEncoding)
println("Response: \(responseString)")
}
}
task.resume()
I came across with few other POSTS explaining the same issue… But NOT sure if it's good to go with ASCII rather than UTF8…
Also I can't understand the response contains '£' sign and works ok with ASCII encoding (eventhough '£' is NOT in ASCII character Set), BUT NOT with UTF8.
Like to hear if I am missing anything or what the best way to go with this… Thanks.
Best Answer
NSASCIIStringEncoding
is documented as a strict 7-bit encoding for the ASCII values 0 .. 127. However, experiments show that when decodingNSData
to(NS)String
, it accepts arbitrary data and interprets the bytes 0 .. 255 as the Unicode characters U+0000 .. U+00FF. So when decoding,NSASCIIStringEncoding
behaves identically toNSISOLatin1StringEncoding
:This can explain why a character like "£" is decoded correctly even if it is not in the ASCII character set.
But note that this behavior is (as far as I know) not documented, so you should not rely on it. Also this does not work when encoding
(NS)String
toNSData
:If the server sends a HTTP response header with a
Content-Type = charset=...
field then you can detect the encoding automatically, see https://stackoverflow.com/a/32051684/1187415.If the server does not send the response encoding in the HTTP response header then you can only try different encodings. Frequently used encodings are
NSUTF8StringEncoding
for the UTF-8 encoding,NSWindowsCP1252StringEncoding
for the Windows-1252 encoding,NSISOLatin1StringEncoding
for the ISO-8859-1 encoding.There is also a
NSString
method which can detect the used encoding, however this requires that you write the data to a file first, see Convert TXT File of Unknown Encoding to String.