If you haven't dabbled in Protocol Buffers for Objective-C, we highly recommend taking a look at http://code.google.com/p/metasyntactic/wiki/ProtocolBuffers for starters.
By doing a bulk photos fetch (for every friend), and persisting to the local iOS documents cache directory, we can save an average of 5-8 calls per user per hour of usage. The following code demonstrates how to convert a Protocol Buffer object to an NSData stream for writing. We simply have these methods within a singleton Objective-C class:
#define USER_CACHE_ALL_PHOTOS_PATH @"All_Photos.pb"
- (NSString*) cacheDir {
NSArray *paths =
NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
if ([paths count] > 0) {
return [paths objectAtIndex:0];
}
return nil;
}
- (void)writePhotos {
if (photos != nil) {
NSOutputStream* rawOutput = [[NSOutputStream outputStreamToMemory] retain];
PBCodedOutputStream* output =
[[PBCodedOutputStream streamWithOutputStream:rawOutput] retain];
[photos writeToCodedOutputStream:output];
[output flush];
NSData* actualData = [rawOutput propertyForKey:NSStreamDataWrittenToMemoryStreamKey];
NSString* pathToStorePhotos =
[[NSString [self cacheDir], USER_CACHE_ALL_PHOTOS_PATH] retain];
[pathToStorePhotos release];
[output release];
[rawOutput release];
}
}
- (Photos*)readPhotos {
Photos* photosOnDisk = nil;
NSString* pathToStorePhotos = [[NSString
stringWithFormat:@"%@/%@",
[self cacheDir], USER_CACHE_ALL_PHOTOS_PATH] retain];
NSData *photoData = [[NSData dataWithContentsOfFile:pathToStorePhotos] retain];
if (photoData) {
photosOnDisk = [[[[Photos builder] mergeFromData:photoData] build] retain];
}
[photoData release];
[pathToStorePhotos release];
return [photosOnDisk autorelease];
}
Hope you enjoy this little snippet, it can be reused for all your objects that need long-term disk cache.