Search code examples
ioscachingrestkit-0.20request.querystring

Not caching specific requests using RestKit


My problem

I'm not being able to cache a specific request but other ones using the same library and server yes

http://server.com/lastEntities?authors=37&authors=125&authors=32&authors=36&authors=561&page=0&fromDate=&toDate=&pageSize=20

I've asked back-end people to change this query string due to that repeated param named "authors", but seems that now isn't possible, this is one of my candidates for being my bug but i'm not sure.

I'm using Charles Proxy for see the client requests and only the one above is always calling ignoring the server cache policy and beating the network again and again.

Server response

Cache control:

no-transform, max-age=300

Content-type:

application/json;charset=utf-8

Code

RestKit ~> 0.20.0

Setting the NSURL sharedCache

In the AppDelegate:

NSURLCache *URLCache = [[NSURLCache alloc] initWithMemoryCapacity:10 * 1024 * 1024
                                                      diskCapacity:20 * 1024 * 1024
                                                          diskPath:nil];
[NSURLCache setSharedURLCache:URLCache];

Other blind attemp to cache

In my subclass of "RKObjectManager" i'm doing this as an attempt to force cache, but if i'm not wrong RestKit use the NSURLCache transparently for the developer, the only thing needed is that the server returns the appropiate "Cache control" header.

- (NSMutableURLRequest *)requestWithObject:(id)object method:(RKRequestMethod)method path:(NSString *)path parameters:(NSDictionary *)parameters
{
    NSMutableURLRequest *request = [super requestWithObject:object method:method path:path parameters:parameters];
    request.cachePolicy = NSURLRequestUseProtocolCachePolicy ;

    return request;
}

Doing the request

- (void) lastEntities:(NSDictionary *)params
            onSuccess:(void (^)(NSArray *entities, int numEntities)) success
              failure:(void (^)(RKObjectRequestOperation *operation, NSError *error))failure{
NSString *path = @"entity";

NSMutableDictionary *requestParams = [NSMutableDictionary dictionaryWithDictionary:params];

NSString *urlParams = [NSString stringWithFormat:@"%@?",path];

//Compose the URL with query params


[sharedManager addResponseDescriptor:[RKResponseDescriptor responseDescriptorWithMapping:[MVEntityModel responseMapping]
                                                                                  method:RKRequestMethodGET
                                                                             pathPattern:path
                                                                                 keyPath:@"entities"
                                                                             statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)]];

RKObjectMapping *mapping = [RKObjectMapping mappingForClass:[NSMutableDictionary class]];
[mapping addAttributeMappingsFromDictionary:@{@"numEntities": @"numEntities"}];
[sharedManager addResponseDescriptor:[RKResponseDescriptor responseDescriptorWithMapping:mapping
                                                                                  method:RKRequestMethodGET
                                                                             pathPattern:path
                                                                                 keyPath:nil
                                                                             statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)]];

[self getObjectsAtPath:urlParams parameters:nil success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
    if (success) {
        success([mappingResult.dictionary objectForKey:@"entities"], (int)[[[mappingResult.dictionary objectForKey:[NSNull null]] objectForKey:@"numEntities"] integerValue]);
    }
} failure:nil
 ];
}

Solution

  • The most obvious reason for not storing a response in the cache is the size of the response. In NSURLCache there is a mechanism for deciding what the maximum file size is it will cache. This size is related to your maximum cache size. The exact relation is not clear (nowhere documented) Try setting your cache size much larger than the 10 and 20MB you have now.