Percent encoding output incorrect in Swift 4 for '(apostrophe) [duplicate] - ios

This question already has answers here:
Swift - encode URL
(19 answers)
Closed 3 years ago.
I am encoding my string to hit a web service. I am using addingPercentEncoding(withAllowedCharacters: CharacterSet) to encode my String.
Everything works fine except the '(apostrophe) character gets encoded to %E2%80%99 instead of %27.
if let _keyword = keyword?
.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) {
parameters?["keyword"] = _keyword
}
For Example:
When keyword is Maggie's, output = "Maggie%E2%80%99s" instead of "Maggie%27s".
Output is fine for others, when keyword is Jelly Extracts output is "Jelly%20Extracts".
So, how do I encode '(apostrophe) properly to %27
Edit: When I pass static text, like "Maggie's.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)" output is correct but when I wrap it in a variable output comes incorrect.

Instead of urlQueryAllowed use alphanumerics.
let originalString = "Maggie's"
let escapedString = originalString.addingPercentEncoding(withAllowedCharacters: .alphanumerics)
print(escapedString) // Optional("Maggie%27s")

Related

Swift URL.path changes encoding of utf-8 characters

Why does converting a String to an URL in Swift 4.2 and then converting the URL back to a String using url.path change the encoding of special characters like german umlauts (ä, ö, ü), even if I use a utf-8 encoding?
I wrote some sample code to show my problem. I encoded the strings to base64 in order to show that there is a difference.
I also have a similar unsolved problem with special characters and swift here.
Sample Code
let string = "/path/to/file"
let stringUmlauts = "/path/to/file/with/umlauts/testäöü"
let base64 = Data(string.utf8).base64EncodedString()
let base64Umlauts = Data(stringUmlauts.utf8).base64EncodedString()
print(base64, base64Umlauts)
let url = URL(fileURLWithPath: string)
let urlUmlauts = URL(fileURLWithPath: stringUmlauts)
let base64Url = Data(url.path.utf8).base64EncodedString()
let base64UrlUmlauts = Data(urlUmlauts.path.utf8).base64EncodedString()
print(base64Url, base64UrlUmlauts)
Output
The base64 and base64Url string stay the same but the base64Umlauts and the base64UrlUmlauts are different.
"L3BhdGgvdG8vZmlsZQ==" for base64
"L3BhdGgvdG8vZmlsZQ==" for base64Url
"L3BhdGgvdG8vZmlsZS93aXRoL3VtbGF1dHMvdGVzdMOkw7bDvA==" for base64Umlauts
"L3BhdGgvdG8vZmlsZS93aXRoL3VtbGF1dHMvdGVzdGHMiG/MiHXMiA==" for base64UrlUmlauts
When I put the base64Umlauts and base64UrlUmlauts strings into an online Base64 decoder, they both show /path/to/file/with/umlauts/testäöü, but the ä, ö, ü are different (not visually).
stringUmlauts.utf8 uses the Unicode characters äöü.
But urlUmlauts.path.utf8 uses the Unicode characters aou each followed by the combining ¨.
This is why you get different base64 encoding - the characters look the same but are actually encoded differently.
What's really interesting is that Array(stringUmlauts) and Array(urlUmlauts.path) are the same. The difference doesn't appear until you perform the UTF-8 encoding of the otherwise exact same String values.
Since the base64 encoding is irrelevant, here's a more concise test:
let stringUmlauts = "/path/to/file/with/umlauts/testäöü"
let urlUmlauts = URL(fileURLWithPath: stringUmlauts)
print(stringUmlauts, urlUmlauts.path) // Show the same
let rawStr = stringUmlauts
let urlStr = urlUmlauts.path
print(rawStr == urlStr) // true
print(Array(rawStr) == Array(urlStr)) // true
print(Array(rawStr.utf8) == Array(urlStr.utf8)) // false!!!
So how is the UTF-8 encoding of two equal strings different?
One solution to this is to use precomposedStringWithCanonicalMapping on the result of path.
let urlStr = urlUmlauts.path.precomposedStringWithCanonicalMapping
Now you get true from:
print(Array(rawStr.utf8) == Array(urlStr.utf8)) // now true

how can I convert String to Data [duplicate]

This question already has answers here:
Creating NSData from NSString in Swift
(9 answers)
Closed 4 years ago.
I have next:
deviceName = String.init(bytes: temp.prefix(upTo: index), encoding: .windowsCP1251)
where temp - [UInt8]. My question is: how can I convert this string back to Data?
I'm trying to convert like this:
newDataName = Data(newName.windowsCP1251)
But result is:
Value of type String has no member windowsCP1251
It is works with converting using utf8, but it shows russian characters incorrect. I need to use windowsCP1251 only:
newDataName = Data(newName.utf8)
Maybe this is what you looking for:
newDataName = newName.data(using: .windowsCP1251)

Capitalize each first letter of the words in a string [duplicate]

This question already has answers here:
How to capitalize each word in a string using Swift iOS
(8 answers)
Closed 5 years ago.
How can i capitalized each first letter of the result of this
self.namE.text = currentUser.displayName
self.handle.text = snapshotValue?["handle"] as? String
instead of "Bruce willis" i would like to have "Bruce Willis", i created this extension to capitalized the first letter
extension String {
func capitalizingFirstLetter() -> String {
return prefix(1).uppercased() + dropFirst()
}
}
but it obviously capitalize only the first word in a string, so how i have to modify this extension to get the right result? ( i looked in the doc but i didn't understand very well )
String in swift4 has already a capitalized computed property on itself, so without implementing anything yourself, you can get the desired result using this:
self.namE.text = currentUser.displayName.capitalized
E.g.:
self.namE.text = "bruce willis".capitalized

C# - How to decode UTF-8 String to Normal Strings or Emoji [duplicate]

This question already has answers here:
How to decode UTF8 bytes?
(2 answers)
Closed 5 years ago.
I storing my messages as utf-8 to preserve emoji
but how do I decode it again and show its original form
This is the Sample Message - %e2%9c%8c
String result = java.net.URLDecoder.decode(contacts.getYourmessage(), "UTF-8");
This is the Sample Message - %e2%9c%8c
It is url-encoded string. So you can
var str = WebUtility.UrlDecode("%e2%9c%8c");
which returns ✌
This is for swift:
var str = "%e2%9c%8c"
print(str.removingPercentEncoding)
Output:
Optional("✌")

How can I print the content of a variable of type Data using Swift? [duplicate]

This question already has answers here:
How to convert Data to hex string in swift
(8 answers)
Closed 6 years ago.
All I am looking to do is take a string and get its hex value. I've been following this post. Here is the code I have in my playground:
let str = "Say Hello to My Little Friend"
let data = str.data(using: String.Encoding.utf16)
print("\(data!)")
However, my code just prints:
"60 bytes\n"
How can I print the hex value? For reference, it should be:
5361792048656c6c6f20746f204d79204c6974746c6520467269656e64
Since Data is a Sequence of UInt8, you could map each byte to a string and then join them:
data.map { String(format: "%02x", $0) }.joined()
Just
print(data! as NSData)
PS: Your expected hex is .utf8

Resources