web-dev-qa-db-fra.com

Comment définir un délai d'expiration de demande et une stratégie de cache dans AFNetworking 2.0?

Je suis l'exemple de code donné

AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
[manager GET:@"http://example.com/resources.json" parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
    NSLog(@"JSON: %@", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    NSLog(@"Error: %@", error);
}];

Pour changer le délai d'attente et la politique de cache, j'ai "piraté" la bibliothèque et créé

- (AFHTTPRequestOperation *)GET:(NSString *)URLString
                     parameters:(NSDictionary *)parameters
                          timeoutInterval:(NSTimeInterval)timeoutInterval
                    cachePolicy:(NSURLRequestCachePolicy)cachePolicy
                        success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success
                        failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure
{
    NSMutableURLRequest *request = [self.requestSerializer requestWithMethod:@"GET" URLString:[[NSURL URLWithString:URLString relativeToURL:self.baseURL] absoluteString] parameters:parameters];
    [request setTimeoutInterval:timeoutInterval];
    [request setCachePolicy:cachePolicy];
    AFHTTPRequestOperation *operation = [self HTTPRequestOperationWithRequest:request success:success failure:failure];
    [self.operationQueue addOperation:operation];

    return operation;
}

Existe-t-il une façon propre de procéder?

26
joao

Je suis un peu paresseux pour catégoriser ou sous-classer. Vous pouvez accéder directement au sérialiseur de demande du gestionnaire:

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

Le mieux est de créer une sous-classe

(vous pouvez également ajouter la politique de cache de la même manière)

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

tiliser

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

Vous pouvez également créer une catégorie AFHTTPRequestOperationManager + timeout pour ajouter cette méthode sans avoir à sous-classer AFHTTPRequestOperationManager.

4
Pierre Marty

Essayez quelque chose comme:

NSURLRequest *request = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:kRequestTimout];

kRequestTimout est la durée de temporisation souhaitée

Créez ensuite votre demande sérialisée:

NSURLRequest *serializedRequest = [self.requestOperationManager.requestSerializer requestBySerializingRequest:request withParameters:parameters error:&error];

Et créez et ajoutez votre opération de demande:

AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:serializedRequest];
[operation setCompletionBlockWithSuccess:successBlock failure:failureBlock];
[self.requestOperationManager.operationQueue addOperation:operation];
1
user3465357

Jetez un œil à Méthode 1 pour une façon plus propre de le faire: https://stackoverflow.com/a/21238330/43504

La différence est que j'utilise le sous-classement et que je ne corrige pas le code d'AFNetworking.

Une chose que j'ai oublié de mentionner. Dans cette réponse, je modifie uniquement l'intervalle de temporisation, mais l'ajout d'une autre stratégie de mise en cache ne représente qu'une ligne de code supplémentaire.

1
arturgrigor