AFNetworking 3.0 解决加密后请求参数是字符串问题
把整个请求参数的json加密生成一个字符串传给服务器,错误提示:[NSJSONSerialization dataWithJSONObject:options:error:]: Invalid top-level type in JSON write';
因为请求参数不是字典、数组、集合...等, AFNetworking自动过滤掉了;
解决方案一:
在AFNetworking源码的AFURLRequestSerialization.m修改:
#pragma mark - AFURLRequestSerialization - (NSURLRequest *)requestBySerializingRequest:(NSURLRequest *)request withParameters:(id)parameters error:(NSError *__autoreleasing *)error { NSParameterAssert(request); if ([self.HTTPMethodsEncodingParametersInURI containsObject:[[request HTTPMethod] uppercaseString]]) { return [super requestBySerializingRequest:request withParameters:parameters error:error]; } NSMutableURLRequest *mutableRequest = [request mutableCopy]; [self.HTTPRequestHeaders enumerateKeysAndObjectsUsingBlock:^(id field, id value, BOOL * __unused stop) { if (![request valueForHTTPHeaderField:field]) { [mutableRequest setValue:value forHTTPHeaderField:field]; } }]; if (parameters) { if (![mutableRequest valueForHTTPHeaderField:@"Content-Type"]) { [mutableRequest setValue:@"application/json" forHTTPHeaderField:@"Content-Type"]; } // [mutableRequest setHTTPBody:[NSJSONSerialization dataWithJSONObject:parameters options:self.writingOptions error:error]]; if ([parameters isKindOfClass:[NSString class]]) { [mutableRequest setHTTPBody:[parameters dataUsingEncoding:NSUTF8StringEncoding]]; }else{ [mutableRequest setHTTPBody:[NSJSONSerialization dataWithJSONObject:parameters options:self.writingOptions error:error]]; } } return mutableRequest; }
解决方案二:
构建请求参数,设置HTTPBody,直接操作request:
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:url]]; [request setHTTPMethod:@"POST"]; //requestManager.responseSerializer.acceptableContentTypes = [NSSet setWithObject:@"text/html"]; //[request setValue:@"application/json; charset=utf-8" forHTTPHeaderField:@"Content-Type"]; // 此处设置请求体 (即将参数加密后的字符串,转为data) 一般是参数字典转json字符串,再将json字符串加密,最后将加密后的字符串转为data 设置为请求体 [request setHTTPBody: [data dataUsingEncoding:NSUTF8StringEncoding]];
然后发送请求:
requestManager = [AFHTTPSessionManager manager]; requestManager.requestSerializer = [AFJSONRequestSerializer serializer]; requestManager.responseSerializer = [AFHTTPResponseSerializer serializer]; NSURLSessionDataTask * tesk = [requestManager dataTaskWithRequest:request uploadProgress:nil downloadProgress:nil completionHandler:^(NSURLResponse * _Nonnull response, id _Nullable responseObject, NSError * _Nullable error) { if (error) { failure(error); }else{ success(responseObject); } }]; [tesk resume];