I have used the following code to encode/decode the string which has emojis.
extension String {
func encodeEmoji() -> String {
let data = self.data(using: .nonLossyASCII, allowLossyConversion: true)!
return String(data: data, encoding: .utf8)!
}
func decodeEmoji() -> String? {
let data = self.data(using: .utf8)!
return String(data: data, encoding: .nonLossyASCII)
}
}
I have called this function like this below. Converted the response in the 'User' model.
let user = User() // Loaded API's response in this model
let textWithEmoji = user.aboutMe.decodeEmoji() //Here, I am getting the string as the same as before decoding
lblAboutMe.text = textWithEmoji
Following is the encoded string which is not decoding:
"I love too...\n\u2705 Laugh \uD83D\uDE02\n\u2705 Read novels \uD83D\uDCDA\n\u2705 Watch movies \uD83C\uDFAC\n\u2705 Go for bike rides \uD83D\uDEB5\uD83C\uDFFD\u200D\u2640\uFE0F\n\u2705 Go for long walks \uD83D\uDEB6\uD83C\uDFFD\u200D\u2640\uFE0F\n\u2705 Cook \uD83D\uDC69\uD83C\uDFFD\u200D\uD83C\uDF73\n\u2705 Travel \uD83C\uDDEA\uD83C\uDDFA\uD83C\uDDEE\uD83C\uDDF3\uD83C\uDDEC\uD83C\uDDE7\n\u2705 Eat \uD83C\uDF2E\uD83C\uDF5F\uD83C\uDF73\n\u2705 Play board games \u265F\n\u2705 Go to the theatre \uD83C\uDFAD\nMy favourite season is autumn \uD83C\uDF42, i love superhero movies \uD83E\uDDB8\u200D\u2642\uFE0F and Christmas is the most wonderful time of the year! \uD83C\uDF84"
Here is the original text image:
The string you are using is invalid ("I love too...\n\u2705 Laugh \uD83D\uDE02\n\u2705 Read novels \uD83D\uDCDA\n\u2705 Watch movies \uD83C\uDFAC\n\u2705")
It should be in valid String literal
"\\uD83D\\uDCDA\\u2705"
You have a string non-BMP characters in form of JSON String. And your decodeEmoji cannot convert them into valid characters.
So we need to forcefully convert such strings.
extension String {
var jsonStringRedecoded: String? {
let data = ("\""+self+"\"").data(using: .utf8)!
let result = try! JSONSerialization.jsonObject(with: data, options: .allowFragments) as! String
return result
}
}
After that you need to decode emoji from above string using below function.
extension String {
var decodeEmoji: String? {
let data = self.data(using: String.Encoding.utf8,allowLossyConversion: false);
let decodedStr = NSString(data: data!, encoding: String.Encoding.nonLossyASCII.rawValue)
if decodedStr != nil{
return decodedStr as String?
}
return self
}
}
Usually JSON decoder can decode these type of characters into emoji
May be there is chances of invalid JSON
First need to verify these things that json is valid or not before using.
USAGE:
let jsonDecodedString = "Your string".jsonStringRedecoded
let decodedEmojiText = jsonDecodedString?.decodeEmoji
debugPrint("\(decodedEmojiText)")
Related
Twitter Api Response:
"retweet_count" = 0;
retweeted = 0;
source = "Twitter for Android";
text = "ALTIN alm\U0131\U015f ba\U015f\U0131n\U0131 gidiyor... bakal\U0131m t\U00fcrk liras\U0131 daha ne kadar de\U011fersizle\U015fecek #Turkiye #BorsaAltin\U2026 https://twitter.com/i/web/status/1216306036602277889";
truncated = 1;
My code:
let request = client.urlRequest(withMethod: "GET", urlString: statusesShowEndpoint, parameters: params, error: &clientError)
client.sendTwitterRequest(request) { (response, data, connectionError) -> Void in
if connectionError != nil {
print("Error: \(connectionError)")
}
do {
let json = try JSONSerialization.jsonObject(with: data!, options: [])
print("json: \(json)")
} catch let jsonError as NSError {
print("json error: \(jsonError.localizedDescription)")
}
}
}
how can I convert Unicode to string ? i have been don't use model.
I hope this will help.
I made a playground to test this issue. Swift will complain that the String contains incorrect escape characters.
This is a problem and the code will not compile:
Swift expect the Unicode to be formatted with ex '\u0131' or '\u{0131} but you receive the twitter API with '\U0131'
You need to "sanitise" the input first otherwise it will not work! Also when I tested the below I could not save the input in a string with the incorrect escaping. The compiler checks that the strings are correct before doing any operations on them.
I used a trick. Before saving the input from the file I split into an array of characters with map, of these characters I check with filter which one is an escaping backlash remove it and join the characters again to form a string.
Sorry but I did not find any other way, just having '\U' in my input would get Swift yelling at me.
What remains in the input string is "ALTIN almU0131U015f ..etc"
Now I need to replace those 'U0131' with '\u0131' and for this I use Regex:
And this is the final output of my String test as property of my struct after the conversion.
I apologise if my code is a bit messy but it was not easy to get past the string validation in Swift!
The below is the playground code in detail.
What I did is to create a json file with your input as a test:
Then create a struct reflecting the JSON properties, in this case only one: "test"
public struct Test: Codable {
var test = ""
}
// this is the initialisation of the empty struct to be filled from json
var unicodetest: Test = Test()
func parse(json: Data) {
let decoder = JSONDecoder()
if let testmodel = try? decoder.decode(Test.self, from: json) {
unicodetest = testmodel
print(unicodetest.test)
}
}
// Here I get my Json and parse with the above function
do {
guard let fileUrl = Bundle.main.url(forResource: "test", withExtension: "json") else { fatalError() }
let input = try String(contentsOf: fileUrl, encoding: String.Encoding.utf8).map {String($0)}.filter {$0 != "\\"}.joined(separator: "")
if let sanitisedData = input.replacingOccurrences(of: "U(.*?)", with: "\\\\u$1", options: .regularExpression).data(using: .utf8){
parse(json: sanitisedData)
}
} catch {
// if something did not work out
print(error)
}
You can use \u{Unicode}:
print("Ain\u{2019}t i am a smart boy")
/* Prints "Ain’t i am a smart boy"
You can Use this Extension as well
extension String {
var unescapingUnicodeCharacters: String {
let mutableString = NSMutableString(string: self)
CFStringTransform(mutableString, nil, "Any-Hex/Java" as NSString, true)
return mutableString as String
}
}
let input = "ALTIN alm\\u0131\\u015f ba\\u015f\\u0131n\\u0131 gidiyor... bakal\\u0131m t\\u00fcrk liras\\u0131 daha ne kadar de\\u011fersizle\\u015fecek #Turkiye #BorsaAltin\\u2026 https://twitter.com/i/web/status/1216306036602277889"
print("result: \(input.unescapingUnicodeCharacters)")
//ALTIN almış başını gidiyor... bakalım türk lirası daha ne kadar değersizleşecek #Turkiye #BorsaAltin… https://twitter.com/i/web/status/1216306036602277889
Hey guys so I create a NSMutableArray send it to my mysql server convert it to base64, then when the app reads the data, it decodes the base64 code into a string format. Now im trying to convert the string back into an NSMutableArray. I cant seem to get it work heres the code that converts it to a string.
let string = String(data: (Data(base64Encoded:((data?.value(forKey: "14112017") as! NSArray)[0] as! NSDictionary)["data"] as! String)!), encoding: .utf8)!
So the answer to my question ended up converting my array to a JSONstring first which I did by using:
let jsonData: Data? = try? JSONSerialization.data(withJSONObject: UniversalArray)
let jsonString = String(data: jsonData!, encoding: .utf8)
then when retreiving it I get back my jsonString, however it has "\" which I replace using:
let cleanJsonString = myData.replacingOccurrences(of: "\\", with: "")
then to finally finish it off I just send this cleanJsonString to this function:
func convertToDictionary(text: String) -> Any? {
if let data = text.data(using: .utf8) {
do {
return try JSONSerialization.jsonObject(with: data, options: [])
} catch {
print(error.localizedDescription)
}
}
return nil
}
when calling this function I used this:
let array = convertToDictionary(text: myMutableArray) as? [AnyObject]
Thanks everyone for the amazing support, heres the answer to this bogus mess I created.
There are 2 parts to this: Serializing your array for transmission to your server, and then deserializing it from the server.
We need to see the code you use to serialize your array first. (The code that converts it to a string.) Based on what you post, it appears to be in JSON format. If so you may be able to skip the base64 encoding step, depending on what you're doing with the data. JSON is a good format for transmission to remote servers. You don't typically base64 encode JSON before transmission.
If you are receiving JSON that was then base64 encoded, you'll need to un-encode it back to data, and then use the JSONSerializer class to convert the JSON back to objects like arrays or dictionaries:
let data = Data(base64Encoded: base64DataFromServer)
guard let object = try? JSONSerialization.jsonObject(with: data) else {
return nil
}
(Note that the JSON you posted contains a dictionary as the top-level object, not an array.)
I am getting base64 string with extension and I want to convert base64 string to GIF and display it in ImageView. I am using iOSDevCenters+GIF.swift file. I am getting NSData from string but when data converted in image, its giving nil.Below is my code:
let imageData = profileImageString.data(using: .utf8)
self.thumbnailMedia.image = UIImage.gifImageWithData(imageData!)
Does anybody have any ideas on how to do this?
If you are starting from a base64 string, you should decode it as a base64 string not UTF8.
if let data = Data(base64Encoded: imageDataString) {
let image = UIImage(data: data)
}
This snippet simply takes the encode image string, decode into a Data object and create an image from the data.
If you are working a lot using base64 string I strongly suggest you to extend the String structure functionalities.
extension String {
//: ### Base64 encoding a string
func base64Encoded() -> String? {
if let data = self.data(using: .utf8) {
return data.base64EncodedString()
}
return nil
}
//: ### Base64 decoding a string
func base64Decoded() -> String? {
if let data = Data(base64Encoded: self) {
return String(data: data, encoding: .utf8)
}
return nil
}
}
This snippet was taken from Github, credits to Stringer.
Also another way is use the extension created by Leo Dabus that is compliant with Swift convention:
extension String {
var data: Data { return Data(utf8) }
var base64Encoded: Data { return data.base64EncodedData() }
var base64Decoded: Data? { return Data(base64Encoded: self) }
}
extension Data {
var string: String? { return String(data: self, encoding: .utf8) }
}
I'm trying to encode and decode Emojis to send them to my database.
I use this to encode:
var comentario = String()
let data = Comment.data(using: String.Encoding.nonLossyASCII, allowLossyConversion: true)
if let data = data {
let emojiString = NSString(data: data, encoding: String.Encoding.utf8.rawValue)! as String
comentario = emojiString
}
And it works. But now I don't know how to decode the emoji.
This is the type of encode ---> \ud83d\ude1a
Your encoding code can be simplified to
func encode(_ s: String) -> String {
let data = s.data(using: .nonLossyASCII, allowLossyConversion: true)!
return String(data: data, encoding: .utf8)!
}
Note that it encodes all non-ASCII characters as \uNNNN, not only
Emojis. Decoding is done by reversing the transformations:
func decode(_ s: String) -> String? {
let data = s.data(using: .utf8)!
return String(data: data, encoding: .nonLossyASCII)
}
This returns an optional because it can fail for invalid input.
Example:
let s = "Hello 😃."
let e = encode(s)
print(e) // Hello \ud83d\ude03.
if let d = decode(e) {
print(d) // Hello 😃.
}
Of course you can also define the code as extension methods of the
String type, and you might want to choose better function names.
I fixed this. If you have a server with encode utf8mb4, then for encoding emojis use this code:
var comentario = String()
let data = Comment.data(using: String.Encoding.nonLossyASCII, allowLossyConversion: true)
if let data = data {
let emojiString = NSString(data: data, encoding: String.Encoding.utf8.rawValue)! as String
comentario = emojiString
}// comentario contains the emoji encoded
DECODING:
let data = comentarios.data(using: String.Encoding.utf8, allowLossyConversion: false)
if data != nil{
let valueunicode = NSString(data: data!, encoding: String.Encoding.nonLossyASCII.rawValue) as? String
if valueunicode != nil{
comentarios = valueunicode!
}
}//comentarios contantes the deecode string(emoji)
i want to use text input and emoji from iOS default keyboard and send it to server and show that text to label but i am not able to display emojis.it only display text but not emojis.
if i do it locally than it will display emoji.
self.labelName.text = TextFiled.text
output : "test 😘😝"
but when i send send it to server and receive from it from api than emoji is gone.
output : "test"
please dont down vote my question without any reason
Swift 3.0 Extension solution:
You need to encode and decode emoji's on iOS side when sending it to server. You can do it as below.
extension String {
func encodeChatString() -> String? {
if let encodedTextData = self.data(using: .nonLossyASCII) {
return String(data: encodedTextData, encoding: .utf8)
}
return nil
}
func decodeChatString() -> String? {
let trimmedString = self.trimmingCharacters(in: .whitespacesAndNewlines)
if let stringData = trimmedString.data(using: .utf8) {
let messageString = String(data: stringData, encoding: .nonLossyASCII)
return messageString
}
return nil
}
}
When you send message encode string like below:
message.encodeChatString()
When you receive message decode string like below:
message.decodeChatString()
When send a data to server use this method .
let data1 = txtMessage.text.dataUsingEncoding(NSNonLossyASCIIStringEncoding)!
let finalmessage = String(data: data1, encoding: NSUTF8StringEncoding)
when you get a response from server before set in label use this method.
let trimmedString = YOURSERVER_RESPONSE_STRING.stringByTrimmingCharactersInSet(
NSCharacterSet.whitespaceAndNewlineCharacterSet())
let data2 = trimmedString.dataUsingEncoding(NSUTF8StringEncoding)!
let messagestring = String(data: data2, encoding: NSNonLossyASCIIStringEncoding)
YOURLABEL.text = messagestring as String
Try this your problem solve.