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:
1-(void)testiPhoneSDK312NSKeyedArchiver
2{
3// prepare a NSCachedURLResponse
4 NSCachedURLResponse *src = nil;
5 {
6 NSURL *i_url = [NSURL URLWithString:@"http://www.url.example/path/file.html"];
7 NSString *i_mime = @"text/html";
8 NSInteger expectedContentLength = 112;
9 NSString *i_encoding = @"iso-8859-2";
10
11 NSURLResponse *i_response = [[NSURLResponse alloc] initWithURL:i_url
12 MIMEType:i_mime
13 expectedContentLength:expectedContentLength
14 textEncodingName:i_encoding];
15 NSData *i_data = [@"Hello, world!" dataUsingEncoding:NSISOLatin2StringEncoding];
16 NSURLCacheStoragePolicy i_storage = NSURLCacheStorageAllowed;
17 NSDictionary *i_userInfo = [NSDictionary dictionaryWithObject:
18 [NSDate dateWithTimeIntervalSince1970:13] forKey:@"era"];
19
20 NSCachedURLResponse *src = [[NSCachedURLResponse alloc] initWithResponse:i_response
21 data:i_data
22 userInfo:i_userInfo
23 storagePolicy:i_storage];
24
25// ensure it's all in place:
26 STAssertEqualObjects(i_url, src.response.URL, @"");
27 STAssertEqualObjects(i_mime, src.response.MIMEType, @"");
28 STAssertEquals((int)expectedContentLength, (int)src.response.expectedContentLength, @"");
29 STAssertEqualObjects(@"file.html", src.response.suggestedFilename, @"");
30 STAssertEqualObjects(i_encoding, src.response.textEncodingName, @"");
31
32 STAssertEqualObjects(i_data, src.data, @"");
33 STAssertEqualObjects(i_userInfo, src.userInfo, @"");
34 STAssertEquals( 0u, src.storagePolicy, @"");
35 }
36
37// archive + unarchive:
38 NSCachedURLResponse *dst = [NSKeyedUnarchiver unarchiveObjectWithData:
39 [NSKeyedArchiver archivedDataWithRootObject:src]];
40
41// check whether src == dst
42 STAssertEqualObjects(src.response.URL, dst.response.URL, @"");
43 STAssertEqualObjects(src.response.MIMEType, dst.response.MIMEType, @"");
44 STAssertEquals(src.response.expectedContentLength, dst.response.expectedContentLength, @"");
45 STAssertEqualObjects(src.response.suggestedFilename, dst.response.suggestedFilename, @"");
46 STAssertEqualObjects(src.response.textEncodingName, dst.response.textEncodingName, @"");
47
48// !!!!!!!!!!
49// sad information loss after unarchiving:
50 STAssertNil( dst.data, @"" );
51 STAssertNil( dst.userInfo, @"" );
52 STAssertEquals( 2u , dst.storagePolicy, @"" );
53}
When my NSURLCache replacement is ready I think about publishing it a github — interested anyone?