+
may be a valid character when the content-type is application/x-www-form-urlencoded, see the link, so NSURLComponents
doesn't encode it.
Apple also mention this:
RFC 3986 specifies which characters must be percent-encoded in the
query component of a URL, but not how those characters should be
interpreted. The use of delimited key-value pairs is a common
convention, but isn't standardized by a specification. Therefore, you
may encounter interoperability problems with other implementations
that follow this convention.
One notable example of potential interoperability problems is how the
plus sign (+) character is handled:
According to RFC 3986, the plus sign is a valid character within a
query, and doesn't need to be percent-encoded. However, according to
the W3C recommendations for URI addressing, the plus sign is reserved
as shorthand notation for a space within a query string (for example,
?greeting=hello+world).
If a URL query component contains a date formatted according to RFC
3339 with a plus sign in the timezone offset (for example,
2013-12-31T14:00:00+00:00), interpreting the plus sign as a space
results in an invalid time format. RFC 3339 specifies how dates should
be formatted, but doesn't advise whether the plus sign must be
percent-encoded in a URL. Depending on the implementation receiving
this URL, you may need to preemptively percent-encode the plus sign
character.
As an alternative, consider encoding complex and/or potentially
problematic data in a more robust data-interchange format, such as
JSON or XML.
The conclude is you may or may not encode '+'.
In my opinion, NSURLComponents
only encode character which it make sure that should be encoded, such as '&', '=' or Chinese characters like '你' '好', it doesn't encode the character may be encode or not according to the content-type, like '+' I mentioned above. So if you find you have to encode '+' or your server can't parse correctly, you can use the code below.
I don't know swift, so I just provide objective-c code, sorry for that.
- (NSString *)URLEncodingValue:(NSString *)value
{
NSCharacterSet *set = [NSCharacterSet URLQueryAllowedCharacterSet];
NSMutableCharacterSet *mutableQueryAllowedCharacterSet = [set mutableCopy];
[mutableQueryAllowedCharacterSet removeCharactersInString:@"!*'();:@&=+$,/?%#[]"];
return [value stringByAddingPercentEncodingWithAllowedCharacters:mutableQueryAllowedCharacterSet];
}
!*'();:@&=+$,/?%#[] are reserved characters defined in RFC 3986, the code will encode all of them appear in the value parameter, if you just want to encode '+', just replace !*'();:@&=+$,/?%#[]
with +
.