iOS - Increase timeout for AFHTTPRequestOperationManager

后端 未结 5 935
被撕碎了的回忆
被撕碎了的回忆 2021-02-04 09:11

I\'m downloading JSON data from a very slow server. It takes about a minute to get a resoonse from the server. I use AFNetworking library and my code throws \"The request timed

相关标签:
5条回答
  • 2021-02-04 09:46

    In AFNetworking 2 library there is method in AFHTTPRequestSerializer set the request time out interval directly.

    NSString *urlString = [NSString stringWithFormat:@"%@/account.do?JSON&sysparm_action=getRecords",baseUrlString];
    
        NSString *login = [[NSUserDefaults standardUserDefaults] objectForKey:@"login"];
        NSString *password = [[NSUserDefaults standardUserDefaults] objectForKey:@"password"];
    
        [manager setRequestSerializer:[AFHTTPRequestSerializer serializer]];
        [manager.requestSerializer setAuthorizationHeaderFieldWithUsername:login password:password];
        [manager.requestSerializer setTimeoutInterval:TIME_OUT_INTERVAL];
    
    
        [manager GET:urlString parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
            NSLog(@"JSON: %@", responseObject);
            [self parseJsonWithAccountsData:responseObject];
        } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
            NSLog(@"Error: %@", operation.responseString);
            [self performSelectorOnMainThread:@selector(failedWithContactsDownload) withObject:nil waitUntilDone:YES];
        }];
    

    You don't need to override the class to set the request time out interval.

    0 讨论(0)
  • 2021-02-04 09:59

    Actually, the value of timeoutInterval property is ignored - I've checked by debugging the method requestWithMethod:URLString:parameters:error:

    I managed to subclass and override the method (Swift)

    class RequestSerializer: AFHTTPRequestSerializer {
    
        override func requestWithMethod(method: String!, URLString: String!, parameters:AnyObject!, error: NSErrorPointer) -> NSMutableURLRequest {
                var req = super.requestWithMethod(method, URLString: URLString, parameters: parameters, error: error)
                    req.timeoutInterval = self.timeoutInterval
                    return req
        }
    }
    
    0 讨论(0)
  • 2021-02-04 10:09

    Method 1.

    I think the best way is to subclass AFHTTPRequestSerializer and override

    - (NSMutableURLRequest *)requestWithMethod:(NSString *)method
                                     URLString:(NSString *)URLString
                                    parameters:(NSDictionary *)parameters
    

    like this:

    - (NSMutableURLRequest *)requestWithMethod:(NSString *)method
                                     URLString:(NSString *)URLString
                                    parameters:(NSDictionary *)parameters
    {
        NSMutableURLRequest *request = [super requestWithMethod:method URLString:URLString parameters:parameters];
        [request setTimeoutInterval:YOUR_TIMEOUT_INTERVAL_HERE];
    
        return request;
    }
    

    and then

        NSString *urlString = [NSString stringWithFormat:@"%@/account.do?JSON&sysparm_action=getRecords",baseUrlString];
    
        NSString *login = [[NSUserDefaults standardUserDefaults] objectForKey:@"login"];
        NSString *password = [[NSUserDefaults standardUserDefaults] objectForKey:@"password"];
    
        [manager setRequestSerializer:YOUR_NEW_REQUEST_SERIALIZER_HERE];
        [manager.requestSerializer setAuthorizationHeaderFieldWithUsername:login password:password];
    
    
        [manager GET:urlString parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
            NSLog(@"JSON: %@", responseObject);
            [self parseJsonWithAccountsData:responseObject];
        } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
            NSLog(@"Error: %@", operation.responseString);
            [self performSelectorOnMainThread:@selector(failedWithContactsDownload) withObject:nil waitUntilDone:YES];
        }];
    

    Method 2

    NSString *urlString = [NSString stringWithFormat:@"%@/account.do?JSON&sysparm_action=getRecords",baseUrlString];
    
    NSString *login = [[NSUserDefaults standardUserDefaults] objectForKey:@"login"];
    NSString *password = [[NSUserDefaults standardUserDefaults] objectForKey:@"password"];
    
    [manager setRequestSerializer:[AFHTTPRequestSerializer serializer]];
    [manager.requestSerializer setAuthorizationHeaderFieldWithUsername:login password:password];
    
    NSMutableURLRequest *request = [manager.requestSerializer requestWithMethod:@"GET" URLString:[[NSURL URLWithString:urlString relativeToURL:manager.baseURL] absoluteString] parameters:nil];
    [request setTimeoutInterval:YOUR_TIMEOUT_INTERVAL_HERE];
    
    AFHTTPRequestOperation *operation = [manager HTTPRequestOperationWithRequest:request success:^(AFHTTPRequestOperation *operation, id responseObject) {
        NSLog(@"JSON: %@", responseObject);
        [self parseJsonWithAccountsData:responseObject];
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        NSLog(@"Error: %@", operation.responseString);
        [self performSelectorOnMainThread:@selector(failedWithContactsDownload) withObject:nil waitUntilDone:YES];
    }];
    [manager.operationQueue addOperation:operation];
    
    0 讨论(0)
  • 2021-02-04 10:10

    I'm a bit lazy to categorize or subclass. You can access the manager's request serializer directly:

    AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
    manager.requestSerializer.timeoutInterval = INTERNET_TIMEOUT;
    manager.requestSerializer.cachePolicy = NSURLRequestReloadIgnoringLocalAndRemoteCacheData;
    
    0 讨论(0)
  • 2021-02-04 10:10

    Create a subclass

    self.requestOperationManager.requestSerializer = [[TimeoutAFHTTPRequestSerializer alloc] initWithTimeout:30];
    

    TimeoutAFHTTPRequestSerializer.h

    #import "AFURLRequestSerialization.h"
    
    @interface TimeoutAFHTTPRequestSerializer : AFHTTPRequestSerializer
    
    @property (nonatomic, assign) NSTimeInterval timeout;
    
    - (id)initWithTimeout:(NSTimeInterval)timeout;
    
    @end
    

    TimeoutAFHTTPRequestSerializer.m

    #import "TimeoutAFHTTPRequestSerializer.h"
    
    @implementation TimeoutAFHTTPRequestSerializer
    
    - (id)initWithTimeout:(NSTimeInterval)timeout {
    
        self = [super init];
        if (self) {
            self.timeout = timeout;
        }
        return self;
    
    }
    
    - (NSMutableURLRequest *)requestWithMethod:(NSString *)method
                                     URLString:(NSString *)URLString
                                    parameters:(NSDictionary *)parameters
                                         error:(NSError *__autoreleasing *)error
    {
        NSMutableURLRequest *request = [super requestWithMethod:method URLString:URLString parameters:parameters error:error];
    
        if (self.timeout > 0) {
            [request setTimeoutInterval:self.timeout];
        }
        return request;
    }
    
    @end
    
    0 讨论(0)
提交回复
热议问题