我正在使用AFNetworking for iOS,我希望发送一个带有查询参数的请求,该参数的日期时间为值。想要的行为应该是:
Original: 2016-07-04T14:30:21+0200
Encoded: 2016-07-04T14%3A30%3A21%2B0200
Example: .../?datetime=2016-07-04T14%3A30%3A21%2B0200
AFNetworking自己进行字符串编码,不包括+ / & :
等特殊字符和更多(Wikipedia: Percent-encoding),这很好,因为它们是保留的。
因此,我必须以另一种方式编码我的日期时间值以逃避加号和冒号。但是当我在AFNetworking之前手动编码该值时,它显然会两次逃脱%
。因此,它为每个%25
%
2016-07-04T14%253A30%253A21%252B0200
我希望AFNetworking对包含允许字符的查询使用百分比编码:
query.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLPathAllowedCharacterSet())
我没有找到通过AFNetworking更改或禁用编码的解决方案来完全手动完成。你有什么建议吗?
答案 0 :(得分:3)
经过一番研究后,我找到了一个可以注入我想要的编码的地方。这是它没有工作的方式:
编码不工作
初始化requestOperationManager
:
self.requestOperationManager = [[AFHTTPRequestOperationManager alloc] init];
self.requestOperationManager.requestSerializer = [AFJSONRequestSerializer serializer];
使用requestOperationManager
初始化操作
NSURLRequest *request = [NSURLRequest alloc] initWithURL:url]; // The problem is here
AFHTTPRequestOperation *operation = [self.requestOperationManager HTTPRequestOperationWithRequest:urlRequest success:^(AFHTTPRequestOperation *operation, id responseObject) {
// Success
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
// Failure
}];
[self.requestOperationManager.operationQueue addOperation:operation];
[operation start];
有更多控制权的方法
AFHTTPRequestSerializer
也可以创建请求,您可以使用自己的序列化。
初始化requestOperationManager
并添加查询字符串序列化块:
self.requestOperationManager = [[AFHTTPRequestOperationManager alloc] init];
self.requestOperationManager.requestSerializer = [AFJSONRequestSerializer serializer];
[self.requestOperationManager.requestSerializer setQueryStringSerializationWithBlock:^NSString * _Nonnull(NSURLRequest * _Nonnull request, id _Nonnull parameters, NSError * _Nullable __autoreleasing * _Nullable error) {
if ([parameters isKindOfClass:[NSString class]]) {
NSString *yourEncodedParameterString = // What every you want to do with it.
return yourEncodedParameterString;
}
return parameters;
}];
现在更改您创建NSURLRequest
的方式:
NSString *method = @"GET";
NSString *urlStringWithoutQuery = @"http://example.com/";
NSString *query = @"datetime=2016-07-06T12:15:42+0200"
NSMutableURLRequest *urlRequest = [self.requestOperationManager.requestSerializer requestWithMethod:method URLString:urlStringWithoutQuery parameters:query error:nil];
分割您的网址重要。使用不查询URLString
参数的网址,仅查询parameters
参数的查询。使用requestWithMethod:URLString:parameters:error
,它将调用您在上面提供的查询字符串序列化块,并根据需要对参数进行编码。
AFHTTPRequestOperation *operation = [self.requestOperationManager HTTPRequestOperationWithRequest:urlRequest success:^(AFHTTPRequestOperation *operation, id responseObject) {
// Success
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
// Failure
}];
[self.requestOperationManager.operationQueue addOperation:operation];
[operation start];