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?