Search code examples
swiftobjective-cnsstringurlencode

Objective-C and Swift URL encoding


I have an NSString like this:

http://www.

But I want to transform it to this:

http%3A%2F%2Fwww.

How can I do this?


Solution

  • To escape the characters you want is a little more work.

    Example code

    iOS7 and above:

    NSString *unescaped = @"http://www";
    NSString *escapedString = [unescaped stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLHostAllowedCharacterSet]];
    NSLog(@"escapedString: %@", escapedString);
    

    NSLog output:

    escapedString: http%3A%2F%2Fwww

    The following are useful URL encoding character sets:

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

    Creating a characterset combining all of the above:

    NSCharacterSet *URLCombinedCharacterSet = [[NSCharacterSet characterSetWithCharactersInString:@" \"#%/:<>?@[\\]^`{|}"] invertedSet];
    

    Creating a Base64

    In the case of Base64 characterset:

    NSCharacterSet *URLBase64CharacterSet = [[NSCharacterSet characterSetWithCharactersInString:@"/+=\n"] invertedSet];
    

    For Swift 3.0:

    var escapedString = originalString.addingPercentEncoding(withAllowedCharacters:.urlHostAllowed)
    

    For Swift 2.x:

    var escapedString = originalString.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLHostAllowedCharacterSet())
    

    Note: stringByAddingPercentEncodingWithAllowedCharacters will also encode UTF-8 characters needing encoding.

    Pre iOS7 use Core Foundation
    Using Core Foundation With ARC:

    NSString *escapedString = (NSString *)CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(
        NULL,
       (__bridge CFStringRef) unescaped,
        NULL,
        CFSTR("!*'();:@&=+$,/?%#[]\" "),
        kCFStringEncodingUTF8));
    

    Using Core Foundation Without ARC:

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

    Note: -stringByAddingPercentEscapesUsingEncoding will not produce the correct encoding, in this case it will not encode anything returning the same string.

    stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding encodes 14 characrters:

    `#%^{}[]|\"<> plus the space character as percent escaped.

    testString:

    " `~!@#$%^&*()_+-={}[]|\\:;\"'<,>.?/AZaz"  
    

    encodedString:

    "%20%60~!@%23$%25%5E&*()_+-=%7B%7D%5B%5D%7C%5C:;%22'%3C,%3E.?/AZaz"  
    

    Note: consider if this set of characters meet your needs, if not change them as needed.

    RFC 3986 characters requiring encoding (% added since it is the encoding prefix character):

    "!#$&'()*+,/:;=?@[]%"

    Some "unreserved characters" are additionally encoded:

    "\n\r \"%-.<>\^_`{|}~"