AFNetworking: Handle error globally and repeat request

前端 未结 6 1646
温柔的废话
温柔的废话 2020-12-07 11:07

I have a use case that should be rather common but I can\'t find an easy way to handle it with AFNetworking:

Whenever the server returns a specific status code for <

6条回答
  •  粉色の甜心
    2020-12-07 12:01

    If you are subclassing AFHTTPSessionManager or using directly an AFURLSessionManager you could use the following method to set a block executed after the completion of a task:

    /**
     Sets a block to be executed as the last message related to a specific task, as handled by the `NSURLSessionTaskDelegate` method `URLSession:task:didCompleteWithError:`.
    
     @param block A block object to be executed when a session task is completed. The block has no return value, and takes three arguments: the session, the task, and any error that occurred in the process of executing the task.
    */
    - (void)setTaskDidCompleteBlock:(void (^)(NSURLSession *session, NSURLSessionTask *task, NSError *error))block;
    

    Just perform whatever you want to do for each tasks of the session in it:

    [self setTaskDidCompleteBlock:^(NSURLSession *session, NSURLSessionTask *task, NSError *error) {
        if ([task.response isKindOfClass:[NSHTTPURLResponse class]]) {
            NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)task.response;
            if (httpResponse.statusCode == 500) {
    
            }
         }
    }];
    

    EDIT: In fact if you need to handle an error returned in the response object the above method won't do the job. One way if you are subclassing AFHTTPSessionManager could be to subclass and set a custom response serializer with it's responseObjectForResponse:data:error: overloaded like that:

    @interface MyJSONResponseSerializer : AFJSONResponseSerializer
    @end
    
    @implementation MyJSONResponseSerializer
    
    #pragma mark - AFURLResponseSerialization
    - (id)responseObjectForResponse:(NSURLResponse *)response
                               data:(NSData *)data
                              error:(NSError *__autoreleasing *)error
    {
        id responseObject = [super responseObjectForResponse:response data:data error:error];
    
        if ([responseObject isKindOfClass:[NSDictionary class]]
            && /* .. check for status or error fields .. */)
        {
            // Handle error globally here
        }
    
        return responseObject;
    }
    
    @end
    

    and set it in your AFHTTPSessionManager subclass:

    @interface MyAPIClient : AFHTTPSessionManager
    + (instancetype)sharedClient;
    @end
    
    @implementation MyAPIClient
    
    + (instancetype)sharedClient {
        static MyAPIClient *_sharedClient = nil;
        static dispatch_once_t onceToken;
    
        dispatch_once(&onceToken, ^{
            _sharedClient = [[MyAPIClient alloc] initWithBaseURL:[NSURL URLWithString:MyAPIBaseURLString]];
            _sharedClient.responseSerializer = [MyJSONResponseSerializer serializer];
        });
    
        return _sharedClient;
    }
    
    @end
    

提交回复
热议问题