Objective-C and Swift URL encoding Objective-C and Swift URL encoding ios ios

Objective-C and Swift URL encoding


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 \"%-.<>\^_`{|}~"


It's called URL encoding. More here.

-(NSString *)urlEncodeUsingEncoding:(NSStringEncoding)encoding {    return (NSString *)CFURLCreateStringByAddingPercentEscapes(NULL,           (CFStringRef)self,           NULL,           (CFStringRef)@"!*'\"();:@&=+$,/?%#[]% ",           CFStringConvertNSStringEncodingToEncoding(encoding));}


This is not my solution. Someone else wrote in stackoverflow but I have forgotten how.

Somehow this solution works "well". It handles diacritic, chinese characters, and pretty much anything else.

- (NSString *) URLEncodedString {    NSMutableString * output = [NSMutableString string];    const char * source = [self UTF8String];    int sourceLen = strlen(source);    for (int i = 0; i < sourceLen; ++i) {        const unsigned char thisChar = (const unsigned char)source[i];        if (false && thisChar == ' '){            [output appendString:@"+"];        } else if (thisChar == '.' || thisChar == '-' || thisChar == '_' || thisChar == '~' ||                   (thisChar >= 'a' && thisChar <= 'z') ||                   (thisChar >= 'A' && thisChar <= 'Z') ||                   (thisChar >= '0' && thisChar <= '9')) {            [output appendFormat:@"%c", thisChar];        } else {            [output appendFormat:@"%%%02X", thisChar];        }    }    return output;}

If someone would tell me who wrote this code, I'll really appreciate it. Basically he has some explanation why this encoded string will decode exactly as it wish.

I modified his solution a little. I like space to be represented with %20 rather than +. That's all.