Files
RestKit/Docs/Design/RKCache.txt

93 lines
4.0 KiB
Plaintext

RestKit Cache Design
====================
This document outlines the design for a lightweight cache implementation for the RestKit framework. The goals
of the cache are:
* Provide support for offline access to data payloads
* Provide storage of last modification times for etags
* Provide cache policies at the client and request level
* RKResponse should be able to answer - (BOOL)wasLoadedFromCache
* Each RKClient has its own cache (path initialized by Base URL somehow?)
* RKCache should have a storage policy. This should be settable to session (store for the run of the app) or permanently.
Needs to store:
* Key/values
* Settable via NSURL (not resource path)
Concerns:
* Does this need to be harmonized with the managed object cache? Can it be?
* Don't love how tightly coupled cacheing is in Three20. Want something more orthogonal.
* How are we going to unit test this? Need to identify test cases...
* Where does the cache loading logic go? Request queue? Client? Inside of RKRequest? New class?
References:
* TTURLCache
* ASIDownloadCache
ETags:
* http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
* Comes across as either "ETag" or "Etag" header
* Should be contained to RKRequest / RKResponse (don't bleed through into the cache)
* Needs to be added on load via If-None-Match
Request cache policies:
* RKClient should have a default cache policy that gets passed through to requests
* RKRequest will have a cache policy property. This determines when and how to utilize the cache.
* You should be able to bitwise | these together, i.e. RKRequestCachePolicyLoadIfOffline | RKRequestCachePolicyEtag
typedef enum {
RKRequestCachePolicyNone = 0, // Never use the cache
RKRequestCachePolicyLoadIfOffline, // Load from the cache when we are offline
RKRequestCachePolicyLoadOnError, // Load from the cache if we encounter an error
RKRequestCachePolicyEtag, // Load from the cache if we have data stored and the server returns a 304 (not modified) response
RKRequestCachePolicyDefault = RKRequestCachePolicyEtag;
} RKRequestCachePolicy;
###################################################################################
// Proposed Interface
// Returns a cache key for a URL (md5 the full URL after coercing to a string)
// This will let you work with the cache via URL's pretty easily
- (NSString*)RKCacheKeyForURL:(NSURL*)URL;
// Storage policy. Determines if we clear the cache out when the app is shut down. Cache
// instance needs to register for
typedef enum {
RKCacheStoragePolicyDisabled, // The cache has been disabled. Attempts to store data will silently fail
RKCacheStoragePolicyForDurationOfSession, // Cache data for the length of the session. Clear cache at app exit.
RKCacheStoragePolicyPermanently // Cache data permanently, until explicitly expired or flushed
} RKCacheStoragePolicy;
@interface RKCache : NSObject {
NSString* _cachePath;
RKCacheStoragePolicy _storagePolicy;
}
@property (nonatomic, readonly) NSString* cachePath; // Full path to the cache
@property (nonatomic, assign) RKCacheStoragePolicy storagePolicy; // User can change storage policy.
// Should be initialized with the full path to store it. RKClient should
// figure out the appropriate path when initializing.
- (id)initWithCachePath:(NSString*)cachePath storagePolicy:(RKCacheStoragePolicy)storagePolicy;
// Key/value storage
- (NSString*)pathForKey:(NSString*)key;
- (BOOL)hasDataForKey:(NSString*)key;
- (void)storeData:(NSData*)data forKey:(NSString*)key;
- (NSData*)dataForKey:(NSString*)key;
- (NSData*)dataForKey:(NSString*)key expires:(NSTimeInterval)expirationAge
timestamp:(NSDate**)timestamp;
// Cache Invalidation
- (void)invalidateKey:(NSString*)key;
- (void)invalidateAll;
@end
// RKRequest
Get new properties:
NSString* cacheKey; // When GET, defaults to RKCacheKeyForURL. For POST/PUT, md5 of the serialization data.
RKRequestCachePolicy cachePolicy; // Cache policy inherited from RKClient.
// RKResponse
BOOL wasLoadedFromCache; // YES when the response was built from cached data