NSUrl swift 2 with greek and other special characters - ios

I'm trying to make a server request with
NSUrl(string: "http://example.com/α")
In which α is a greek character. So when i request this i get an error and my app crashes. So i tried to encode the url to this
let myUrl = NSURL(string: myLink.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)!)!
and now my link has become http://example.com/%CE%B1
where %CE%B1 is the α character. Although my server does not recognise it and it doesnt send me back the data.
I use node.js with io.socket connections. Is there any way with swift to send the correct url without the percent encoding?

For encode α in your url
let str = "α"
let url = str.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLQueryAllowedCharacterSet())
Now decode url string like this
let orgStr = url?.stringByRemovingPercentEncoding
print(orgStr)

Related

Or parameterized API call crashing in Swift

I am making a call to an API where I want have status equal to final or in progress. Here is the call I am using:
let request = NSMutableURLRequest(url: NSURL(string: "https://sportspage-feeds.p.rapidapi.com/games?status=in%20progress||status=final")! as URL,
cachePolicy: .useProtocolCachePolicy,
timeoutInterval: 10.0)
It works perfectly in Postman, but when trying it in my app it is crashing with this error:
Fatal error: Unexpectedly found nil while unwrapping an Optional value: file
Is there a different way to use or in Swift?
You have manually percent encoded the space, but you have not percent encoded the two pipe characters. As a result the initialiser for NSURL fails, returning nil. Since you have force-unwrapped this value, your app then crashes.
You can use the function .addingPercentEncoding(withAllowedCharacters:) to percent encode a string appropriately and then create a URL.
Both percent encoding a string and creating a URL can fail, so these operations return an optional. You should use conditional unwrapping rather than force unwrapping to avoid crashes if these operations fail.
Many NS classes have bridged Swift equivalents including URLRequest for NSURLRequest and URL for NSURL. Idiomatic Swift eschews the use of an NS class when a Swift equivalent exists.
Use something like
if let urlStr = "https://sportspage-feeds.p.rapidapi.com/games?status=in progress||status=final".addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed), let url = URL(urlStr) {
let request = URLRequest(url, timeoutInterval: 10)
...
}
As Matt pointed out in a comment, the correct way to construct a URL in iOS is to use URLComponents. This allows you to specify each component of the URL independently and not worry about things like manual percent encoding.
The use of URLComponents is particularly important where you collect input from the user and they could attempt to manipulate the resulting URL string.
var components = URLComponents()
components.scheme = "https"
components.host = "sportspage-feeds.p.rapidapi.com"
components.path = "/games"
components.queryItems = [(URLQueryItem(name:"status", value:"in progress||status=final"))]
if let url = components.url {
let request = URLRequest(url, timeoutInterval: 10)
...
}

Swift URL decoding does not decode string

when trying to decode the following encoded string, it does not work...it´s actually doing nothing...leaving the string as it is:
https://www.foodhat.app/?rOpeningTime=08:00&rClosingTime=20:00&rClosedUntil=2019-08-19&pId=557&rId=69&goTo=CUSTOMER_PRODUCT_DETAILS&cName=Duhok&pName=%D9%85%D9%86%D8%B3%D9%81+%D8%AF%D9%88%D9%84%D9%85%D8%A9&rName=Mansaf+Alzain&rMinOrderValue=15000
pName is arabic, so do not wonder the encoding of it.
I use str.removingPercentEncoding to decode the string...but as said...it doesn´t remove the "+" (e.g. in rName)!
Result is
let str = "https://www.foodhat.app/?rOpeningTime=08:00&rClosingTime=20:00&rClosedUntil=2019-08-19&pId=557&rId=69&goTo=CUSTOMER_PRODUCT_DETAILS&cName=Duhok&pName=%D9%85%D9%86%D8%B3%D9%81+%D8%AF%D9%88%D9%84%D9%85%D8%A9&rName=Mansaf+Alzain&rMinOrderValue=15000"
print(str.removingPercentEncoding!)
//https://www.foodhat.app/?rOpeningTime=08:00&rClosingTime=20:00&rClosedUntil=2019-08-19&pId=557&rId=69&goTo=CUSTOMER_PRODUCT_DETAILS&cName=Duhok&pName=منسف+دولمة&rName=Mansaf+Alzain&rMinOrderValue=15000
What am I doing wrong?
Use 'str.replacingOccurrences()' instead. A better solution would be to use 'URLComponents', 'queryItems' to perform the filtering on the targeted queryItem, to ensure that '+' removal is not done for the entire url.
When decoding an URL you should use URLComponents :
let url = URL(string:"https://www.foodhat.app/?rOpeningTime=08:00&rClosingTime=20:00&rClosedUntil=2019-08-19&pId=557&rId=69&goTo=CUSTOMER_PRODUCT_DETAILS&cName=Duhok&pName=%D9%85%D9%86%D8%B3%D9%81+%D8%AF%D9%88%D9%84%D9%85%D8%A9&rName=Mansaf+Alzain&rMinOrderValue=15000")!
let components = URLComponents(url: url, resolvingAgainstBaseURL: false)
print(components)
Output is :
[rOpeningTime=08:00, rClosingTime=20:00, rClosedUntil=2019-08-19, pId=557, rId=69, goTo=CUSTOMER_PRODUCT_DETAILS, cName=Duhok, pName=منسف+دولمة, rName=Mansaf+Alzain, rMinOrderValue=15000]

Can iOS URL support unicode characters within top level domain?

