cs193p – Assignment #5 Task #4

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

When the user chooses a place in a table view, you must query Flickr again to get an array of 50 photos from that place and display them in a list. The URL provided by FlickrFetcher’s URLforPhotosInPlace:maxResults: method will get this from Flickr.

Create a new class derived from the table-view-controller class to be used to show a list of photos with a public property to hold an array of photos:

@property (nonatomic, strong) NSArray *photos; // of Flickr photos NSDicitionary

Everytime the photos are set, reload the table:

- (void)setPhotos:(NSArray *)photos
    _photos = photos;
    [self.tableView reloadData];

The number of rows equals the number of photos:

- (NSInteger)tableView:(UITableView *)tableView
    return [self.photos count];

The cells are populated with data from the photos for now (we will change that in the following task):

- (UITableViewCell *)tableView:(UITableView *)tableView
         cellForRowAtIndexPath:(NSIndexPath *)indexPath
    static NSString *CellIdentifier = @"Photo Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier
    NSDictionary *photo = self.photos[indexPath.row];
    cell.textLabel.text = [photo valueForKeyPath:FLICKR_PHOTO_TITLE];
    cell.detailTextLabel.text = [photo valueForKeyPath:FLICKR_PHOTO_DESCRIPTION];    
    return cell;

From this new class derive a new class with another public property to store the current place:

@property (nonatomic, strong) NSDictionary *place;

When the view did load or then the refresh action is triggered, download the available photos for the current place using another helper method:

- (IBAction)fetchPhotos
    [self.refreshControl beginRefreshing];
    [self.tableView setContentOffset:CGPointMake(0, -self.refreshControl.frame.size.height) animated:YES];    
    [FlickrHelper loadPhotosInPlace:self.place
                       onCompletion:^(NSArray *photos, NSError *error) {
                           if (!error) {
                               self.photos = photos;
                               [self.refreshControl endRefreshing];
                           } else {
                               NSLog(@"Error loading Photos of %@: %@", self.place, error);

- (void)viewDidLoad
    [super viewDidLoad];
    [self fetchPhotos];

The helper method is similar to the one used to load places:

+ (void)loadPhotosInPlace:(NSDictionary *)place
             onCompletion:(void (^)(NSArray *photos, NSError *error))completionHandler
    NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration ephemeralSessionConfiguration]];
    NSURLSessionDownloadTask *task = [session downloadTaskWithURL:[FlickrHelper URLforPhotosInPlace:[place valueForKeyPath:FLICKR_PLACE_ID] maxResults:results]
                                                completionHandler:^(NSURL *location, NSURLResponse *response, NSError *error) {
                                                    NSArray *photos;
                                                    if (!error) {
                                                        photos = [[NSJSONSerialization JSONObjectWithData:[NSData dataWithContentsOfURL:location]
                                                                                                    error:&error] valueForKeyPath:FLICKR_RESULTS_PHOTOS];
                                                    dispatch_async(dispatch_get_main_queue(), ^{
                                                        completionHandler(photos, error);
    [task resume];

The current place and the title of the view are set when selecting a cell in the places table:

- (void)preparePhotosTVC:(PlacePhotosTVC *)tvc
                forPlace:(NSDictionary *)place
    tvc.place = place;
    tvc.title = [FlickrHelper titleOfPlace:place];

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
    NSIndexPath *indexPath = [self.tableView indexPathForCell:sender];
    if ([segue.identifier isEqualToString:@"Show Place"] && indexPath) {
        [self preparePhotosTVC:segue.destinationViewController

Finally add a new table view controllor in story board and link it to the just created class above. Don’t forget to set the cell identifier. Create a push segue from the cell of the first table view controller to this new controller. Don’t for set its identifier, too:

cs193p – assignment #5 task #4 - place photos table
cs193p – assignment #5 task #4 – place photos table

The complete code is available on github.


3 thoughts on “cs193p – Assignment #5 Task #4”

  1. Trying to take course on my own and can’t get URL for PhotosInPlace to work. Very much a newbie.

    Flickr returns fail message of: “Method “flickr.photos.searcapih” not found”.

    Is query still working?

Leave a Reply

Your email address will not be published.