Search code examples
iosswifturlencode

Swift - encode URL


If I encode a string like this:

var escapedString = originalString.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)

it doesn't escape the slashes /.

I've searched and found this Objective C code:

NSString *encodedString = (NSString *)CFURLCreateStringByAddingPercentEscapes(
                        NULL,
                        (CFStringRef)unencodedString,
                        NULL,
                        (CFStringRef)@"!*'();:@&=+$,/?%#[]",
                        kCFStringEncodingUTF8 );

Is there an easier way to encode an URL and if not, how do I write this in Swift?


Solution

  • Swift 3

    In Swift 3 there is addingPercentEncoding

    let originalString = "test/test"
    let escapedString = originalString.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed)
    print(escapedString!)
    

    Output:

    test%2Ftest

    Swift 1

    In iOS 7 and above there is stringByAddingPercentEncodingWithAllowedCharacters

    var originalString = "test/test"
    var escapedString = originalString.stringByAddingPercentEncodingWithAllowedCharacters(.URLHostAllowedCharacterSet())
    println("escapedString: \(escapedString)")
    

    Output:

    test%2Ftest

    The following are useful (inverted) character sets:

    URLFragmentAllowedCharacterSet  "#%<>[\]^`{|}
    URLHostAllowedCharacterSet      "#%/<>?@\^`{|}
    URLPasswordAllowedCharacterSet  "#%/:<>?@[\]^`{|}
    URLPathAllowedCharacterSet      "#%;<>?[\]^`{|}
    URLQueryAllowedCharacterSet     "#%<>[\]^`{|}
    URLUserAllowedCharacterSet      "#%/:<>?@[\]^`
    

    If you want a different set of characters to be escaped create a set:
    Example with added "=" character:

    var originalString = "test/test=42"
    var customAllowedSet =  NSCharacterSet(charactersInString:"=\"#%/<>?@\\^`{|}").invertedSet
    var escapedString = originalString.stringByAddingPercentEncodingWithAllowedCharacters(customAllowedSet)
    println("escapedString: \(escapedString)")
    

    Output:

    test%2Ftest%3D42

    Example to verify ascii characters not in the set:

    func printCharactersInSet(set: NSCharacterSet) {
        var characters = ""
        let iSet = set.invertedSet
        for i: UInt32 in 32..<127 {
            let c = Character(UnicodeScalar(i))
            if iSet.longCharacterIsMember(i) {
                characters = characters + String(c)
            }
        }
        print("characters not in set: \'\(characters)\'")
    }