Lê Khánh Vinh Lê Khánh Vinh - 3 months ago 46
iOS Question

Cannot make singleton for JSON and XML response using AFNetworking 3

Hi I'm Making a singleton for networking for JSON and XML response

my ApiClient.h

+ (ApiClient *)sharedInstance;

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


My 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;
}


The problem is the singleton cannot handle both XML and JSON response. It can successfully parse the JSON and XML for 1 time. But when call again to parse again) (after successfully parse XML) result will not be parse properly (give hex string response)

My JSON block request

- (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];

}


My XML block request

- (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];
}


My hex string fail resonse:
enter image description here

Anyway to make the singleton work properly or I need to make 2 singleton for JSON and XML response? Any help is much appreciate. Thanks!

Rob Rob
Answer

Your error is likely telling you that it was expecting a Content-Type of application/xml, and you may of had an application/json. It's hard to tell because you didn't share the full error, but it's likely something like that.

There are two logical approaches. Either:

  1. Have single AFHTTPSessionManager accept both XML and JSON. So, with a responseSerializer of AFHTTPResponseSerializer and an acceptableContentTypes of both application/xml and application/json (or whatever specific Content-Type your two web services return), and then when you receive the NSData response object, either parse the XML or JSON as appropriate.

  2. Have separate AFHTTPSessionManager objects, one for XML (with responseSerializer of AFXMLResponseSerializer) and one for JSON (with responseSerializer of AFJSONResponseSerializer). Note, if you do this, you don't have to adjust acceptableContentTypes at all.

Comments