How to decode unicode characters in swift 3? [duplicate] - ios

This question already has answers here:
Using Swift to unescape unicode characters, ie \u1234
(3 answers)
Closed 6 years ago.
I am developing one chat application, for that everything is working fine except. This application is in both Android and iOS platform. We want to pass emoji in the chat. In android we use UTF encoding with StringEscapeUtils. it is working perfect in android. when we pass emoji it is encoded and stored in DB like "\u263A".
Now in android this string is also decode and shown perfect in view but some how we can not decode the same string in iOS. We have simply try to
decode using UTF string. But still it is not working.
I have already follow this link Print unicode character from variable (swift)
Thanks in advance.

The easiest way is to use CFStringTransform like below.
let wI = NSMutableString( string: "\\u263a" )
CFStringTransform( wI, nil, "Any-Hex/Java" as NSString, true )
someUILabel.text = wI as String

You should try this:
For Example:
let charString = "263A"
if let charCode = UInt32(charString, radix: 16),let unicode = UnicodeScalar(charCode)
{
let str = String(unicode)
print(str)
}
else
{
print("invalid input")
}
If you want to Print on Label/TextField then:
let charString = "263A"
if let charCode = UInt32(charString, radix: 16),let unicode = UnicodeScalar(charCode)
{
let str = String(unicode)
CharLabel.text = str //Print on Label
CharTextField.text = str //Print on TextField
}
else
{
print("invalid input")
}

Related

How to encode only all special characters in PercentEncoding is swift 5

I am running the code from similar questions from stackoverflow to percentage encode only all the special characters(#!#$%^&*()~-_=+;:'/.,<>{}[])(not encoding alphanumeric characters) on xcode playground . Here are my attempts
import UIKit
//////////////
//Attempt 1
var originalString = "Test#123!#$%^&*()~-_=+;:'/.,<>{}[]"
let escapedString = originalString.addingPercentEncoding(withAllowedCharacters:NSCharacterSet.urlQueryAllowed)
print("Attemp 1:",escapedString)
///////////////////
//Attempt 2
func encodeValue(_ string: String) -> String? {
guard let unescapedString = string.addingPercentEncoding(withAllowedCharacters: CharacterSet(charactersIn: ":/").inverted) else { return nil }
return unescapedString
}
let encodedString = encodeValue("Test#123!#$%^&*()~-_=+;:'/.,<>{}[]")
print("Attemp 2:",encodedString)
//////////////////////
//Attempt 3
extension String {
var encoded: String? {
return self.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed)
}
}
let encodedUrl = "Test#123!#$%^&*()~-_=+;:'/.,<>{}[]".encoded
print("Attemp 3:",encodedUrl)
//////////////
//Attempt 4
let myurlstring = "Test#123!#$%^&*()~-_=+;:'/.,<>{}[]"
let urlwithPercentEscapes = myurlstring.addingPercentEncoding( withAllowedCharacters: .urlQueryAllowed)
print("Attemp 4:",urlwithPercentEscapes)
//////////////
//Attempt 5
var s = "Test#123!#$%^&*()~-_=+;:'/.,<>{}[]"
let encodedLink = s.addingPercentEncoding(withAllowedCharacters: .urlFragmentAllowed)
let encodedURL = NSURL(string: encodedLink!)! as URL
print("Attemp 5:",encodedURL)
Here are the results
Attemp 1:
Optional("Test#123!%23$%25%5E&*()~-_=+;:'/.,%3C%3E%7B%7D%5B%5D")
Attemp 2: Optional("Test#123!#$%^&*()~-_=+;%3A'%2F.,<>{}[]")
Attemp 3:
Optional("Test%40123!%23$%25%5E&*()~-_=+;%3A'%2F.,%3C%3E%7B%7D%5B%5D")
Attemp 4:
Optional("Test#123!%23$%25%5E&*()~-_=+;:'/.,%3C%3E%7B%7D%5B%5D")
Attemp 5: Test#123!%23$%25%5E&*()~-_=+;:'/.,%3C%3E%7B%7D%5B%5D
Non of them are percentage encoding the complete special characters.I want to encode all of the special character just like following special character are never encoded in almost all attempts.
*()~-_=+;:'/.,
Kindly tell me the code to percentage encode all of my special character including *()~-_=+;:'/., ? Thanks
To percent-encode everything except alphanumerics, pass .alphanumerics as the allowed characters:
let encoded = s.addingPercentEncoding(withAllowedCharacters: .alphanumerics)
For your example this returns (as an Optional):
Test%40123%21%23%24%25%5E%26%2A%28%29%7E%2D%5F%3D%2B%3B%3A%27%2F%2E%2C%3C%3E%7B%7D%5B%5D
I assume this what you were looking for.
This isn't particularly useful, since this is unlikely to correctly encode any particular URL (which is what you seem to be doing). But if you have the need you describe (which is unrelated to correctly encoding URLs), then that's how you do it.
If you want to correctly encode URLs, construct the URL using URLComponents. It'll encode each piece using the rules for that piece. There is no simple string substitution that will correctly percent-encode an URL.

