cs193p – Assignment #4 Task #8

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

The recents tab must show a list of the most recently view photos in order, with the most recent at the top and no duplicates in the list. The list of recents must also persist across application termination and relaunch. When a recent photo in the list is chosen, it should navigate to a view of the photo in the same way as other table views in the application do. Limit the size of the list to a reasonable number.

Create a new class derived from NSObject to handle saving and storing the recent photos. Create a public interface to get all photos and to set a new photo:

+ (NSArray *)allPhotos;
+ (void) addPhoto:(NSDictionary *)photo;

To get all photos just readout the object in NSUserDefaults for the proper key:

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

When adding a new photo, first check if it is already there. If so remove it, because we want to sort them by the time of viewing, and thus the current photo will be placed at the first position:

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

The photo will be stored when it going to be viewed – when the segue for the image view is prepared:

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
                if ([segue.destinationViewController respondsToSelector:@selector(setImageURL:)]) {
                    [RecentFlickrPhotos addPhoto:self.photos[indexPath.row]];

For the table view controller for the recent items, create a subclass of the Flickr-photo-table view controller, which just reads the photos whenever the view appears on screen:

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

In storyboard copy the Flickr-photo-table view controller and use it to replace the view controller previously used as place holder for the recents tab. Change its class to the newly created one from above. Create a push segue from its cell to the image view and set its identifier to “Show Image”:

cs193p - assignment #4 task #8
cs193p – assignment #4 task #8

… and an addendum for task #4 – when using the code from Shutterbug, the subtitle uses the owner of the photo, where task #4 requires its description:

- (NSString *)subtitleForRow:(NSUInteger)row
    return [[self.photos[row] valueForKeyPath:FLICKR_PHOTO_DESCRIPTION] description];

The complete code is available on github.


Leave a Reply

Your email address will not be published.