【问题标题】:Correct way to use AFHTTPSessionManager as a singleton?将 AFHTTPSessionManager 用作单例的正确方法?
【发布时间】:2013-11-07 05:45:27
【问题描述】:

我正在尝试使用 AFNetworking 2.0 来执行我的网络请求,但我遇到了一些奇怪的行为。我将AFHTTPSessionManager 子类化为suggested in the documentation,并提供了一个类方法,该方法返回一个设置了基本url 并设置我的auth 标头的单例对象。

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

我的应用程序使用它发出 POST 请求来验证我的用户。这很好用。然后我发出一个 GET 请求来检索对象列表。也很好用。然后我发出相同的 GET 请求,我收到网络错误Error Domain=AFNetworkingErrorDomain Code=-1016 "Request failed: unacceptable content-type: application/json" 这是完全相同的 GET 请求,但在第二次调用时失败。当我取消注释 sharedInstance.responseSerializer 行时,每次我获得对共享实例的引用时,我都会创建一个响应序列化程序的新实例,然后我不会再收到此错误。

一个 responseSerializer 不能安全地多次使用吗?感觉就像某种状态在请求之间徘徊。设置它的正确方法是什么?

【问题讨论】:

  • 一个responseSerializer可以安全地多次使用。您是否在 POST(身份验证)代码中的任何位置更改 responseSerializer
  • 什么是self.serializer?我在 AFHTTPSessionManager 或 AFURLSessionManager 界面中没有看到。
  • 原来我什至没有设置responseSerializer。我尝试在 initWithBaseUrl 方法中设置一次,但遇到了同样的问题。只有当我每次请求共享实例时都设置它时,错误才会消失。
  • self.serializer 是我添加到子类的一个属性,它包含对我在 initWithBaseUrl 方法中创建的 AFHTTPRequestSerializer 实例的引用。我持有一个参考,因此我可以在它更改时更改我的会话 ID。
  • @AaronBrager 您的原始评论是正确的...我们回顾了所有的响应处理程序,并且我们在一次情况下设置了我们的 responseSerializer 来处理图像下载并且从不设置它。如果您想将其添加为答案,我很乐意将您的评论标记为答案。感谢您的帮助。

标签: afnetworking-2


【解决方案1】:

可以安全地多次使用响应序列化程序。根据您发布的错误消息“不可接受的内容类型:应用程序/json”,您似乎正在将 responseSerializer 设置为代码中的其他内容。只要设置为[AFJSONResponseSerializer serializer],JSON 就会正确序列化。

【讨论】:

  • 这个答案为我节省了很多时间!谢谢@亚伦!就我而言,我在下载照片消息列表时将responseSerializer 设置为AFJSONResonseSerializer,然后在下载每张照片时,responseSerializer 被设置为AFImageResponseSerializer。由于答案中解释的原因,重用共享客户端并不完全。
  • @indyfromoz 您可能需要考虑制作一个复合序列化程序,如果是 JSON,它会解析 JSON,如果是图像,它会解析图像。
猜你喜欢
  • 1970-01-01
  • 2020-01-17
  • 1970-01-01
  • 2021-03-07
  • 1970-01-01
  • 2011-06-24
  • 1970-01-01
  • 2019-06-17
  • 1970-01-01
相关资源
最近更新 更多