Correct way to use AFHTTPSessionManager as a singleton?

ideaencoder picture ideaencoder · Oct 28, 2013 · Viewed 9.6k times · Source

I'm trying to use AFNetworking 2.0 to perform my network requests but I'm running into some odd behavior. I've subclassed AFHTTPSessionManager as suggested in the documentation and provided a class method that returns a singleton object that has the base url set as well as sets my auth header.

+ (id)sharedInstance {
  static dispatch_once_t once;
  static MyHTTPClient *sharedInstance;

  dispatch_once(&once, ^{
    sharedInstance = [[self alloc] initWithBaseURL: NSURLURLWithString:kPlatformAPIBaseURL]];
  });

  //Uncommenting this line makes the error go away
  //sharedInstance.responseSerializer = [AFJSONResponseSerializer serializer];

  //get latest session id everytime someone gets an instance of the client
  sharedInstance.sessionId = [MySessionManager getSessionId];

  return sharedInstance;
}

- (instancetype)initWithBaseURL:(NSURL *)url {
  self = [super initWithBaseURL:url];

  if(self) {
    self.sessionId = [FSSessionManager getSessionId];

    self.serializer = [AFHTTPRequestSerializer serializer];
    [_serializer setValue:_sessionId forHTTPHeaderField:kAuthorizationHeader];
    [_serializer setValue:@"application/json" forHTTPHeaderField:kAcceptHeader];

    self.requestSerializer = _serializer;
  }

  return self;
}

- (void)setSessionId:(NSString *)sessionId {
  _sessionId = sessionId;
  [self.serializer setValue:_sessionId forHTTPHeaderField:kAuthorizationHeader];
}

My app uses this to make a POST request to authenticate my user. That works great. I then make a GET request to retrieve a list of objects. Also works great. I then make the same GET request and I get back a network error Error Domain=AFNetworkingErrorDomain Code=-1016 "Request failed: unacceptable content-type: application/json" It's the exact same GET request but it fails on the second call. When I uncomment the sharedInstance.responseSerializer line so I create a new instance of the response serializer each time I get a reference to my shared instance then I don't get this error anymore.

Can a responseSerializer not be used multiple times safely? It feels like some sort of state is hanging around across requests. What's the correct way to set this up?

Answer

Aaron Brager picture Aaron Brager · Oct 28, 2013

A response serializer can be used multiple times safely. Based on the error message you posted, "unacceptable content-type: application/json ", it appears you're setting responseSerializer to something else elsewhere in your code. JSON will serialize properly as long as it's set to [AFJSONResponseSerializer serializer].