Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

addingPercentEncoding works different in Swift

I have obj-C method that encodes String:

- (NSString *) encodeValue:(NSString*) unescaped{
    return [unescaped stringByAddingPercentEncodingWithAllowedCharacters:
             [NSCharacterSet URLHostAllowedCharacterSet]];
}

input: testswiftapppod://

output: testswiftapppod%3A%2F%2F

I wrote the same method in Swift but got different output: testswiftapppod:%2F%2F

static func encodeValue(unescaped:String!) -> String{
   return unescaped.addingPercentEncoding(
        withAllowedCharacters: CharacterSet.urlHostAllowed)!
}

For some reason colon not converted

How to fix this issue?

I use Xcode 8.3

[EDIT]

From Docs:

// Returns a new string made from the receiver by replacing all characters not in the allowedCharacters set with percent encoded characters. UTF-8 encoding is used to determine the correct percent encoded characters. Entire URL strings cannot be percent-encoded. This method is intended to percent-encode an URL component or subcomponent string, NOT the entire URL string. Any characters in allowedCharacters outside of the 7-bit ASCII range are ignored. - (nullable NSString *)stringByAddingPercentEncodingWithAllowedCharacters:(NSCharacterSet *)allowedCharacters NS_AVAILABLE(10_9, 7_0);

like image 856
snaggs Avatar asked Apr 06 '17 11:04

snaggs


1 Answers

EDIT:

This is probably undocumented but intended behavior. See is `addingPercentEncoding` broken in Xcode 9 beta 2? for more details.


This is a bug.

I went over different cases, it seems all Swift code works correctly. Note that : is allowed in URL host, therefore it should not be encoded and the bug is in the Obj-C version.

NSCharacterSet *set = [NSCharacterSet URLHostAllowedCharacterSet];    
NSLog(@"Colon is member: %@", [set characterIsMember:':'] ? @"true" : @"false"); // prints true

It's an interesting bug because if you add ":" to the character set manually

NSMutableCharacterSet *set = [[NSCharacterSet URLHostAllowedCharacterSet] mutableCopy];
[set addCharactersInString:@":"];

Everything starts to work correctly.

Report it.

Note that when encoding for URL parameters, you shouldn't use urlHostAllowed. If possible, use NSURLQuery to build your URL instead. Neither of the predefined sets is actually suitable for URL encoding. You can start with urlQueryAllowed but you still have to remove some characters from it.

See for example this answer for a correct solution or for example the implementation in Alamofire library.

like image 150
Sulthan Avatar answered Nov 15 '22 09:11

Sulthan