Need help decoding UTF8 string coming from HTTP request in Swift.

I've got a situation with a chat app with unicode languages. When someone says Hello in Russian, I'm able to push it out to the cloud infrastructure as "Здравствуйте". I can see it in the database as "Здравствуйте". When I hit my server's API directly to get the message back, I can see "Здравствуйте" displayed clearly in the results in the browser.


But when the app receives that same API response--mind you, it's the same app that was able to accept the user input and send it up to the cloud just fine--I get: "Здравствуйте".



After doing some poking around, I found a couple of options on StackOverflow such as the following, which seemed promising, but I haven't found one that actually works yet.


let decodedString = String.init(utf8String: message.cString(using: String.Encoding.utf8)!)

let decodedString = String(utf8String: message.cString(using: .utf8)!)


There were some other options which also didn't work. I'm just bamboozled because in every other step it Just Works®. What am I doing wrong and how can I fix it?

I was just testing it with French accents, and I got a similar issue:


- Bien sûr


becomes


- Bien sûr


...at the end of the rainbow. It appears to be intact through all steps until the end. User input is fine, outbound post is fine, sitting in the DB it's fine, shows up in a browser fine, but in the app which is making the exact same REST call as the browser, it chokes.

You should try to define the conversion


        let decodedString = message.data(using: String.Encoding.utf8, allowLossyConversion: true)

I'll check this one out, but I found a different solution as well: When I made my HTTP call, I was specifying ASCII on the return data:


let result = NSString(data: data!, encoding: String.Encoding.ascii.rawValue)!


Switching to UTF8 seems to have fixed it.


let result = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)!

Yes, but you loose accents.

>> seems to have fixed it


Yes, but you should try to understand what happened.


You don't say exactly what you did, but you imply that you "uploaded" the data using a POST request that contained the data after the URL in a single string. In that case, your data was encoded for free because it was riding along with the URL.


When you used "my server's API" to retrieve the information, it came back as a separate block of raw data bytes. It was encoded by the server, but not decoded automatically at your end. That means you must decode it yourself, which also means you must find out what encoding it's in.


There are ways to find out (and, indeed, to request it in a specific encoding), but for practical purposes all modern, general-use REST APIs will encode string data in UTF-8 by default. You got to this eventually, though you would have got a bonus star for doing it in pure Swift:


     let result = String (data: data!, encoding: .utf8)!


Your original attempts to use "cString" APIs failed because a "cString" really is a C-string, which is an arbitrary sequence of non-zero bytes followed by a zero byte to mark the end. Your data didn't have any zero bytes.

Strangely, the accents work fine. I'll be looking into this more to make sure I haven't broken anything else. Thanks for the response!

Thanks for the feedback and the corrected version. This is a great help!

Need help decoding UTF8 string coming from HTTP request in Swift.
 
 
Q