Подтвердить что ты не робот

IOS - увеличение тайм-аута для AFHTTPRequestOperationManager

Я загружаю данные JSON с очень медленного сервера. Требуется около минуты, чтобы получить перерыв с сервера. Я использую библиотеку AFNetworking, и мой код выдает ошибку "Ошибка при запросе":

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

Не удалось найти способ установить тайм-аут для AFHTTPRequestOperationManager. Как я могу это сделать?

4b9b3361

Ответ 1

Метод 1.

Я думаю, что лучший способ - подкласс AFHTTPRequestSerializer и переопределить

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

вот так:

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

а затем

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

Метод 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];

Ответ 2

В библиотеке AFNetworking 2 есть метод в AFHTTPRequestSerializer установить интервал времени ожидания запроса напрямую.

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

Вам не нужно переопределять класс, чтобы установить интервал времени ожидания запроса.

Ответ 3

Я немного ленив, чтобы классифицировать или подклассы. Вы можете напрямую обращаться к сериализатору запросов менеджера:

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

Ответ 4

Создайте подкласс

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

Ответ 5

Собственно, значение свойства timeoutInterval игнорируется - я проверил путем отладки метода requestWithMethod:URLString:parameters:error:

Мне удалось подклассировать и переопределить метод (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
    }
}