cs193p – Assignment #5 Task #11

Please note, this blog entry is from a previous course. You might want to check out the current one.

The list of recent photos should be saved in NSUserDefaults (i.e. it should be persistent across launchings of your application). Conveniently, the arrays you get back from the FlickrFetcher URLs are all property lists (once converted from JSON).

Create a new public instance method for the Flickr helper class to return the ID of the photo (again, it is not really complicated to get the ID but let’s keep everything Flickr related encapsulated inside the helper class):

+ (NSString *)IDforPhoto:(NSDictionary *)photo
    return [photo valueForKeyPath:FLICKR_PHOTO_ID];

Follow the same approach to save and load photos to/from the user defaults. Create two public instance methods. The first one just returns all stored photos:

#define RECENT_PHOTOS_KEY @"Recent_Photos_Key"
+ (NSArray *)allPhotos
    return [[NSUserDefaults standardUserDefaults] objectForKey:RECENT_PHOTOS_KEY];

Its second method checks if the photo has already been stored before, which is done by checking the photo ID derived from the helper method above. If it was already there, remove the photo from the current position. Add the photo at the first position. To make sure there are only a certain amount of photos, keep deleting the last one till there are no surplus photos:

+ (void)addPhoto:(NSDictionary *)photo
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    NSMutableArray *photos = [[defaults objectForKey:RECENT_PHOTOS_KEY] mutableCopy];    
    if (!photos) photos = [NSMutableArray array];
    NSUInteger key = [photos indexOfObjectPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) {
        return [[FlickrHelper IDforPhoto:photo] isEqualToString:[FlickrHelper IDforPhoto:obj]];
    if (key != NSNotFound) [photos removeObjectAtIndex:key];
    [photos insertObject:photo atIndex:0];
    while ([photos count] > RECENT_PHOTOS_MAX_NUMBER) {
        [photos removeLastObject];
    [defaults setObject:photos forKey:RECENT_PHOTOS_KEY];
    [defaults synchronize];

Add the photo when preparing to segue to the image view controller:

- (void)prepareImageVC:(ImageVC *)vc
              forPhoto:(NSDictionary *)photo
    [RecentPhotos addPhoto:photo];

Create a new class derived from the generic photo table view controller and set the photos for the table when the view will appear:

- (void)viewWillAppear:(BOOL)animated
    [super viewWillAppear:animated];
    self.photos = [RecentPhotos allPhotos];

Finally link this new class to the respective table view controller in both storyboards, and make sure the reuse identifiers for its cells are set, too.

The complete code is available on github.


Leave a Reply

Your email address will not be published.