dbconfession dbconfession - 5 months ago 35
Swift Question

Why won't NSURL accept a valid string that contains quotes or braces?

EDIT

https://www.someurl.com/search?&access_token=1,84,848473938;848483,83&_json={"key1":"value1","key2":"value2"}


When declaring a URL that has a JSON string, I obviously need to use braces
_json={ }
and qoutes
\"key1\":\"value1\"


NSURL(string: String)
, however, magically becomes
nil
if either of these characters are included in the string.

So as answered correctly here: NSURL is returning nil for a valid URL, I tried using:

let url = NSURL(string: url.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLQueryAllowedCharacterSet())!)


But I believe that's deprecated since it was before Swift 2 was released and I am getting the error:
cannot convert value of Type NSCharacterSet to expected argument type NSStringEncoding (aka UInt)


So I tried using

let url = NSURL(string: url.stringByAddingPercentEncodingWithAllowedCharacters(NSUTF8StringEncoding)!)!


and while that did allow NSURL to have a value instead of nil, it did not return the expected results, so something is still wrong.

I know that the format is correct, because if I type the URL string manually in a browser, I get the expected result. If i copy/paste the encoded version from Xcode, it gives me the wrong result as did Swift when encoding as shown above.

Any insight would be much appreciated.

Answer

You can modify a mutable character set to remove an allowed character: since you want the commas to be encoded, remove the comma from the URLQueryAllowedCharacterSet before using it.

In Swift 2, we need to dance with NSMutableCharacterSet like this:

let sourceURL = "https://www.someurl.com/search?&access_token=1,84,848473938;848483,83&_json={\"key1\":\"value1\",\"key2\":\"value2\"}"

let charSet = NSMutableCharacterSet()
charSet.formUnionWithCharacterSet(NSCharacterSet.URLQueryAllowedCharacterSet())
charSet.removeCharactersInString(",")

let url = NSURL(string: sourceURL.stringByAddingPercentEncodingWithAllowedCharacters(charSet)!)

print(url!)

Prints:

https://www.someurl.com/search?&access_token=1%2C84%2C848473938;848483%2C83&_json=%7B%22key1%22:%22value1%22%2C%22key2%22:%22value2%22%7D

To do the same thing with Swift 3 we're using the CharacterSet struct instead of NSMutableCharacterSet but it's the same idea:

var charSet = CharacterSet()
charSet.formUnion(.urlQueryAllowed)
charSet.remove(",")
if let encoded = sourceURL.addingPercentEncoding(withAllowedCharacters: charSet) {
    if let url = URL(string: encoded) {
        print(url)
    }
}
Comments