dbconfession dbconfession - 1 year ago 87
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 Source

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)
    }
}