Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trial

David Klein
Courses Plus Student 1,456 PointsImplement hashtag search on photo bomber app
Hell guys, i tried to implement search hashtag by using UITextField i i added UITextField to photoviewcontroller.m file. It's pretty weird when i NSLog the self.hashtag and the result is null. how can i fix this? Below is my code. How can i make when user put a string in textfield text and pressed RETURN and this action will change the picture of collection view?
self.textField = [[UITextField alloc] initWithFrame:CGRectMake(0, 50, 80, 40)];
self.textField.backgroundColor = [UIColor greenColor];
[self.textField setBorderStyle:UITextBorderStyleRoundedRect];
self.hashtag = self.textField.text;
[self.view addSubview:self.textField];
NSLog(@"search : %@", self.hashtag);
I put the self.hashtag value here but it didn't works.
NSString *urlString = [[NSString alloc] initWithFormat:@"https://api.instagram.com/v1/tags/%@/media/recent?access_token=%@", self.hashtag,self.accessToken];
PS : self.hashtag gave me return value when i set to self.textField.text = @"london";
3 Answers

Stone Preston
42,016 PointsI assume you have this code in viewDidLoad? if so thats why its not working. you init your textfield, which the user hasnt had a chance to type anything into yet, and then set your hashtag property using the value of that empty textfield, which is why its null.
If you want this to work correctly, you are going to need to add a button or something similar and when the user clicks that button after typing something into the text field run this code:
self.hashtag = self.textField.text;
NSString *urlString = [[NSString alloc] initWithFormat:@"https://api.instagram.com/v1/tags/%@/media/recent?access_token=%@", self.hashtag,self.accessToken];
//run the rest of the instagram api download task stuff here as well

David Klein
Courses Plus Student 1,456 PointsI figured out my problem by adding UISearchBar to the viewdidload of photoviewcontroller and set the search text to the searchBarSearchButtonClicked delegate method. hope this answer can help others that have similar problem with me.
//
// THPhotosViewController.m
// Photo Bombers
//
// Created by Sam Soffes on 1/28/14.
// Copyright (c) 2014 Treehouse. All rights reserved.
//
#import "THPhotosViewController.h"
#import "THPhotoCell.h"
#import "THDetailViewController.h"
#import "THPresentDetailTransition.h"
#import "THDismissDetailTransition.h"
#import <SimpleAuth/SimpleAuth.h>
@interface THPhotosViewController () <UIViewControllerTransitioningDelegate>
@property (nonatomic) NSString *accessToken;
@property (nonatomic) NSArray *photos;
@property (nonatomic) BOOL loading;
@property (nonatomic) NSString *hashtag;
@property (nonatomic) UITextField *textField;
@property (nonatomic) UISearchBar *searchBar;
@end
@implementation THPhotosViewController
- (void)setLoading:(BOOL)loading {
_loading = loading;
self.navigationItem.rightBarButtonItem.enabled = !_loading;
}
- (instancetype)init {
UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
layout.itemSize = CGSizeMake(106.0, 106.0);
layout.minimumInteritemSpacing = 1.0;
layout.minimumLineSpacing = 1.0;
return (self = [super initWithCollectionViewLayout:layout]);
}
- (void)viewDidLoad {
[super viewDidLoad];
//set default hashtag to whatever you want
self.hashtag = @"breakfast";
self.title = @"XYPIC";
// TODO: Add a refresh right bar button item
UIBarButtonItem *refreshButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemRefresh target:self action:@selector(refresh)];
self.navigationItem.rightBarButtonItem = refreshButton;
// UIBarButtonItem *searchButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemSearch target:self action:@selector(searchHashtag)];
// self.navigationItem.leftBarButtonItem = searchButton;
//make search bar and set search delegate
self.searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 0, 200, 40)];
self.searchBar.keyboardType = UIKeyboardTypeEmailAddress;
self.searchBar.barStyle = UIBarStyleBlack;
self.searchBar.placeholder = @"Hashtag";
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:_searchBar];
self.searchBar.delegate = self;
[self.collectionView registerClass:[THPhotoCell class] forCellWithReuseIdentifier:@"photo"];
self.collectionView.backgroundColor = [UIColor whiteColor];
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
self.accessToken = [userDefaults objectForKey:@"accessToken"];
if (self.accessToken == nil) {
[SimpleAuth authorize:@"instagram" options:@{@"scope": @[@"likes"]} completion:^(NSDictionary *responseObject, NSError *error) {
self.accessToken = responseObject[@"credentials"][@"token"];
[userDefaults setObject:self.accessToken forKey:@"accessToken"];
[userDefaults synchronize];
[self refresh];
}];
} else {
[self refresh];
}
}
- (void)refresh {
if (self.loading) {
return;
}
self.loading = YES;
NSURLSession *session = [NSURLSession sharedSession];
// You can change the hashtag here to make your very own photo browser app!
NSString *urlString = [[NSString alloc] initWithFormat:@"https://api.instagram.com/v1/tags/%@/media/recent?access_token=%@", self.hashtag, self.accessToken];
NSURL *url = [[NSURL alloc] initWithString:urlString];
NSURLRequest *request = [[NSURLRequest alloc] initWithURL:url];
NSURLSessionDownloadTask *task = [session downloadTaskWithRequest:request completionHandler:^(NSURL *location, NSURLResponse *response, NSError *error) {
NSData *data = [[NSData alloc] initWithContentsOfURL:location];
NSDictionary *responseDictionary = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
self.photos = [responseDictionary valueForKeyPath:@"data"];
dispatch_async(dispatch_get_main_queue(), ^{
[self.collectionView reloadData];
self.loading = NO;
});
}];
[task resume];
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
return [self.photos count];
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
THPhotoCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"photo" forIndexPath:indexPath];
cell.backgroundColor = [UIColor lightGrayColor];
cell.photo = self.photos[indexPath.row];
return cell;
}
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
NSDictionary *photo = self.photos[indexPath.row];
THDetailViewController *viewController = [[THDetailViewController alloc] init];
viewController.modalPresentationStyle = UIModalPresentationCustom;
viewController.transitioningDelegate = self;
viewController.photo = photo;
[self presentViewController:viewController animated:YES completion:nil];
}
- (id<UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source {
return [[THPresentDetailTransition alloc] init];
}
- (id<UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed {
return [[THDismissDetailTransition alloc] init];
}
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar {
[searchBar resignFirstResponder];
self.hashtag = searchBar.text;
NSLog(@"hashtag : %@", self.hashtag);
[self refresh];
}
@end

Rashad Abdul-Salaam
Courses Plus Student 13,392 PointsThanks for posting this, it works like a charm! It's exactly something I was contemplating setting up myself.

David Klein
Courses Plus Student 1,456 PointsYes, I'm doing it in viewDidLoad. thank you for noticing that. Btw stone, do i need to add - (IBAction)UIButton:(id)sender; to make things works when user clicks that button?

Stone Preston
42,016 PointsNo, you can set the method that runs using a selector. See this post about adding a button in code