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);
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With