I'm building an iOS app that takes urls as input.
Unicode characters are valid for a tld but when I instantiate a valid URL that contains unicode characters NSURL returns nil.
Is this even possible?
swift eg.
URL(string: "http://➡.ws/䨹")
How to use special characters in URL (Swift 3) :
let myUrl = "http://➡.ws/䨹" as String
let url = URL(string: myUrl) // nil here .. problem !
if let encoded = myUrl.addingPercentEncoding(withAllowedCharacters: .urlFragmentAllowed){
let urlencoded = URL(string: encoded) // "http://%E2%9E%A1.ws/%E4%A8%B9" here :) no problem ^^
}

Only one emoji image display in my app

I am building chat app and need to send and receive emoji images. I use following code to post data :
let myUrl = NSURL(string: "http://test.php")
let request = NSMutableURLRequest(URL:myUrl!)
request.HTTPMethod = "POST"
let postString = " shareImageMessage=\(message)"
request.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding)
I can see my message with emojies in debug area as follows :
But only following image display in mysql database :
And following code from php script :
$shareImageMessage = $_POST["shareImageMessage"];
I couldn't understand why only one kind of image transferring.
To send more than one emoticon in the same url simply convert the string you are sending to the server to a base64 and then decode it on the other end of the database. To Encode and Decode strings to base64 you can check this Convert between UIImage and Base64 string. :)
SWIFT: encode the message with base64 like so:
func base64encode(message: NSString)->String{
let plainData = message.dataUsingEncoding(NSUTF8StringEncoding)
return plainData.base64EncodedStringWithOptions(NSDataBase64EncodingOptions.fromRaw(0))!
}
usage : let msgToPost = base64encode("born to be encoded 👻")
then in PHP just use the famous $decodedmsg = base64_decode($str);
this code worked perfectly for me
one more thing..
make sure that your database column supports emoji, you can refer to the question for more detail about fixing the database emoji thing
How to insert utf-8 mb4 character(emoji in ios5) in mysql?

Cyrillic symbols in URL

App crashes with following url:
let jsonUrl = "http://api.com/алматы/events"
let session = NSURLSession.sharedSession()
let shotsUrl = NSURL(string: jsonUrl)
let task = session.dataTaskWithURL(shotsUrl!)
Log:
fatal error: unexpectedly found nil while unwrapping an Optional value
It's because of cyrillic symbols in url. How can I solve this issue. Thanks for your help!
Swift 4
Using String Extension
Create a swift file named String+Extension.swift and paste this code
import UIKit
extension String{
var encodeUrl : String
{
return self.addingPercentEncoding(withAllowedCharacters: NSCharacterSet.urlQueryAllowed)!
}
var decodeUrl : String
{
return self.removingPercentEncoding!
}
}
and Use it like so: (sample according to question):
"http://api.com/алматы/events".encodeUrl
Try this:
let encodedUrl = jsonUrl.stringByAddingPercentEncodingWithAllowedCharacters(URLQueryAllowedCharacterSet)
Something like this:
let apiHost = "http://api.com/"
let apiPath = "алматы/events"
let escapedPath = apiPath.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLHostAllowedCharacterSet())
let url = NSURL(string: "\(apiHost)\(escapedPath!)")
Obviously you should do something smarter than just force unwrap escapedPath.
Using the Wikipedia page for Swift as an example:
https://ru.wikipedia.org/wiki/Swift_(язык_программирования)
Becomes:
https://ru.wikipedia.org/wiki/Swift_(%D1%8F%D0%B7%D1%8B%D0%BA_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F)
Which when pasted into the browser takes you to the right page (and most browsers will conveniently render the UFT-8 characters for you).
Non-ASCII characters (and many special characters) need to be escaped in a URL. Chrome and other browser do it automatically. And they unescape the URLs in the address bar for a nicer display.
So if you have a static URL, just paste it into the adressbar, press enter, selected the URL again, copy and paste it to your app:
So instead of:
let jsonUrl = "http://api.com/алматы/events"
You'll get:
let jsonUrl = "http://api.com/%D0%B0%D0%BB%D0%BC%D0%B0%D1%82%D1%8B/events"
Try stringByAddingPercentEncodingWithAllowedCharacters: defined on NSString. You may see people suggesting stringByAddingPercentEscapesUsingEncoding:, but that method is deprecated in iOS 9.
There are also a few predefined NSCharacterSets in Foundation, such as URLHostAllowedCharacterSet and URLPathAllowedCharacterSet. Therefore, if you really have to parse the unescaped URL in code (using preprocessed URLs, mentioned in the accepted answer, is usually a much better idea), you can write a helper method like this:
import Foundation
func url(scheme scheme: String, host: String, path: String) -> NSURL? {
let components = NSURLComponents()
components.scheme = scheme
components.host = host.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLHostAllowedCharacterSet())
components.path = path.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLPathAllowedCharacterSet())
return components.URL
}
// evaluates to http://api.com/%25D0%25B0%25D0%25BB%25D0%25BC%25D0%25B0%25D1%2582%25D1%258B/events
url(scheme: "http", host: "api.com", path: "/алматы/events")
Note that the above documentation mentions that
This method is intended to percent-encode an URL component or subcomponent string, NOT an entire URL string.
That's because according RFC 3986, not all parts of an URL can be percent-encoded (e.g. scheme - http/https/etc.)
in xamarin:
var uri = new Uri (url);
var nsurl = new NSUrl (uri.GetComponents (UriComponents.HttpRequestUrl, UriFormat.UriEscaped));
UIApplication.SharedApplication.OpenUrl (nsurl);
URLs cannot contain Cyrillic characters. There are standards how to translate Cyrillic characters into valid URLs - you might find something if you search for "Punicode" (the P is intentional).

Resources