iOS: aumenta el time de espera para AFHTTPRequestOperationManager

Estoy descargando datos JSON de un server muy lento. Se tarda alnetworkingedor de un minuto para get una respuesta del server. Utilizo la biblioteca AFNetworking y mi código muestra el error "El time de espera de la request":

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

No encontré una manera de establecer un time de espera para AFHTTPRequestOperationManager . ¿Cómo puedo hacerlo?

Método 1.

Creo que la mejor manera es subclass AFHTTPRequestSerializer y anular

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

Me gusta esto:

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

y entonces

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

Método 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]; 

En la biblioteca AFNetworking 2 hay un método en AFHTTPRequestSerializer establece el intervalo de time de espera de request directamente.

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

No necesita anular la class para establecer el intervalo de time de request.

Soy un poco perezoso para clasificar o subclass. Puede acceder directamente al serializador de requestes del administrador:

 AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager]; manager.requestSerializer.timeoutInterval = INTERNET_TIMEOUT; manager.requestSerializer.cachePolicy = NSURLRequestReloadIgnoringLocalAndRemoteCacheData; 

Crea una 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 

En realidad, el valor de la propiedad timeoutInterval se ignora: he comprobado depurando el método requestWithMethod:URLString:parameters:error:

Logré subclasificar y anular el método (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 } }