Skip to content

PopularMediaViewController

Alfie Hanssen edited this page Nov 20, 2013 · 8 revisions

###UIViewController

From the View Controller Programming Guide:

"View controllers are a vital link between an app’s data and its visual appearance. Whenever an iOS app displays a user interface, the displayed content is managed by a view controller or a group of view controllers coordinating with each other. Therefore, view controllers provide the skeletal framework on which you build your apps."

    // Override point for customization after application launch.
    
    UIViewController *vc = [[UIViewController alloc] init];
    vc.view.backgroundColor = [UIColor orangeColor];
    [self.window setRootViewController:vc];

    [self.window makeKeyAndVisible];
    return YES;

"You rarely instantiate UIViewController objects directly. Instead, you instantiate subclasses of the UIViewController class based on the specific task each subclass performs."

UIViewController Class Ref

UIViewController Subclass with .xib

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    
    // Override point for customization after application launch.
    
    PopularMediaViewController *vc = [[PopularMediaViewController alloc] initWithNibName:@"PopularMediaViewController" bundle:nil];
    UINavigationController *nc = [[UINavigationController alloc] initWithRootViewController:vc];
    [self.window setRootViewController:nc];
    
    self.window.backgroundColor = [UIColor whiteColor];
    [self.window makeKeyAndVisible];
    return YES;
}

UINavigationController Class Reference

###PopularMediaViewController

A blank UIViewController subclass:

@interface PopularMediaViewController ()

@end

@implementation PopularMediaViewController

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view.
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end

###Interface Builder and UITableView

Setup the UITableView IBOutlet:

Interface Building Library

@interface PopularMediaViewController ()
@property (nonatomic, strong) IBOutlet UITableView *tableView;
@end

UITableView Class Ref
UITableView Delegate Protocol Ref
UITableView Datasource Protocol Ref

Add the relevant UITableView delegate and datasource protocol methods:

@interface PopularMediaViewController () <UITableViewDataSource, UITableViewDelegate>
@property (nonatomic, strong) IBOutlet UITableView *tableView;
@end

@implementation PopularMediaViewController

#pragma mark - UITableView Delegate

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{

}

#pragma mark - UITableView Datasource

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{

}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{

}

@end

The App will crash unless we fill in the delegate and datasource methods with some placeholder data:

#pragma mark - UITableView Delegate

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSString *placeholder = @"Cell title";
    UIViewController *vc = [[UIViewController alloc] init];
    [self.navigationController pushViewController:vc animated:YES];
}

#pragma mark - UITableView Datasource

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *cellIdentifier = @"Cell";
    
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
    if (!cell) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
    }
    
    cell.textLabel.text = @"Placeholder Title";
    cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
    
    return cell;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return 5;
}

UITableViewCell Class Ref

###MediaManager

Create an NSObject subclass named MediaManager.

Add to it a method named - (void)fetchPopularMedia; that does nothing for the time being.

Now, what do we need to do to use MediaManager in our PopularMediaViewController?

#import "MediaManager.h"

@interface PopularMediaViewController () <UITableViewDataSource, UITableViewDelegate>
@property (nonatomic, strong) IBOutlet UITableView *tableView;
@property (nonatomic, strong) MediaManager *mediaManager;
@end

@implementation PopularMediaViewController

// ...

- (void)viewDidLoad
{
    [super viewDidLoad];

    // Do any additional setup after loading the view.

    self.title = @"Media";

    self.mediaManager = [[MediaManager alloc] init];
    [self updateContent];
}

- (void)updateContent
{
    [self.mediaManager fetchPopularMedia];
}

The MediaManager is a "controller" class that will be responsible for fetching data from the Instagram API and converting it into "model" objects. PopularMediaViewController and ImageViewController will each contain an instance of MediaManager. They will ask those instances to return the relevant data in the appropriate format.

#define POPULAR_MEDIA_ENDPOINT @"https://api.instagram.com/v1/media/popular?client_id="
#define INSTAGRAM_CLIENT_ID @"5609d2fb2bf74d749716bd00a9090e5e"

// The Instagram "popular media" endpoint we're hitting is documented here:
// http://instagram.com/developer/endpoints/media/#get_media_popular

@implementation MediaManager

#pragma mark - Networking

- (void)fetchPopularMedia
{
    NSString * endpoint = [NSString stringWithFormat:@"%@%@", POPULAR_MEDIA_ENDPOINT, INSTAGRAM_CLIENT_ID];
    
    NSURL *URL = [NSURL URLWithString:endpoint];
    NSURLRequest *request = [NSURLRequest requestWithURL:URL];
    
    // Use an NSURLSessionDataTask to asynchronously fetch JSON from Instagram's "popular media" endpoint
    
    __weak MediaManager * weakSelf = self;
    NSURLSession *session = [NSURLSession sharedSession];
    NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
        NSLog(@"Response: %@", response);        
    }];
    [task resume];
}

@end

NSURL Class Ref
NSURLRequest Class Ref
NSURLSession Class Ref
NSURLSessionDataTask Class Ref
NSURLResponse Class Ref
NSError Class Ref