I am attempting to cache a web request. Basically I have an app that uses a facebook user's friend list but I don't want to grab it every single time they log in. Maybe refresh once per month. Caching the friend list in a plist in the documents directory seems to make sense for this functionality. I do this as follows:
- (void)writeToDisk {
NSLog(@"writing cache to disk, where cache = %@", cache);
BOOL res = [cache writeToFile:[FriendCache persistentPath] atomically:YES];
NSLog(@"reading cache from disk immediately after writing, res = %d", res);
NSMutableArray *temp = [[NSMutableArray alloc] initWithContentsOfFile:[FriendCache persistentPath]];
NSLog(@"cache read in = %@", temp);
}
+ (NSString *)persistentPath {
NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) objectAtIndex:0];
return [documentsDirectory stringByAppendingPathComponent:@"FriendCache.plist"];
}
These are members of a FriendCache singleton I am using which basically wraps an NSMutableArray. I have verified that the peristentPath method is returning a valid path. As you you can see in the writeToDisk method, I verify there is data in the cache and then I print the result of the write and check if any data could be read back in. There is never data read back in, because the result of the file write is 0.
The output of the cache print is very long, but here is the abbreviated version:
2010-12-28 13:35:23.006 AppName[51607:207] writing cache to disk, where cache = (
{
birthday = "<null>";
name = "Some Name1";
pic = "http://profile.ak.fbcdn.net/hprofile-ak-snc4/hs1324.snc4/7846385648654.jpg";
"pic_big" = "http://profile.ak.fbcdn.net/hprofile-ak-snc4/hs442.snc4/784365789465746.jpg";
"pic_square" = "http://profile.ak.fbcdn.net/hprofile-ak-snc4/hs1324.snc4/7846357896547.jpg";
sex = female;
status = "<null>";
uid = 892374897165;
},
{
birthday = "<null>";
name = "Some Name2";
pic = "http://profile.ak.fbcdn.net/hprofile-ak-snc4/hs625.ash1/54636536547_s.jpg";
"pic_big" = "http://profile.ak.fbcdn.net/hprofile-ak-snc4/hs170.ash2/65465656365666_n.jpg";
"pic_square" = "http://profile.ak.fbcdn.net/hprofile-ak-snc4/hs625.ash1/654635656547_q.jpg";
sex = female;
status = "<null>";
uid = 7658436;
},
...
One thing I checked out is when using writeToFile, I must make sure the object I am writing has valid plist objects. I did check this and here is how I construct the cache object:
- (void)request:(FBRequest*)request didLoad:(id)result{
NSMutableArray *friendsInfo = [[[NSMutableArray alloc] init] autorelease];
for (NSDictionary *info in result) {
NSString *friend_id = [NSString stringWithString:[[info objectForKey:@"uid"] stringValue]];
NSString *friend_name = nil;
NSString *friend_sex = nil;
NSString *friend_relationship_status = nil;
NSString *friend_current_location = nil;
if ([info objectForKey:@"name"] != [NSNull null]) {
friend_name = [NSString stringWithString:[info objectForKey:@"name"]];
}
if ([info objectForKey:@"relationship_status"] != [NSNull null]) {
friend_relationship_status = [NSString stringWithString:[info objectForKey:@"relationship_status"]];
}
if ([info objectForKey:@"sex"] != [NSNull null]) {
friend_sex = [NSString stringWithString:[info objectForKey:@"sex"]];
}
if ([info objectForKey:@"current_location"] != [NSNull null]) {
friend_current_location = [[info objectForKey:@"current_location"] objectForKey:@"name"];
}
NSString *friend_pic_square = [info objectForKey:@"pic_square"];
NSString *friend_status = [info objectForKey:@"status"];
NSString *friend_pic = [info objectForKey:@"pic"];
NSString *friend_pic_big = [info objectForKey:@"pic_big"];
NSString *friend_birthday = [info objectForKey:@"birthday"];
NSDictionary *friend_info = [NSDictionary dictionaryWithObjectsAndKeys:
friend_id,@"uid",
friend_name, @"name",
friend_pic_square, @"pic_square",
friend_status, @"status",
friend_sex, @"sex",
friend_pic, @"pic",
friend_pic_big, @"pic_big",
friend_birthday, @"birthday",
friend_relationship_status, @"relationship_status",
friend_current_location, @"current_location",
nil];
// If the friend qualifies as a single of your gender, add to the friend cache
if ( [AppHelpers friendQualifies:friend_info] == YES) {
[[FriendCache sharedInstance] push:friend_info];
}
}
[[FriendCache sharedInstance] writeToDisk];
}
My push method just wraps the NSMutableArray push:
- (void)push:(id)o {
[cache addObject:o];
}
Can you think of any reason why the write would fail?
Thanks!