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 numberOfRowsInSection:(NSInteger)section { 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 forIndexPath:indexPath]; 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:
#define MAX_PHOTO_RESULTS 50 - (IBAction)fetchPhotos { [self.refreshControl beginRefreshing]; [self.tableView setContentOffset:CGPointMake(0, -self.refreshControl.frame.size.height) animated:YES]; [FlickrHelper loadPhotosInPlace:self.place maxResults:MAX_PHOTO_RESULTS 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 maxResults:(NSUInteger)results 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] options:0 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 forPlace:self.placesByCountry[self.countries[indexPath.section]][indexPath.row]]; } }
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:
The complete code is available on github.
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?
Never mind. Figured it out had inadvertently modified URL string in FlickrFetcher.m
… which, theoretically, you should not touch 😉