无法使用 AFNetworking 3 为 JSON 和 XML 响应创建单例

Posted

技术标签:

【中文标题】无法使用 AFNetworking 3 为 JSON 和 XML 响应创建单例【英文标题】:Cannot make singleton for JSON and XML response using AFNetworking 3 【发布时间】:2016-08-19 09:50:24 【问题描述】:

您好,我正在为 JSON 和 XML 响应的网络制作单例

我的 ApiClient.h

+ (ApiClient *)sharedInstance;

-(instancetype)initWithBaseURL:(NSURL *)url sessionConfiguration:(NSURLSessionConfiguration *)configuration;

我的 ApiClient.m

+ (ApiClient *)sharedInstance 
    static ApiClient *sharedInstance = nil;

    static dispatch_once_t oncePredicate;
    dispatch_once(&oncePredicate, ^
        NSURLSessionConfiguration *sessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration];
        sharedInstance = [[self alloc] initWithBaseURL:[NSURL URLWithString:SINGPOST_BASE_URL] sessionConfiguration:sessionConfiguration];

        [sharedInstance setDataTaskWillCacheResponseBlock:^NSCachedURLResponse *(NSURLSession *session, NSURLSessionDataTask *dataTask, NSCachedURLResponse *proposedResponse)
         
             NSHTTPURLResponse *resp = (NSHTTPURLResponse*)proposedResponse.response;
             NSMutableDictionary *newHeaders = [[resp allHeaderFields] mutableCopy];
             if (newHeaders[@"Cache-Control"] == nil) 
                 newHeaders[@"Cache-Control"] = @"max-age=120, public";
             
             NSURLResponse *response2 = [[NSHTTPURLResponse alloc] initWithURL:resp.URL statusCode:resp.statusCode HTTPVersion:nil headerFields:newHeaders];
             NSCachedURLResponse *cachedResponse2 = [[NSCachedURLResponse alloc] initWithResponse:response2
                                                                                             data:[proposedResponse data]
                                                                                         userInfo:[proposedResponse userInfo]
                                                                                    storagePolicy:NSURLCacheStorageAllowed];
             return cachedResponse2;
         ]; 
    );
    return sharedInstance;

-(instancetype)initWithBaseURL:(NSURL *)url sessionConfiguration:(NSURLSessionConfiguration *)configuration 
    self = [super initWithBaseURL:url sessionConfiguration:configuration];
        if (self) 
        
    return self;

问题是单例不能同时处理 XML 和 JSON 响应。它可以成功解析 JSON 和 XML 1 次。但是当再次调用再次解析时)(成功解析XML后)结果将无法正确解析(给出十六进制字符串响应)

我的 JSON 块请求

- (void)sendJSONRequest:(NSMutableURLRequest *)request
                success:(void (^)(NSURLResponse *response, id responseObject))success
                failure:(void (^)(NSError *error))failure 

    self.responseSerializer.acceptableContentTypes = [AFHTTPResponseSerializer serializer].acceptableContentTypes;

    NSURLSessionDataTask *dataTask = [self dataTaskWithRequest:request completionHandler:^(NSURLResponse *response, id responseObject, NSError *error) 
        if (error) 
            NSLog(@"Error URL: %@",request.URL.absoluteString);
            NSLog(@"Error: %@", error);
            failure(error);
         else 
            NSDictionary *jsonDict  = (NSDictionary *) responseObject;
            success(response,jsonDict);
            NSLog(@"Success URL: %@",request.URL.absoluteString);
            NSLog(@"Success %@",jsonDict);
        
    ];
    [dataTask resume];


我的 XML 块请求

- (void)sendXMLRequest:(NSMutableURLRequest *)request
               success:(void (^)(NSURLResponse *response, RXMLElement *responseObject))success
               failure:(void (^)(NSError *error))failure 

    self.requestSerializer = [AFHTTPRequestSerializer serializer];
    self.responseSerializer = [AFHTTPResponseSerializer serializer];
    [self.responseSerializer.acceptableContentTypes setByAddingObject:@"application/xml"];
    NSURLSessionDataTask *dataTask = [self dataTaskWithRequest:request completionHandler:^(NSURLResponse *response, id responseObject, NSError *error) 
        if (error) 
            NSLog(@"Error URL: %@",request.URL.absoluteString);
            NSLog(@"Error: %@", error);
            failure(error);
         else 
            RXMLElement *rootXml = [RXMLElement elementFromXMLData:responseObject];
            success(response, rootXml);
            NSLog(@"Success URL: %@",request.URL.absoluteString);
            NSLog(@"Success %@",rootXml);

        
    ];
    [dataTask resume];

我的十六进制字符串失败共振:

无论如何要使单例正常工作还是我需要为 JSON 和 XML 响应制作 2 个单例?非常感谢任何帮助。谢谢!

【问题讨论】:

仅仅向我们展示十六进制字符串失败是不够的,因为这只是向我们展示了响应的 JSON 正文。您也应该分享错误消息。 【参考方案1】:

您的错误可能告诉您它期望的是 Content-Typeapplication/xml,而您可能有一个 application/json。很难说,因为你没有分享完整的错误,但很可能是这样的。

有两种合乎逻辑的方法。要么:

    让单个 AFHTTPSessionManager 同时接受 XML 和 JSON。因此,使用AFHTTPResponseSerializerresponseSerializerapplication/xmlapplication/jsonacceptableContentTypes(或任何特定的Content-Type 您的两个Web 服务返回),然后当您收到NSData 响应对象时,根据需要解析 XML 或 JSON。

    有单独的 AFHTTPSessionManager 对象,一个用于 XML(responseSerializerAFXMLResponseSerializer),一个用于 JSON(responseSerializerAFJSONResponseSerializer)。注意,如果你这样做,你根本不需要调整acceptableContentTypes

【讨论】:

非常感谢您的帮助。我设法使用 1 个单例 AFHTTPSessionManager。诀窍是我们需要设置正确的 XML 或 JSON 请求和响应序列化器: self.requestSerializer = [AFJSONRequestSerializer serializer];对于 JSON 和 self.requestSerializer = [AFHTTPRequestSerializer 序列化器];对于 XML。你知道我们可以使用可能的 2 或 3 个基本 URL 吗? 不用担心基本 URL。如果会话正在访问单个服务器,这很有用,但在其他情况下,不使用基本 URL 并为请求提供完整的 URL,它会将基本 URL 排除在等式之外。 那么基本 URL 是做什么的?我认为它用于加快连接速度或为相同的连接保存一些信息? 基本 URL 只是为了方便您在 Web 服务中引用端点,而无需引用完整 URL。但是,您可以很容易地引用完整的 URL(或分别编写用于在两个 Web 服务中构建 URL 的方法)。 感谢您的所有澄清。最后一个问题我们如何在用户使用期间保持与服务器的可靠连接(用户在使用 POST 和 GET 应用程序时可以多次请求)?我们应该使用cookies还是其他方法

以上是关于无法使用 AFNetworking 3 为 JSON 和 XML 响应创建单例的主要内容,如果未能解决你的问题,请参考以下文章

无法使用 AFNetworking 3.0 上传图像

AFNetworking 3.0 无法下载图片

AFNetworking 无法序列化压缩响应(响应对象为零)

任务“:cinteropAFNetworkingIOS”执行失败。 > 无法为 AFNetworking 执行 cinterop 处理:无法确定标头位置

无法识别的选择器发送到 UIButton+AFNetworking.h 的实例(UIImageView+AFNetworking 也是)

AFNetworking 后无法获取 UIImage 大小高度