String with Unicode (variable) [duplicate]

I have a problem I couldn't find a solution to.
I have a string variable holding the unicode "1f44d" and I want to convert it to a unicode character πŸ‘.
Usually one would do something like this:
println("\u{1f44d}") // πŸ‘
Here is what I mean:
let charAsString = "1f44d" // code in variable
println("\u{\(charAsString)}") // not working
I have tried several other ways but somehow the workings behind this magic stay hidden for me.
One should imagine the value of charAsString coming from an API call or from another object.
One possible solution (explanations "inline"):
let charAsString = "1f44d"
// Convert hex string to numeric value first:
var charCode : UInt32 = 0
let scanner = NSScanner(string: charAsString)
if scanner.scanHexInt(&charCode) {
// Create string from Unicode code point:
let str = String(UnicodeScalar(charCode))
println(str) // πŸ‘
} else {
println("invalid input")
}
Slightly simpler with Swift 2:
let charAsString = "1f44d"
// Convert hex string to numeric value first:
if let charCode = UInt32(charAsString, radix: 16) {
// Create string from Unicode code point:
let str = String(UnicodeScalar(charCode))
print(str) // πŸ‘
} else {
print("invalid input")
}
Note also that not all code points are valid Unicode scalars,
compare Validate Unicode code point in Swift.
Update for Swift 3:
public init?(_ v: UInt32)
is now a failable initializer of UnicodeScalar and checks if the
given numeric input is a valid Unicode scalar value:
let charAsString = "1f44d"
// Convert hex string to numeric value first:
if let charCode = UInt32(charAsString, radix: 16),
let unicode = UnicodeScalar(charCode) {
// Create string from Unicode code point:
let str = String(unicode)
print(str) // πŸ‘
} else {
print("invalid input")
}
This can be done in two steps:
convert charAsString to Int code
convert code to unicode character
Second step can be done e.g. like this
var code = 0x1f44d
var scalar = UnicodeScalar(code)
var string = "\(scalar)"
As for first the step, see here how to convert String in hex representation to Int
As of Swift 2.0, every Int type has an initializer able to take String as an input. You can then easily generate an UnicodeScalar corresponding and print it afterwards. Without having to change your representation of chars as string ;).
UPDATED: Swift 3.0 changed UnicodeScalar initializer
print("\u{1f44d}") // πŸ‘
let charAsString = "1f44d" // code in variable
let charAsInt = Int(charAsString, radix: 16)! // As indicated by #MartinR radix is required, default won't do it
let uScalar = UnicodeScalar(charAsInt)! // In Swift 3.0 this initializer is failible so you'll need either force unwrap or optionnal unwrapping
print("\(uScalar)")
You can use
let char = "-12"
print(char.unicodeScalars.map {$0.value }))
You'll get the values as:
[45, 49, 50]
Here are a couple ways to do it:
let string = "1f44d"
Solution 1:
"&#x\(string);".applyingTransform(.toXMLHex, reverse: true)
Solution 2:
"U+\(string)".applyingTransform(StringTransform("Hex/Unicode"), reverse: true)
I made this extension that works pretty well:
extension String {
var unicode: String? {
if let charCode = UInt32(self, radix: 16),
let unicode = UnicodeScalar(charCode) {
let str = String(unicode)
return str
}
return nil
}
}
How to test it:
if let test = "e9c8".unicode {
print(test)
}
//print:
You cannot use string interpolation in Swift as you try to use it. Therefore, the following code won't compile:
let charAsString = "1f44d"
print("\u{\(charAsString)}")
You will have to convert your string variable into an integer (using init(_:radix:) initializer) then create a Unicode scalar from this integer. The Swift 5 Playground sample code below shows how to proceed:
let validCodeString = "1f44d"
let validUnicodeScalarValue = Int(validCodeString, radix: 16)!
let validUnicodeScalar = Unicode.Scalar(validUnicodeScalarValue)!
print(validUnicodeScalar) // πŸ‘

How to extract phrase from string using Range? [duplicate]

