as the iPhone SDK comes with a rather dysfunctional NSURLCache — Apple suggests to implement it from scratch yourself in the code examples about caching — I went for just this.
Until I came across the [NSKeyedUnarchiver unarchiveObjectWithData:...] not restoring userInfo, storagePolicy and data of NSCachedURLResponse.
Couldn’t believe it and spent almost the whole day verifying that the error is not within my code but really the unarchiver treats those fields transient.
See yourself:
-(void)testiPhoneSDK312NSKeyedArchiver { // prepare a NSCachedURLResponse NSCachedURLResponse *src = nil; { NSURL *i_url = [NSURL URLWithString:@"http://www.url.example/path/file.html"]; NSString *i_mime = @"text/html"; NSInteger expectedContentLength = 112; NSString *i_encoding = @"iso-8859-2"; NSURLResponse *i_response = [[NSURLResponse alloc] initWithURL:i_url MIMEType:i_mime expectedContentLength:expectedContentLength textEncodingName:i_encoding]; NSData *i_data = [@"Hello, world!" dataUsingEncoding:NSISOLatin2StringEncoding]; NSURLCacheStoragePolicy i_storage = NSURLCacheStorageAllowed; NSDictionary *i_userInfo = [NSDictionary dictionaryWithObject: [NSDate dateWithTimeIntervalSince1970:13] forKey:@"era"]; NSCachedURLResponse *src = [[NSCachedURLResponse alloc] initWithResponse:i_response data:i_data userInfo:i_userInfo storagePolicy:i_storage]; // ensure it's all in place: STAssertEqualObjects(i_url, src.response.URL, @""); STAssertEqualObjects(i_mime, src.response.MIMEType, @""); STAssertEquals((int)expectedContentLength, (int)src.response.expectedContentLength, @""); STAssertEqualObjects(@"file.html", src.response.suggestedFilename, @""); STAssertEqualObjects(i_encoding, src.response.textEncodingName, @""); STAssertEqualObjects(i_data, src.data, @""); STAssertEqualObjects(i_userInfo, src.userInfo, @""); STAssertEquals( 0u, src.storagePolicy, @""); } // archive + unarchive: NSCachedURLResponse *dst = [NSKeyedUnarchiver unarchiveObjectWithData: [NSKeyedArchiver archivedDataWithRootObject:src]]; // check whether src == dst STAssertEqualObjects(src.response.URL, dst.response.URL, @""); STAssertEqualObjects(src.response.MIMEType, dst.response.MIMEType, @""); STAssertEquals(src.response.expectedContentLength, dst.response.expectedContentLength, @""); STAssertEqualObjects(src.response.suggestedFilename, dst.response.suggestedFilename, @""); STAssertEqualObjects(src.response.textEncodingName, dst.response.textEncodingName, @""); // !!!!!!!!!! // sad information loss after unarchiving: STAssertNil( dst.data, @"" ); STAssertNil( dst.userInfo, @"" ); STAssertEquals( 2u , dst.storagePolicy, @"" ); }
When my NSURLCache replacement is ready I think about publishing it a github — interested anyone?