From db6adb2d00d541c0f2bd8bf91fbcd86ae4aacb3a Mon Sep 17 00:00:00 2001 From: Sam Stewart Date: Wed, 28 Mar 2012 17:41:42 -0700 Subject: [PATCH 1/5] [fix] category warnings in xcode 4.3 by using wrapper SDCachedURLResponse instead of NSCachedURLResponse category smashing --- SDURLCache.h | 14 ++++- SDURLCache.m | 164 ++++++++++++++++++++++++++++----------------------- 2 files changed, 102 insertions(+), 76 deletions(-) diff --git a/SDURLCache.h b/SDURLCache.h index adbcebd..00c8325 100644 --- a/SDURLCache.h +++ b/SDURLCache.h @@ -8,7 +8,14 @@ #import -@interface SDURLCache : NSURLCache +// wrapper pattern +@interface SDCachedURLResponse : NSObject ++ (id)cachedURLResponseWithNSCachedURLResponse:(NSCachedURLResponse*)url_response; + +@property (nonatomic, retain) NSCachedURLResponse *cached_response; +@end + +@interface SDURLCachePH : NSURLCache { @private NSString *diskCachePath; @@ -50,4 +57,9 @@ */ - (BOOL)isCached:(NSURL *)url; +/* + * Returns the hash key for the url +*/ ++ (NSString *)cacheKeyForURL:(NSURL *)url; + @end diff --git a/SDURLCache.m b/SDURLCache.m index 5117a3e..d4c2063 100644 --- a/SDURLCache.m +++ b/SDURLCache.m @@ -7,6 +7,7 @@ // #import "SDURLCache.h" +#import "PHConstants.h" #import static NSTimeInterval const kSDURLCacheInfoDefaultMinCacheInterval = 5 * 60; // 5 minute @@ -20,42 +21,65 @@ static NSDateFormatter* CreateDateFormatter(NSString *format) { NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; - NSLocale *locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US"]; - - [dateFormatter setLocale:locale]; + [dateFormatter setLocale:[[[NSLocale alloc] initWithLocaleIdentifier:@"en_US"] autorelease]]; [dateFormatter setTimeZone:[NSTimeZone timeZoneWithAbbreviation:@"GMT"]]; [dateFormatter setDateFormat:format]; - [locale release]; - return [dateFormatter autorelease]; } -@implementation NSCachedURLResponse(NSCoder) -#pragma clang diagnostic push -#pragma clang diagnostic ignored "-Wobjc-protocol-method-implementation" +@implementation SDCachedURLResponse +@synthesize cached_response; + ++ (id)cachedURLResponseWithNSCachedURLResponse:(NSCachedURLResponse *)url_response { + SDCachedURLResponse *response = [[SDCachedURLResponse alloc] init]; + response.cached_response = url_response; + + return [response autorelease]; +} +#pragma mark NSCopying Methods +- (id)copyWithZone:(NSZone *)zone { + SDCachedURLResponse *newResponse = [[[self class] allocWithZone:zone] init]; + if (newResponse) { + newResponse.cached_response = [[self.cached_response copyWithZone:zone] autorelease]; + } + + return newResponse; +} + +#pragma mark NSCoding Methods - (void)encodeWithCoder:(NSCoder *)coder { - [coder encodeDataObject:self.data]; - [coder encodeObject:self.response forKey:@"response"]; - [coder encodeObject:self.userInfo forKey:@"userInfo"]; - [coder encodeInt:self.storagePolicy forKey:@"storagePolicy"]; + // force write the data of underlying cached response + [coder encodeDataObject:self.cached_response.data]; + [coder encodeObject:self.cached_response.response forKey:@"response"]; + [coder encodeObject:self.cached_response.userInfo forKey:@"userInfo"]; + [coder encodeInt:self.cached_response.storagePolicy forKey:@"storagePolicy"]; } - (id)initWithCoder:(NSCoder *)coder { - return [self initWithResponse:[coder decodeObjectForKey:@"response"] - data:[coder decodeDataObject] - userInfo:[coder decodeObjectForKey:@"userInfo"] - storagePolicy:[coder decodeIntForKey:@"storagePolicy"]]; + self = [super init]; + + if (self) { + self.cached_response = [[[NSCachedURLResponse alloc] initWithResponse:[coder decodeObjectForKey:@"response"] + data:[coder decodeDataObject] + userInfo:[coder decodeObjectForKey:@"userInfo"] + storagePolicy:[coder decodeIntForKey:@"storagePolicy"]] autorelease]; + } + + return self; } -#pragma clang diagnostic pop +- (void)dealloc { + [super dealloc]; + [cached_response release], cached_response = nil; +} @end -@interface SDURLCache () +@interface SDURLCachePH () @property (nonatomic, retain) NSString *diskCachePath; @property (nonatomic, readonly) NSMutableDictionary *diskCacheInfo; @property (nonatomic, retain) NSOperationQueue *ioQueue; @@ -63,7 +87,7 @@ @interface SDURLCache () - (void)periodicMaintenance; @end -@implementation SDURLCache +@implementation SDURLCachePH @synthesize diskCachePath, minCacheInterval, ioQueue, periodicMaintenanceOperation, ignoreMemoryOnlyStoragePolicy; @dynamic diskCacheInfo; @@ -147,7 +171,7 @@ + (NSDate *)expirationDateFromHeaders:(NSDictionary *)headers withStatusCode:(NS NSDate *now; if (date) { - now = [SDURLCache dateFromHttpDateString:date]; + now = [SDURLCachePH dateFromHttpDateString:date]; } else { @@ -156,7 +180,7 @@ + (NSDate *)expirationDateFromHeaders:(NSDictionary *)headers withStatusCode:(NS } // Look at info from the Cache-Control: max-age=n header - NSString *cacheControl = [[headers objectForKey:@"Cache-Control"] lowercaseString]; + NSString *cacheControl = [headers objectForKey:@"Cache-Control"]; if (cacheControl) { NSRange foundRange = [cacheControl rangeOfString:@"no-store"]; @@ -167,12 +191,11 @@ + (NSDate *)expirationDateFromHeaders:(NSDictionary *)headers withStatusCode:(NS } NSInteger maxAge; - foundRange = [cacheControl rangeOfString:@"max-age"]; + foundRange = [cacheControl rangeOfString:@"max-age="]; if (foundRange.length > 0) { NSScanner *cacheControlScanner = [NSScanner scannerWithString:cacheControl]; [cacheControlScanner setScanLocation:foundRange.location + foundRange.length]; - [cacheControlScanner scanString:@"=" intoString:nil]; if ([cacheControlScanner scanInteger:&maxAge]) { if (maxAge > 0) @@ -192,7 +215,7 @@ + (NSDate *)expirationDateFromHeaders:(NSDictionary *)headers withStatusCode:(NS if (expires) { NSTimeInterval expirationInterval = 0; - NSDate *expirationDate = [SDURLCache dateFromHttpDateString:expires]; + NSDate *expirationDate = [SDURLCachePH dateFromHttpDateString:expires]; if (expirationDate) { expirationInterval = [expirationDate timeIntervalSinceDate:now]; @@ -220,7 +243,7 @@ + (NSDate *)expirationDateFromHeaders:(NSDictionary *)headers withStatusCode:(NS if (lastModified) { NSTimeInterval age = 0; - NSDate *lastModifiedDate = [SDURLCache dateFromHttpDateString:lastModified]; + NSDate *lastModifiedDate = [SDURLCachePH dateFromHttpDateString:lastModified]; if (lastModifiedDate) { // Define the age of the document by comparing the Date header with the Last-Modified header @@ -315,7 +338,7 @@ - (void)removeCachedResponseForCachedKeys:(NSArray *)cacheKeys { NSMutableDictionary *accesses = [self.diskCacheInfo objectForKey:kSDURLCacheInfoAccessesKey]; NSMutableDictionary *sizes = [self.diskCacheInfo objectForKey:kSDURLCacheInfoSizesKey]; - NSFileManager *fileManager = [[NSFileManager alloc] init]; + NSFileManager *fileManager = [[[NSFileManager alloc] init] autorelease]; while ((cacheKey = [enumerator nextObject])) { @@ -327,7 +350,6 @@ - (void)removeCachedResponseForCachedKeys:(NSArray *)cacheKeys diskCacheUsage -= cacheItemSize; [self.diskCacheInfo setObject:[NSNumber numberWithUnsignedInteger:diskCacheUsage] forKey:kSDURLCacheInfoDiskUsageKey]; } - [fileManager release]; } [pool drain]; @@ -368,9 +390,12 @@ - (void)balanceDiskUsage - (void)storeToDisk:(NSDictionary *)context { NSURLRequest *request = [context objectForKey:@"request"]; - NSCachedURLResponse *cachedResponse = [context objectForKey:@"cachedResponse"]; + + // use wrapper to ensure we save appropriate fields.. + SDCachedURLResponse *cachedResponse = [SDCachedURLResponse + cachedURLResponseWithNSCachedURLResponse:[context objectForKey:@"cachedResponse"]]; - NSString *cacheKey = [SDURLCache cacheKeyForURL:request.URL]; + NSString *cacheKey = [SDURLCachePH cacheKeyForURL:request.URL]; NSString *cacheFilePath = [diskCachePath stringByAppendingPathComponent:cacheKey]; [self createDiskCachePath]; @@ -402,25 +427,21 @@ - (void)storeToDisk:(NSDictionary *)context - (void)periodicMaintenance { - // If another maintenance operation is already sceduled, cancel it so this new operation will be executed after other + // If another same maintenance operation is already scheduled, cancel it so this new operation will be executed after other // operations of the queue, so we can group more work together [periodicMaintenanceOperation cancel]; self.periodicMaintenanceOperation = nil; - // If disk usage exceeds capacity, run the cache eviction operation and if cacheInfo dictionary is dirty, save it in an operation + // If disk usage outrich capacity, run the cache eviction operation and if cacheInfo dictionnary is dirty, save it in an operation if (diskCacheUsage > self.diskCapacity) { - NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(balanceDiskUsage) object:nil]; - self.periodicMaintenanceOperation = operation; + self.periodicMaintenanceOperation = [[[NSInvocationOperation alloc] initWithTarget:self selector:@selector(balanceDiskUsage) object:nil] autorelease]; [ioQueue addOperation:periodicMaintenanceOperation]; - [operation release]; } else if (diskCacheInfoDirty) { - NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(saveCacheInfo) object:nil]; - self.periodicMaintenanceOperation = operation; + self.periodicMaintenanceOperation = [[[NSInvocationOperation alloc] initWithTarget:self selector:@selector(saveCacheInfo) object:nil] autorelease]; [ioQueue addOperation:periodicMaintenanceOperation]; - [operation release]; } } @@ -429,7 +450,9 @@ - (void)periodicMaintenance + (NSString *)defaultCachePath { NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES); - return [[paths objectAtIndex:0] stringByAppendingPathComponent:@"SDURLCache"]; + NSString *path = [[paths objectAtIndex:0] stringByAppendingPathComponent:@"SDURLCache"]; + NSLog(@"cache path: %@", path); + return path; } #pragma mark NSURLCache @@ -442,11 +465,9 @@ - (id)initWithMemoryCapacity:(NSUInteger)memoryCapacity diskCapacity:(NSUInteger self.diskCachePath = path; // Init the operation queue - NSOperationQueue *queue = [[NSOperationQueue alloc] init]; - self.ioQueue = queue; - [queue release]; - + self.ioQueue = [[[NSOperationQueue alloc] init] autorelease]; ioQueue.maxConcurrentOperationCount = 1; // used to streamline operations in a separate thread + self.ignoreMemoryOnlyStoragePolicy = YES; } @@ -455,7 +476,7 @@ - (id)initWithMemoryCapacity:(NSUInteger)memoryCapacity diskCapacity:(NSUInteger - (void)storeCachedResponse:(NSCachedURLResponse *)cachedResponse forRequest:(NSURLRequest *)request { - request = [SDURLCache canonicalRequestForRequest:request]; + request = [SDURLCachePH canonicalRequestForRequest:request]; if (request.cachePolicy == NSURLRequestReloadIgnoringLocalCacheData || request.cachePolicy == NSURLRequestReloadIgnoringLocalAndRemoteCacheData @@ -478,7 +499,7 @@ - (void)storeCachedResponse:(NSCachedURLResponse *)cachedResponse forRequest:(NS // RFC 2616 section 13.3.4 says clients MUST use Etag in any cache-conditional request if provided by server if (![headers objectForKey:@"Etag"]) { - NSDate *expirationDate = [SDURLCache expirationDateFromHeaders:headers + NSDate *expirationDate = [SDURLCachePH expirationDateFromHeaders:headers withStatusCode:((NSHTTPURLResponse *)cachedResponse.response).statusCode]; if (!expirationDate || [expirationDate timeIntervalSinceNow] - minCacheInterval <= 0) { @@ -487,37 +508,37 @@ - (void)storeCachedResponse:(NSCachedURLResponse *)cachedResponse forRequest:(NS } } - NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self - selector:@selector(storeToDisk:) - object:[NSDictionary dictionaryWithObjectsAndKeys: - cachedResponse, @"cachedResponse", - request, @"request", - nil]]; - [ioQueue addOperation:operation]; - [operation release]; + [ioQueue addOperation:[[[NSInvocationOperation alloc] initWithTarget:self selector:@selector(storeToDisk:) + object:[NSDictionary dictionaryWithObjectsAndKeys: + cachedResponse, @"cachedResponse", + request, @"request", nil]] autorelease]]; } } - (NSCachedURLResponse *)cachedResponseForRequest:(NSURLRequest *)request { - request = [SDURLCache canonicalRequestForRequest:request]; + request = [SDURLCachePH canonicalRequestForRequest:request]; NSCachedURLResponse *memoryResponse = [super cachedResponseForRequest:request]; if (memoryResponse) - { return memoryResponse; - } - NSString *cacheKey = [SDURLCache cacheKeyForURL:request.URL]; + NSString *cacheKey = [SDURLCachePH cacheKeyForURL:request.URL]; // NOTE: We don't handle expiration here as even staled cache data is necessary for NSURLConnection to handle cache revalidation. // Staled cache data is also needed for cachePolicies which force the use of the cache. @synchronized(self.diskCacheInfo) { NSMutableDictionary *accesses = [self.diskCacheInfo objectForKey:kSDURLCacheInfoAccessesKey]; - if ([accesses objectForKey:cacheKey]) // OPTI: Check for cache-hit in a in-memory dictionary before hitting the file system + if ([accesses objectForKey:cacheKey]) // OPTI: Check for cache-hit in a in-memory dictionnary before to hit the FS { - NSCachedURLResponse *diskResponse = [NSKeyedUnarchiver unarchiveObjectWithFile:[diskCachePath stringByAppendingPathComponent:cacheKey]]; + + // load wrapper + SDCachedURLResponse *diskResponseWrapper = [NSKeyedUnarchiver unarchiveObjectWithFile: + [diskCachePath stringByAppendingPathComponent:cacheKey]]; + + NSCachedURLResponse *diskResponse = diskResponseWrapper.cached_response; + if (diskResponse) { // OPTI: Log the entry last access time for LRU cache eviction algorithm but don't save the dictionary @@ -527,7 +548,8 @@ - (NSCachedURLResponse *)cachedResponseForRequest:(NSURLRequest *)request // OPTI: Store the response to memory cache for potential future requests [super storeCachedResponse:diskResponse forRequest:request]; - + + // SRK: Work around an interesting retainCount bug in CFNetwork on iOS << 3.2. if (kCFCoreFoundationVersionNumber < kCFCoreFoundationVersionNumber_iPhoneOS_3_2) { @@ -536,12 +558,13 @@ - (NSCachedURLResponse *)cachedResponseForRequest:(NSURLRequest *)request if (diskResponse) { + PH_LOG(@"Loading URL from local cache: %@", request.URL); return diskResponse; } } } } - + return nil; } @@ -556,21 +579,18 @@ - (NSUInteger)currentDiskUsage - (void)removeCachedResponseForRequest:(NSURLRequest *)request { - request = [SDURLCache canonicalRequestForRequest:request]; + request = [SDURLCachePH canonicalRequestForRequest:request]; [super removeCachedResponseForRequest:request]; - [self removeCachedResponseForCachedKeys:[NSArray arrayWithObject:[SDURLCache cacheKeyForURL:request.URL]]]; + [self removeCachedResponseForCachedKeys:[NSArray arrayWithObject:[SDURLCachePH cacheKeyForURL:request.URL]]]; [self saveCacheInfo]; } - (void)removeAllCachedResponses { [super removeAllCachedResponses]; - - NSFileManager *fileManager = [[NSFileManager alloc] init]; + NSFileManager *fileManager = [[[NSFileManager alloc] init] autorelease]; [fileManager removeItemAtPath:diskCachePath error:NULL]; - [fileManager release]; - @synchronized(self) { [diskCacheInfo release], diskCacheInfo = nil; @@ -580,21 +600,15 @@ - (void)removeAllCachedResponses - (BOOL)isCached:(NSURL *)url { NSURLRequest *request = [NSURLRequest requestWithURL:url]; - request = [SDURLCache canonicalRequestForRequest:request]; + request = [SDURLCachePH canonicalRequestForRequest:request]; if ([super cachedResponseForRequest:request]) { return YES; } - - NSString *cacheKey = [SDURLCache cacheKeyForURL:url]; + NSString *cacheKey = [SDURLCachePH cacheKeyForURL:url]; NSString *cacheFile = [diskCachePath stringByAppendingPathComponent:cacheKey]; - NSFileManager *manager = [[NSFileManager alloc] init]; - - BOOL exists = [manager fileExistsAtPath:cacheFile]; - [manager release]; - - if (exists) + if ([[[[NSFileManager alloc] init] autorelease] fileExistsAtPath:cacheFile]) { return YES; } From eaab124779eb0948a3dbbda22b49c6c1365b232e Mon Sep 17 00:00:00 2001 From: Sam Stewart Date: Wed, 28 Mar 2012 18:04:05 -0700 Subject: [PATCH 2/5] [fix] remove proprietary code --- SDURLCache.h | 2 +- SDURLCache.m | 30 ++++++++++++++---------------- 2 files changed, 15 insertions(+), 17 deletions(-) diff --git a/SDURLCache.h b/SDURLCache.h index 00c8325..d005eb5 100644 --- a/SDURLCache.h +++ b/SDURLCache.h @@ -15,7 +15,7 @@ @property (nonatomic, retain) NSCachedURLResponse *cached_response; @end -@interface SDURLCachePH : NSURLCache +@interface SDURLCache : NSURLCache { @private NSString *diskCachePath; diff --git a/SDURLCache.m b/SDURLCache.m index d4c2063..ea98c0d 100644 --- a/SDURLCache.m +++ b/SDURLCache.m @@ -7,7 +7,6 @@ // #import "SDURLCache.h" -#import "PHConstants.h" #import static NSTimeInterval const kSDURLCacheInfoDefaultMinCacheInterval = 5 * 60; // 5 minute @@ -79,7 +78,7 @@ - (void)dealloc { @end -@interface SDURLCachePH () +@interface SDURLCache () @property (nonatomic, retain) NSString *diskCachePath; @property (nonatomic, readonly) NSMutableDictionary *diskCacheInfo; @property (nonatomic, retain) NSOperationQueue *ioQueue; @@ -87,7 +86,7 @@ @interface SDURLCachePH () - (void)periodicMaintenance; @end -@implementation SDURLCachePH +@implementation SDURLCache @synthesize diskCachePath, minCacheInterval, ioQueue, periodicMaintenanceOperation, ignoreMemoryOnlyStoragePolicy; @dynamic diskCacheInfo; @@ -171,7 +170,7 @@ + (NSDate *)expirationDateFromHeaders:(NSDictionary *)headers withStatusCode:(NS NSDate *now; if (date) { - now = [SDURLCachePH dateFromHttpDateString:date]; + now = [SDURLCache dateFromHttpDateString:date]; } else { @@ -215,7 +214,7 @@ + (NSDate *)expirationDateFromHeaders:(NSDictionary *)headers withStatusCode:(NS if (expires) { NSTimeInterval expirationInterval = 0; - NSDate *expirationDate = [SDURLCachePH dateFromHttpDateString:expires]; + NSDate *expirationDate = [SDURLCache dateFromHttpDateString:expires]; if (expirationDate) { expirationInterval = [expirationDate timeIntervalSinceDate:now]; @@ -243,7 +242,7 @@ + (NSDate *)expirationDateFromHeaders:(NSDictionary *)headers withStatusCode:(NS if (lastModified) { NSTimeInterval age = 0; - NSDate *lastModifiedDate = [SDURLCachePH dateFromHttpDateString:lastModified]; + NSDate *lastModifiedDate = [SDURLCache dateFromHttpDateString:lastModified]; if (lastModifiedDate) { // Define the age of the document by comparing the Date header with the Last-Modified header @@ -395,7 +394,7 @@ - (void)storeToDisk:(NSDictionary *)context SDCachedURLResponse *cachedResponse = [SDCachedURLResponse cachedURLResponseWithNSCachedURLResponse:[context objectForKey:@"cachedResponse"]]; - NSString *cacheKey = [SDURLCachePH cacheKeyForURL:request.URL]; + NSString *cacheKey = [SDURLCache cacheKeyForURL:request.URL]; NSString *cacheFilePath = [diskCachePath stringByAppendingPathComponent:cacheKey]; [self createDiskCachePath]; @@ -476,7 +475,7 @@ - (id)initWithMemoryCapacity:(NSUInteger)memoryCapacity diskCapacity:(NSUInteger - (void)storeCachedResponse:(NSCachedURLResponse *)cachedResponse forRequest:(NSURLRequest *)request { - request = [SDURLCachePH canonicalRequestForRequest:request]; + request = [SDURLCache canonicalRequestForRequest:request]; if (request.cachePolicy == NSURLRequestReloadIgnoringLocalCacheData || request.cachePolicy == NSURLRequestReloadIgnoringLocalAndRemoteCacheData @@ -499,7 +498,7 @@ - (void)storeCachedResponse:(NSCachedURLResponse *)cachedResponse forRequest:(NS // RFC 2616 section 13.3.4 says clients MUST use Etag in any cache-conditional request if provided by server if (![headers objectForKey:@"Etag"]) { - NSDate *expirationDate = [SDURLCachePH expirationDateFromHeaders:headers + NSDate *expirationDate = [SDURLCache expirationDateFromHeaders:headers withStatusCode:((NSHTTPURLResponse *)cachedResponse.response).statusCode]; if (!expirationDate || [expirationDate timeIntervalSinceNow] - minCacheInterval <= 0) { @@ -517,13 +516,13 @@ - (void)storeCachedResponse:(NSCachedURLResponse *)cachedResponse forRequest:(NS - (NSCachedURLResponse *)cachedResponseForRequest:(NSURLRequest *)request { - request = [SDURLCachePH canonicalRequestForRequest:request]; + request = [SDURLCache canonicalRequestForRequest:request]; NSCachedURLResponse *memoryResponse = [super cachedResponseForRequest:request]; if (memoryResponse) return memoryResponse; - NSString *cacheKey = [SDURLCachePH cacheKeyForURL:request.URL]; + NSString *cacheKey = [SDURLCache cacheKeyForURL:request.URL]; // NOTE: We don't handle expiration here as even staled cache data is necessary for NSURLConnection to handle cache revalidation. // Staled cache data is also needed for cachePolicies which force the use of the cache. @@ -558,7 +557,6 @@ - (NSCachedURLResponse *)cachedResponseForRequest:(NSURLRequest *)request if (diskResponse) { - PH_LOG(@"Loading URL from local cache: %@", request.URL); return diskResponse; } } @@ -579,10 +577,10 @@ - (NSUInteger)currentDiskUsage - (void)removeCachedResponseForRequest:(NSURLRequest *)request { - request = [SDURLCachePH canonicalRequestForRequest:request]; + request = [SDURLCache canonicalRequestForRequest:request]; [super removeCachedResponseForRequest:request]; - [self removeCachedResponseForCachedKeys:[NSArray arrayWithObject:[SDURLCachePH cacheKeyForURL:request.URL]]]; + [self removeCachedResponseForCachedKeys:[NSArray arrayWithObject:[SDURLCache cacheKeyForURL:request.URL]]]; [self saveCacheInfo]; } @@ -600,13 +598,13 @@ - (void)removeAllCachedResponses - (BOOL)isCached:(NSURL *)url { NSURLRequest *request = [NSURLRequest requestWithURL:url]; - request = [SDURLCachePH canonicalRequestForRequest:request]; + request = [SDURLCache canonicalRequestForRequest:request]; if ([super cachedResponseForRequest:request]) { return YES; } - NSString *cacheKey = [SDURLCachePH cacheKeyForURL:url]; + NSString *cacheKey = [SDURLCache cacheKeyForURL:url]; NSString *cacheFile = [diskCachePath stringByAppendingPathComponent:cacheKey]; if ([[[[NSFileManager alloc] init] autorelease] fileExistsAtPath:cacheFile]) { From 6349968eac14934e9eae98d01d21ee058cca1a6f Mon Sep 17 00:00:00 2001 From: Sam Stewart Date: Wed, 28 Mar 2012 18:18:50 -0700 Subject: [PATCH 3/5] [fix] extraneous log statement --- SDURLCache.m | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/SDURLCache.m b/SDURLCache.m index ea98c0d..9027cfb 100644 --- a/SDURLCache.m +++ b/SDURLCache.m @@ -449,9 +449,7 @@ - (void)periodicMaintenance + (NSString *)defaultCachePath { NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES); - NSString *path = [[paths objectAtIndex:0] stringByAppendingPathComponent:@"SDURLCache"]; - NSLog(@"cache path: %@", path); - return path; + return [[paths objectAtIndex:0] stringByAppendingPathComponent:@"SDURLCache"]; } #pragma mark NSURLCache From 7d1068ca5db2ec3b1709b3de82ff1783cc0c8004 Mon Sep 17 00:00:00 2001 From: Sam Stewart Date: Thu, 29 Mar 2012 10:28:04 -0700 Subject: [PATCH 4/5] [slice] cache control search into separate commit --- SDURLCache.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SDURLCache.m b/SDURLCache.m index 9027cfb..456ee47 100644 --- a/SDURLCache.m +++ b/SDURLCache.m @@ -179,7 +179,7 @@ + (NSDate *)expirationDateFromHeaders:(NSDictionary *)headers withStatusCode:(NS } // Look at info from the Cache-Control: max-age=n header - NSString *cacheControl = [headers objectForKey:@"Cache-Control"]; + NSString *cacheControl = [[headers objectForKey:@"Cache-Control"] lowercaseString]; if (cacheControl) { NSRange foundRange = [cacheControl rangeOfString:@"no-store"]; From a73fe6724b6410b0ebda75e38cddde110ad2ab59 Mon Sep 17 00:00:00 2001 From: Sam Stewart Date: Thu, 29 Mar 2012 16:50:16 -0700 Subject: [PATCH 5/5] [fix] issue with legacy SDURLCache archives --- SDURLCache.m | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/SDURLCache.m b/SDURLCache.m index 456ee47..db525cc 100644 --- a/SDURLCache.m +++ b/SDURLCache.m @@ -14,6 +14,16 @@ static NSString *const kSDURLCacheInfoDiskUsageKey = @"diskUsage"; static NSString *const kSDURLCacheInfoAccessesKey = @"accesses"; static NSString *const kSDURLCacheInfoSizesKey = @"sizes"; + +// The removal of the NSCachedURLResponse category means that NSKeyedArchiver +// will throw an EXC_BAD_ACCESS when attempting to load NSCachedURLResponse +// data. +// This means that this change requires a cache refresh, and a new cache key +// namespace that will prevent this from happening. +// Old cache keys will eventually be evicted from the system as new keys are +// populated. +static NSString *const kSDURLCacheVersion = @"V2"; + static float const kSDURLCacheLastModFraction = 0.1f; // 10% since Last-Modified suggested by RFC2616 section 13.2.4 static float const kSDURLCacheDefault = 3600; // Default cache expiration delay if none defined (1 hour) @@ -110,8 +120,8 @@ + (NSString *)cacheKeyForURL:(NSURL *)url const char *str = [url.absoluteString UTF8String]; unsigned char r[CC_MD5_DIGEST_LENGTH]; CC_MD5(str, strlen(str), r); - return [NSString stringWithFormat:@"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", - r[0], r[1], r[2], r[3], r[4], r[5], r[6], r[7], r[8], r[9], r[10], r[11], r[12], r[13], r[14], r[15]]; + return [NSString stringWithFormat:@"%@_%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", + kSDURLCacheVersion, r[0], r[1], r[2], r[3], r[4], r[5], r[6], r[7], r[8], r[9], r[10], r[11], r[12], r[13], r[14], r[15]]; } /*