This question already has answers here:
Finding index of character in Swift String
(33 answers)
Closed 6 years ago.
This sounds easy, but I am stumped. The syntax and functions of Range are very confusing to me.
I have a URL like this:
https://github.com/shakked/Command-for-Instagram/blob/master/Analytics%20Pro.md#global-best-time-to-post
I need to extract the part #global-best-time-to-post, essentially the # to the end of the string.
urlString.rangeOfString("#") returns Range
Then I tried doing this assuming that calling advanceBy(100) would just go to the end of the string but instead it crashes.
hashtag = urlString.substringWithRange(range.startIndex...range.endIndex.advancedBy(100))
Easiest and best way to do this is use NSURL, I included how to do it with split and rangeOfString:
import Foundation
let urlString = "https://github.com/shakked/Command-for-Instagram/blob/master/Analytics%20Pro.md#global-best-time-to-post"
// using NSURL - best option since it validates the URL
if let url = NSURL(string: urlString),
fragment = url.fragment {
print(fragment)
}
// output: "global-best-time-to-post"
// using split - pure Swift, no Foundation necessary
let split = urlString.characters.split("#")
if split.count > 1,
let fragment = split.last {
print(String(fragment))
}
// output: "global-best-time-to-post"
// using rangeofString - asked in the question
if let endOctothorpe = urlString.rangeOfString("#")?.endIndex {
// Note that I use the index of the end of the found Range
// and the index of the end of the urlString to form the
// Range of my string
let fragment = urlString[endOctothorpe..<urlString.endIndex]
print(fragment)
}
// output: "global-best-time-to-post"
You could also use substringFromIndex
let string = "https://github.com..."
if let range = string.rangeOfString("#") {
let substring = string.substringFromIndex(range.endIndex)
}
but I'd prefer the NSURL way.
use componentsSeparatedByString method
let url = "https://github.com/shakked/Command-for-Instagram/blob/master/Analytics%20Pro.md#global-best-time-to-post"
let splitArray = url.componentsSeparatedByString("#")
your required last text phrase (without # char) will be at the last index of the splitArray , you can concatenate the # with your phrase
var myPhrase = "#\(splitArray[splitArray.count-1])"
print(myPhrase)

How to compose multi-character emoji from raw hex

I'm getting JSON like this from the server:
{
"unicode":"1f468-1f468-1f467-1f467"
}
and I'm supposed to translate it into its composite character for display and/or copying to the pasteboard: πŸ‘¨β€πŸ‘¨β€πŸ‘§β€πŸ‘§
The solution so far comes from this SO question:
let u = json["unicode"] as? String
let dashless = u.characters.split{$0 == "-"}.map(String.init)
let charArray = dashless.map { char -> Character in
let code = Int(strtoul(char, nil, 16))
return Character(UnicodeScalar(code))
}
let unicode = String(charArray)
UIPasteboard.generalPasteboard().string = unicode
This works great for single-character emoji definitions.
E.g., I can run the code above with this JSON…
{
"unicode":"1f4a9"
}
…and paste the expected result: πŸ’©. But when I do with the mmgg family emoji listed earlier, I get the following in iOS, minus the spaces: πŸ‘¨β€ πŸ‘¨β€ πŸ‘§β€ πŸ‘§. They just don't seem to want to combine when pasted into a text field.
Is this an iOS bug, or am I doing something wrong?
try this in your playground, to see the difference ...
"πŸ‘¨πŸ‘¨πŸ‘§πŸ‘§".unicodeScalars.forEach { (c) in
print(c.escape(asASCII: true),terminator: "")
}
print("")
"πŸ‘¨β€πŸ‘¨β€πŸ‘§β€πŸ‘§".unicodeScalars.forEach { (c) in
print(c.escape(asASCII: true), terminator: "")
}
/*
\u{0001F468}\u{0001F468}\u{0001F467}\u{0001F467}
\u{0001F468}\u{200D}\u{0001F468}\u{200D}\u{0001F467}\u{200D}\u{0001F467}
*/
your original, slightly modified code
import Darwin // stroul
let u = "1f468-1f468-1f467-1f467"
let dashless = u.characters.split{$0 == "-"}.map(String.init)
let emoji = dashless.map { char -> String in
let code = Int(strtoul(char, nil, 16))
return String(UnicodeScalar(code))
}.joinWithSeparator("\u{200D}")
print(emoji) // πŸ‘¨β€πŸ‘¨β€πŸ‘§β€πŸ‘§
pure Swift code, no Foundation, without strtoul
let u = "1f468-1f468-1f467-1f467"
let emoji = u.characters.split("-")
.map {String(UnicodeScalar(Int(String($0),radix: 16) ?? 0))}
.joinWithSeparator("\u{200D}")
print(emoji) // πŸ‘¨β€πŸ‘¨β€πŸ‘§β€πŸ‘§

How to get substring of String in Swift? [duplicate]

This question already has answers here:
How do you use String.substringWithRange? (or, how do Ranges work in Swift?)
(33 answers)
Closed 7 years ago.
If I want to get a value from the NSString "πŸ˜ƒhello WorldπŸ˜ƒ", what should I use?
The return value I want is "hello World".
The smileys can be any string. so i need some regexp to this.
There's more than one way to do it.
First: String in Swift 1.2 is bridged to NSString properly so the answer could be : How to get substring of NSString?
Second: This answer will deal with emoticon characters too.
var s = "πŸ˜ƒhello WorldπŸ˜ƒ"
let index = advance(s.startIndex, 1) // index is a String.Index to the 2nd glyph, β€œh”
let endIndex = advance(s.startIndex, 12)
let substring=s[index..<endIndex] // here you got "hello World"
if let emojiRange = s[index...s.endIndex].rangeOfString("πŸ˜ƒ") {
let substring2 = s[index..<emojiRange.startIndex] // here you get "hello World"
}

Resources