让人忍不住想要使用URLQueryAllowedCharacterSet
,但这并不适用于所有字符串。尤其&
and +
将会逃脱。
如果你想知道为什么我们必须逃脱&
and +
也是因为这两个字在x-www-form-urlencoded
要求。这&
用于分隔键值对x-www-form-urlencoded
请求,因此它会截断您的密码。大多数网络服务都会翻译+
到一个空间,所以你也想逃避它。
因此,我们首先定义一个可用的字符集:
// NSCharacterSet+URLQueryValueAllowed.h
@interface NSCharacterSet (URLQueryValueAllowed)
@property (class, readonly, copy) NSCharacterSet *URLQueryValueAllowedCharacterSet;
@end
and
// NSCharacterSet+URLQueryValueAllowed.m
@implementation NSCharacterSet (URLQueryValueAllowed)
+ (NSCharacterSet *)URLQueryValueAllowedCharacterSet {
static dispatch_once_t onceToken;
static NSCharacterSet *queryValueAllowed;
dispatch_once(&onceToken, ^{
NSMutableCharacterSet *allowed = [[NSCharacterSet URLQueryAllowedCharacterSet] mutableCopy];
NSString *generalDelimitersToEncode = @":#[]@"; // does not include "?" or "/" due to RFC 3986 - Section 3.4
NSString *subDelimitersToEncode = @"!$&'()*+,;=";
[allowed removeCharactersInString:generalDelimitersToEncode];
[allowed removeCharactersInString:subDelimitersToEncode];
queryValueAllowed = [allowed copy];
});
return queryValueAllowed;
}
@end
然后,为了让我们的生活更轻松,让我们定义NSDictionary
字典百分比编码的类别:
// NSDictionary+PercentEncoded.h
@interface NSDictionary (PercentEncoded)
- (NSString *)percentEncodedString;
- (NSData *)percentEncodedData;
@end
and
// NSDictionary+PercentEncoded.m
@implementation NSDictionary (PercentEncoded)
- (NSString *)percentEncodedString {
NSMutableArray<NSString *> *results = [NSMutableArray array];
NSCharacterSet *allowed = [NSCharacterSet URLQueryValueAllowedCharacterSet];
for (NSString *key in self.allKeys) {
NSString *encodedKey = [key stringByAddingPercentEncodingWithAllowedCharacters:allowed];
NSString *value = [[self objectForKey:key] description];
NSString *encodedValue = [value stringByAddingPercentEncodingWithAllowedCharacters:allowed];
[results addObject:[NSString stringWithFormat:@"%@=%@", encodedKey, encodedValue]];
}
return [results componentsJoinedByString:@"&"];
}
- (NSData *)percentEncodedData {
return [[self percentEncodedString] dataUsingEncoding:NSUTF8StringEncoding];
}
@end
然后,您的应用程序代码可以执行以下操作:
NSDictionary *dictionary = @{@"login": userName, @"password": userPassword};
NSData *body = [dictionary percentEncodedData];