Chapter 11

Storyboarding to Multimedia Platforms

This is the last chapter of the book and I have been looking forward to writing this chapter for a long time. This is the capstone app if you will. The app that teaches you how to market your restaurant, business, or whatever you like to various multimedia platforms. I chose to promote a band for this app because it includes iTunes and many of my students struggle with iTunes. We will take care of that right here. In the lecture hall, I first walk through the app with the students as they imagine they are in a distant place and time and they've discovered a band called The Beatles. They then market that band on the Web, YouTube, and iTunes. In the second half of this project, the students create their own business that they market in a similar but much more creative manner.

Unfortunately, due to copyright issues, it is not permissible to show pictures of the Beatles in a book that is not authorized by the Beatles. For the purposes of this book, I've created some dummy sites on the web with pictures of myself playing guitar and iTunes sites where I have songs from many years ago (1997). I will show you where to get the Beatles URLs (public domain) and how to make the site (first for the Beatles as I do in class) and then how to find other bands or other types of media to pretend to promote. Hopefully, you will have your own business, such as a restaurant, bead shop, consulting service, or whatever, that you can then make a promotional app of and shoot it up to the iTunes store so that people can download it for free.

How does this work? Remember back in Figure 1-21, I explained the exact process of how one can make money from an app on the Internet? Well, here I teach you how to market your business and set your app up, possibly for free to begin with. Let's say you have a babysitting business. After you learn how to manage the Beatles website, you can make an app for the babysitting business and shoot it up to the app store for free downloads. In the old days, we used to hand out cards – now we hand out apps. You let parents and potential parents of your babysitting store know that they can download your babysitting business' app for free and, with a password that only works for a limited time (and only if they are a potential parent), view their baby on a live webcam any time of day. They can see other children being taken care of by your staff. They can get updates on snow days, on birthdays, and pay their bills online all through your app. By word of mouth, those parents will tell other parents how great your business is based solely on how convenient and cool your app was.

The same applies to other businesses; you just need to be creative. Innovativeness is your department but hey! You had to have a huge streak of innovation to buy this book and, if you're still reading this, you're well into the realm of Geekdom so I have full faith that you have everything you need to make a wonderful app for your business, another person's business, or yourself. All you need is the technical know-how and I will teach you that right here, right now, so let's go!

myiTunes: A Master-Detail Application

myiTunes is based upon one of the more daunting methods of creating a storyboarding app: the Master-Detail Application. However, Master-Detail Applications empower the iPadiOS5'ssplit view and popover together with incredible storyboarding technology. More so, as if this were not enough, we also throw into the mix the ability to access iTunes, Facebook, Google+, pages that have videos, and, of course, the two iPad splash screens with cool icons that all add up to a beautiful, marketable app just waiting to boost you, your business, or another person's business up into the stratosphere—loudly!

iTunes has some controversial, quirky, and not so user-friendly means of accessing its iTunes music store. I will go through this step by step, including the ability to look up bands, videos, and podcasts. There are some other multimedia platforms I do not cover in the example because that would be overload, but I will show you exactly how to convert your media from images to video and so forth. I also include the code to access these other forms of multimedia and the boilerplate code that you download. So, even though we do not use all these types of media in the boilerplate, they are there for you to use as you so choose.

One thing about terminology before we proceed: we will be talking about split views and popovers in this app. These are the supercool tables and drop-down menus that, depending how you hold your iPad, invoke a table for the user to use. The split view shows 2 panels, side-by-side. In landscape mode, the master view is 320px wide. However, when you go to portrait orientation, the split view appears as a popover that looks like it's lying on top of the existing view. It looks like a drop-down menu sitting on top of what was underneath it (see Figure 11–25). It cannot be that it works like a dialog box or drop-down menu. One student recently asked me: “Dr. Lewis, can we pimp out the popover!?” Hmmm… nope! You cannot tweak, pimp out, and change much. But the issue is whether you want to or not, and the answer is ‘probably not'. Popovers are sophisticated, elegant, and show the user that you, the developer who programmed them, are awesome!

So let's get on with the preliminaries so we can make a start on our app.

Preliminaries

This chapter's download files are similar in nature to Chapter 10's boilerplates and images. Except that, as mentioned before, I include code that we do not use in this app but that you may want to use when you create your own app using alternative or additional media. It's all there for you to use. On the video and in the code, there is a substantial amount of code prewritten by me. However, I explain it all in intense detail in this chapter so I suggest that you try and code it all by yourself. If you find you need to use the boilerplate code after a while, then go ahead and use it, but please first try doing it on your own. If you do have to use the boilerplate code, then go ahead and try typing in the code line by line after you had success running the boilerplate code. If you cannot make it work, even using the boilerplate code, then download my exact Xcode file and, after making my code run, see exactly where you missed something.

These download files can be found at http://bit.ly/sL26vN. One can download the sample code that I programmed on the video here: http://bit.ly/uN1uV1. To view the screencast of this chapter's exercise, go to http://bit.ly/tPatpA. If you need more help, go to the forum at http://bit.ly/oLVwpY.

THE BIG PICTURE

A New Master-Detail Template

images

Figure 11–1. Select the Master-Detail Application icon, and press return or next.

1. We will use a Master-Detail Application. So open Xcode and enter imagesimagesN, as shown in Figure 11–1. After selecting the Master-Detail Application, press enter/return.

images

Figure 11–2. Name your app myiTunes making sure Storyboard and automatic referencing is on.

2. In order to follow along with me as closely as you can, name it “myiTunes,” select “iPad,” check the “Use Storyboard,” and “Use Automatic Reference Counting,” but leave the “Class Prefix” and “Include Unit Tests” unchecked as shown in Figure 11–2.

Bring in the Images!

images

Figure 11–3. Drag in your graphics.

3. Just as we did in myStory_01 after going to my website at http://bit.ly/uN1uV1 and downloading the images and boilerplate code onto your desktop, drag in the 72 × 72 pxiPad icon, iPad 72, into the App Icon box, drag the 769 × 1004 px Default-Portrait iPad splash screen into the Launch 'Images Landscape box, and drag the 1024 × 748 px Default-Landscape iPad splash screen into the Launch Images' Portrait box as shown in Figure 11–3.

images

Figure 11–4. Drag the images into the Supporting Files Folder.

4. Because we always want to keep things nice, orderly, and in their proper place, you will see that the files holding the images you just dragged into Xcode are in the root directory. We want to drag them into their proper location: the Supporting Files folder. This is illustrated in Figure 11–4.

Organize the Popover in Storyboard

The first thing we will do is set up the popover in the storyboard. I am going to be fairly inventive and artful but not go overboard with beautiful popover bells and whistles because I do not want to take away from my two goals: teaching you to set up the storyboard and teaching you to write the code behind the storyboard. However, once you complete this project, you will have opened the door to all the rooms where you can later tinker around. But, for right now, let's keep it simple.

images

Figure 11–5. Select Storyboard and close the Navigator.

5. Select MainStoryboard.storyboard and close the Navigator as shown in Figure 11–5.

images

Figure 11–6. We do not want a View Controller here.

6. Before we get too far, I want you to take a look at Figure 11–14 and take a look at all the Table views and their levels located in the left hand side bar called the Document Outline inside the box called Master View Controller - Master Scene. Compare how populated it is compared to our lone Table view in our Master View Controller - Master Scene. That's quite a lot of work there.

There are two ways to populate these Table Views with what you want. They are the “long boring” way and the “organized and very efficient” way. We plan ahead and we do this by sticking to a simple rule:

Create one Table view with all its sub-attributes. Then, once you have one done exactly the way you want it, duplicate the entire set.

We are selecting the default view Controller because we need to delete it. As far as the big picture is concerned, we will create one group exactly as we want it to be, as indicated by 1.1 in “The Big Picture”.

So go ahead and open the Documents Outline and select Table View in my Master View Controller–Master scene as shown in Figure 11–6.

THE BIG PICTURE

images

Figure 11–7. Create a grouped-style set of static cells.

7. Open the Attributes Inspector in the Utilities pane and then go down and ensure Static Cells from the Content drop-down menu. Next select “Grouped” Style to give us space for headers for separation as shown in Figure 11–7.

images

Figure 11–8. Selecting the Table View Cell - Cell

8. This can be benign but tricky so pay attention to this very simple step: go back to the Documents Outline and, inside your Master View Controller – Master scene, go down two levels from the Table View you have just been working on. As shown in Figure 11–8, you should now be at the Table View Cell—Cell. If you select the wrong level, you will only realize you're lost when you're very lost.

images

Figure 11–9. Create subtitles for each Table View Cell – Cell.

9. We want to create subtitles in each Table View Cell—Cell because they tell us, and most importantly the user, what we will see or where we will be going if we select this option. So, go back to the Attributes Inspector in the utilities pane and then go down and select Subtitle from the Style as shown in Figure 11–9.

NOTE: As we travel here for the first time while we set up the cells, note that there are many fun and awesome tricks you can use when you travel back here again. I mentioned that we will be opening “doors” that lead into rooms with lots of bells and whistles. This is one of them! Keep looking around as we travel to these different rooms.

images

Figure 11–10. Create disclosure indicators for each Table View Cell – Cell.

10. Looking at Figure 11–10, we can now see that, under Detail in our cell, there is a Subtitle. This is exactly what we want. Now, while we're here, why don't we also add disclosure indicators “>” that give the user a sense of the direction that they will be travelling in when they select a particular cell? Yup, that's a great idea! Go to the Accessory section just under the Style section you were in and select Disclosure Indicator as shown inFigure 11–10

images

Figure 11–11. Go back up one level to the Table View Section.

11. Ahh… look at that beautiful Disclosure and subtitle we've just created in Figure11–11. Beautiful! Before we get too lost, look at The Big Picture and see that we are about to embark on setting up the Table View Section (1.1.2.). Go back to the Documents Outline and select the Table View Section as shown in Figure 11–11.

THE BIG PICTURE

images

Figure 11–12. Name the first group “Artist” and create two rows.

12. Keep in mind that we have yet to label any of our Table View Cell—Cells yet. I only do this in step 1.3 in The Big Picture, which is the last step for two reasons. First, it takes time and, second, we will change them. However, in this instance, we need to go to the Header in the Attributes inspector and simply give it a “dummy” label that will give us something, anything, to edit when we duplicate these cells. So, go ahead and label this group with the name of our first group, which will be Artists. Then, create 2 rows as shown in Figure 11–12 because we will only have two rows of cells in each group. You may want more. You will always want to err on the side of creating more cells because then you can delete them very easily, but if you have to recreate cells, you often will have to spend time formatting them.

images

Figure 11–13. Only now do we create all of our sections.

13. We have now created one group exactly as we want it. So now go back to the original Table View where we began and make 4 sections as shown in Figure 11–13.

images

Figure 11–14. Name the cells and headers.

14. Of course you will do things differently when you create your own but for now let's name our four groups: Artists, Albums on iTunes, Songs, and Pictures. These 4 groups will facilitate our “Band's” (I will give you the Beatles links when we get to the code) presence on the Web, and iTunes, under Artists, then Albums. For the Beatles, there will be many albums. For our example, we're only using 2, and likewise for Songs and Pictures. Note that in the subtitles, some are telling the user that they will go to iTunes and some are telling the user they will go to the Internet. Name all the cells as shown in Figure 11–14. Remember that you can simply double-click on the cell to create a name.

Coding the myiTunes App

I really want to keep this really, really, really simple! Two broad things will be done when we code: first create code that hooks up to what we want to happen when each cell is pressed and then make sure our views connect correctly with the WebViews.

THE BIG PICTURE

images

Figure 11–15. Create a NSURL to hook up to iTunes.

15. We start by looking at the MasterViewController so let's first make sure that our header allows us to do all the things we need to do in our implementation file. Save everything, close the utilities, open the navigator, and open up the MasterViewController.h. We start by creating an NSURL to connect to iTunes. I've named this pointer iTunesURL as shown in Figure 11–22. Before we simply blurt out that we want an NSURL *iTunesURL, we need to bring in a protocol that will define this method. In our case, we specifically need to define a method that delegates or gives to us all the good stuff necessary for a UIWebView object that will handle the iTunes web content we want loaded. As we did before in myStory_02, we will use the UIWebViewDelegate Protocol Reference <UIWebViewDelegate>. Please make sure that you also create the @property as shown below.

#import<UIKit/UIKit.h>
@classmyDetailViewController;
@interfacemyMasterViewController : UITableViewController<UIWebViewDelegate>
{
    NSURL *iTunesURL;
}


@property (strong, nonatomic) myDetailViewController *detailViewController;
@property (strong, nonatomic) NSURL *iTunesURL;
@end
images

Figure 11–16. Paste the first Boilerplate.

16. Open up the MasterViewController implementation file and then select all the contents of the first Boilerplate file (Boilerplate 01). After that, paste the contents in-between the #import "myDetailViewController.h" line and the @implementation MasterViewController line as shown in Figure 11–16. This code is nothing else but forward declarations of private methods I've written to accommodate the various types of media we link to in this app and media that you may use in later apps. Specifically we have 3:

a. LocateArtistPageInSafari

b. LocateArtistPageInItunes, a LocateMoviePageInItunes (we do not use this one but I thought you may like to have it at your disposal) and

c. StartExternalAppWithURL:(NSURL *)theURL).

Once you paste the first boilerplate in, it should look as follows:

#import "MasterViewController.h"
#import "myDetailViewController.h"
////////////// START BOILERPLATE 1 ////////////////////
@interfaceMasterViewController (PrivateMethods)
// forward declarations for private methods
-(void)LocateArtistPageInSafari;
-(void)LocateArtist2PageInSafari;
-(void)LocateArtist3PageInSafari;
-(void)LocateArtistPageInItunes;
-(void)LocateMoviePageInItunes;
-(void)LocateAlbumPageInItunes;
-(void)LocateTrackInItunes;

-(void)DeselectRow;
-(void)StartExternalAppWithURL:(NSURL *)theURL;
@end

////////////// END BOILERPLATE 1 ////////////////////
@implementationmyMasterViewController
@synthesizedetailViewController = _detailViewController;
images

Figure 11–17. Synthesize the iTunesURL.

17. We cannot get too wrapped up in the header protocol and forget that we need to synthesize the iTunesURL we set up in our header file. This is shown in Figure 11–23 and also below.

////////////// END BOILERPLATE 1 ////////////////////
@implementationMasterViewController
@synthesizedetailViewController = _detailViewController;
@synthesizeiTunesURL;
- (void)awakeFromNib
{
    self.clearsSelectionOnViewWillAppear = NO;
    self.contentSizeForViewInPopover = CGSizeMake(320.0, 600.0);
    [superawakeFromNib];
}
images

Figure 11–18. Insert boilerplate 2.

18. The viewDidLoad that comes along with the Master-Detail default Instantiation is not exactly what we need. There are two ways to do this and I prefer the first way, which is to code it yourself. Here you will see why we need to add onto it. For those of you who may feel you're being overwhelmed, that's cool too.Hang in there and let me go over how to tweak the viewDidLoad. After that, we'll show you how to use the boilerplate. As you know, the grey lettering is the code that is automatically instantiated. Essentially I've added an “If” statement.Mmm…. what is this if statement doing?All we're doing here is saying that we have code here that is specific to the iPad, and we want to make sure that the interface that's being used on the current device is the correct one.

- (void)viewDidLoad
{
    [superviewDidLoad];
        // Do any additional setup after loading the view, typically from a nib.
    self.detailViewController = (DetailViewController
*)[[self.splitViewController.viewControllerslastObject] topViewController];
    if ([[UIDevicecurrentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
        [self.tableViewselectRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]
animated:NOscrollPosition:UITableViewScrollPositionMiddle];
        self.detailViewController.webView.delegate = self;
    }
}

Now, for those of you who feel a little more comfortable pasting in the boilerplate code, open boilerplate 02 and select everything. Then select all of viewDidLoad and paste it over it so that it looks similar to what is shown in Figure 11–18 and as shown here:

- (void)didReceiveMemoryWarning
{
    [superdidReceiveMemoryWarning];
    // Release any cached data, images, etc that aren't in use.
}

#pragma mark - View lifecycle
////////////// START BOILERPLATE 2 ////////////////////
- (void)viewDidLoad
{
    [superviewDidLoad];
        // Do any additional setup after loading the view, typically from a nib.
    self.detailViewController = (DetailViewController
*)[[self.splitViewController.viewControllerslastObject] topViewController];
    if ([[UIDevicecurrentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
        [self.tableViewselectRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]
animated:NOscrollPosition:UITableViewScrollPositionMiddle];
        self.detailViewController.webView.delegate = self;
    }
}

////////////// END BOILERPLATE 2 ////////////////////
- (void)viewDidUnload
{
    [superviewDidUnload];
    // Release any retained subviews of the main view.
    // e.g. self.myOutlet = nil;
images

Figure 11–19. Boilerplate 3

19. We now need to delete everything from shouldAutorotateToInterfaceOrientation down to the @end. Once it is deleted, select all the contents of boilerplate 3, as shown in Figure 11–19, and paste it in its place. This code is the crux of it all so let's go through it now. Let's start by looking at The Big Picture to see that we have completed 2.1.1.1 through to 2.1.1.2. We need to make sure our app still runs regardless of the orientation of the iPad (split view, in landscape, and popover in portrait) and have a set of cases of events that we will trigger if a cell is selected. We have eight cells so we will have eight cases ranging from 0 through to 7. We will then program our private methods to deal with special circumstances.

NOTE: Since we are first coding the MasterViewController, Xcode will give you some warnings and error signs at this point. Ignore them for now.

THE BIG PICTURE

The original shouldAutorotateToInterfaceOrientation is shown in grey below and we'll only use it if it's an iPad.

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)
interfaceOrientation
{
    // Return YES for supported orientations
    if ([[UIDevicecurrentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
        return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
    } else {

    return YES;
    }
}

We need to do a couple of things now. We need to convert our section and row numbers from a linear index to rows when counting from top to bottom. For those of you who are looking carefully at each line of code, I need to point out that the next two lines assume that the 1st section is 2 rows and all others are 1.

NSInteger nSelectedRowIdx = (indexPath.section > 0) ? indexPath.section+1 : 0;
//now 0,2,3,4
nSelectedRowIdx += indexPath.row;
//now 0,1,2,3,4

If you're happy that this all relates each case to a specific line (the top line in each cell), then that's OK too. Just use this every time you do it. In fact, just paste it in and change the case statements below and you will be fine.

- (void)tableView:(UITableView *)tableViewdidSelectRowAtIndexPath:(NSIndexPath
*)indexPath
{
    NSIntegernSelectedRowIdx = indexPath.section *2 + indexPath.row;
    switch (nSelectedRowIdx) {

Now we need to make the case statements that will tag along the rows we have ordered sequentially. We have four sections: ARTIST, ALBUMS IN ITUNES, SONGS, and PICTURES. We need to have two selections called cases within each of them, so let's lay it out in The Big Picture for a minute.

THE BIG PICTURE

Accordingly, the code is as follows:

        case 0: // in Safari (Artist)
            [selfLocateArtistPageInSafari];
            break;

        case 1: // in iTunes (Artist)
            //[selfLocateArtistPageInItunes];
        {
            NSURL *urlInItunes = [NSURL URLWithString:@"http://itunes.apple.com/images
us/artist/rory-lewis/id65902515?uo=4"];
            [selfStartExternalAppWithURL:urlInItunes];
        }
            break;
        case 2: // in iTunes (Songs)
                     //[selfLocateArtistPageInItunes];
        {
            NSURL *urlInItunes = [NSURL URLWithString:@"http://itunes.apple.com/images
us/album/songs-for-friday/id408548641?uo=4"];
            [selfStartExternalAppWithURL:urlInItunes];
        }
            break;
        case 3: // in iTunes (Songs)
            //[selfLocateArtistPageInItunes];
        {
            NSURL *urlInItunes = [NSURL URLWithString:@"http://itunes.apple.com/us/images
album/heroines/id461113548?uo=4"];
            [selfStartExternalAppWithURL:urlInItunes];
        }
            break;
        case 4: // in iTunes (Songs)
            //[selfLocateArtistPageInItunes];
        {
            NSURL *urlInItunes = [NSURL URLWithString:@"http://itunes.apple.com/us/images
album/elvis-presley/id461113548?i=461113566&uo=4"];

            [selfStartExternalAppWithURL:urlInItunes];
        }
            break;
        case 5: // in iTunes (Songs)
            //[selfLocateArtistPageInItunes];
        {
            NSURL *urlInItunes = [NSURL URLWithString:@"http://itunes.apple.com/images
us/album/hippie-paradise/id408548641?i=408549591&uo=4"];
            [selfStartExternalAppWithURL:urlInItunes];
        }
            break;
        case 6: // in Safari (Artist)
            [self LocateArtist2PageInSafari];
            break;

        case 7: // in Safari (Artist)
            [self LocateArtist3PageInSafari];
            break;

    }

    //[selfDeselectRow];
}

We now need to create our helper routines to process redirects prior to handing off to the open application. Specifically, we need to process a LinkShare/TradeDoubler/DGM URL to something iPhone can handle, if you choose to use a universal app on your own that does include the iPhone. For more information you can go to http://developer.apple.com/library/ios/#qa/qa1629/_index.htm.

- (void)openReferralURL:(NSURL *)referralURL {
    //NSURLConnection *connection =
    (void)[[NSURLConnection alloc] initWithRequest:[NSURLRequest
requestWithURL:referralURL] delegate:self startImmediately:YES];
}

Now we save the most recent URL for a safety measure (just in case multiple redirects occur). Note that iTunesURL is an NSURL property in this class declaration:

- (NSURLRequest *)connection:(NSURLConnection *)connection willSendRequest:(NSURLRequest
*)request redirectResponse:(NSURLResponse *)response {
    self.iTunesURL = [response URL];
    NSLog(@"RxURL [%@]",[self.iTunesURLabsoluteString]);
    return request;
}

OK, no more redirects. So we use the last URL that we saved:

- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
    [selfStartExternalAppWithURL:self.iTunesURL];
}

This is a little technical, but we need to have an iTMS link (a special kind of url/link protocol used for iTunes' links and URLs) to get out there into the ether. We have this little method called StartExternalAppWithURL in order to allow our iTMS links:

-(void)StartExternalAppWithURL:(NSURL *)theURL
{

    NSLog(@"UsingURL [%@]",[theURLabsoluteString]);
    [[UIApplicationsharedApplication] openURL:theURL];
    [selfDeselectRow];
}

Almost done. We just need to deselect our last selected table cell so, when our view reappears, it will not still be selected. We do this after our external app start has been requested because this object is NOT informed of view leaving OR the apprestarting from the background when it is resumed without adding additional plumbing.

-(void)DeselectRow
{
    // Unselect the selected row if any
    NSIndexPath* selection = [self.tableViewindexPathForSelectedRow];
    if (selection) {
        [self.tableViewdeselectRowAtIndexPath:selectionanimated:YES];
    }
    [self.tableViewreloadData];
}

Last bit—three Artist pages in Safari (case 0) and the cases for 6 and 7.

-(void)LocateArtistPageInSafari
{
    NSURL *urlInSafari = [NSURL URLWithString:@"http://bit.ly/poi91o"];
    // if we have an iPAD...
    if ([[UIDevicecurrentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
        // then open page in detail view (UIWebView)
        NSURLRequest *urlRequest = [NSURLRequestrequestWithURL:urlInSafari];
        [self.detailViewController.webViewloadRequest:urlRequest];
    } else {
        // else we have an iPhone/iPod Touch so open in external safari
        [selfStartExternalAppWithURL:urlInSafari];
    }
}

-(void)LocateArtist2PageInSafari
{
    NSURL *urlInSafari = [NSURL URLWithString:@"http://on.fb.me/nFwQj6"];
    // if we have an iPAD...
    if ([[UIDevicecurrentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
        // then open page in detail view (UIWebView)
        NSURLRequest *urlRequest = [NSURLRequestrequestWithURL:urlInSafari];
        [self.detailViewController.webViewloadRequest:urlRequest];
    } else {
        // else we have an iPhone/iPod Touch so open in external safari
        [selfStartExternalAppWithURL:urlInSafari];
    }
}

-(void)LocateArtist3PageInSafari
{
    NSURL *urlInSafari = [NSURL URLWithString:@"http://bit.ly/nxY8AZ"];
    // if we have an iPAD...
    if ([[UIDevicecurrentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
        // then open page in detail view (UIWebView)
        NSURLRequest *urlRequest = [NSURLRequestrequestWithURL:urlInSafari];
        [self.detailViewController.webViewloadRequest:urlRequest];

    } else {
        // else we have an iPhone/iPod Touch so open in external safari
        [selfStartExternalAppWithURL:urlInSafari];
    }
}

@end

Coding DetailViewController

That was something else, wasn't it!? Just as an aside, something that will make you laugh. When I first began to get my head wrapped around storyboarding for my class, we were working on the beta version and it kept changing every week. Not only had I never seen a storyboard before, but the code was changing constantly and I had to teach it in front of the lecture hall. I had many sleepless nights. But here is the deal. If you master this app and storyboarding, you are well on your way to huge success in programming. You do not have to know all of the above, you can simply learn when to use it. In our DetailViewController, we need to set up our UIWebview but first let's have a look at The Big Picture.

THE BIG PICTURE

images

Figure 11–20. Select and open the DetailViewController header file.

20. Save your MasterViewController and open the DetailViewController.h file as shown in Figure 11–20. Then add the code shown below. Note that when we go back to tweak the storyboard, we will connect this to our UIWebView.

#import<UIKit/UIKit.h>
@interfaceDetailViewController : UIViewController<UISplitViewControllerDelegate>
@property (strong, nonatomic) id detailItem;
@property (strong, nonatomic) IBOutletUILabel *detailDescriptionLabel;
@property (strong, nonatomic) IBOutletUIWebView *webView;
@end
images

Figure 11–21. Synthesize the webView in the implementation file.

21. Now open your DetailViewController.m file and synthesize the webView as shown in Figure 11–21 and here:

#import "DetailViewController.h"
@interfaceDetailViewController ()
@property (strong, nonatomic) UIPopoverController *masterPopoverController;
- (void)configureView;
@end

@implementationDetailViewController
@synthesizedetailItem = _detailItem;
@synthesizedetailDescriptionLabel = _detailDescriptionLabel;
@synthesizemasterPopoverController = _masterPopoverController;
@synthesizewebView = _webView;
#pragma mark - Managing the detail item
images

Figure 11–22. Select Boilerplate 4.

22. We now need to redo our shouldAutorotateToInterfaceOrientation method to take care of the Portrait and Landscape issues as mentioned before. Go ahead and delete the shouldAutorotateToInterfaceOrientation and either write these few lines of code or paste in its place the contents of Boilerplate 4.

////////////// START BOILERPLATE 4 ////////////////////
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)images
interfaceOrientation
{
    // Return YES for supported orientations
    if ([[UIDevicecurrentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
        return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
    } else {
        return YES;
    }
}
////////////// END BOILERPLATE 4 ////////////////////
images

Figure 11–23. Go back to Storyboard and select the Table View Cell – Cell and drag a Web View onto the Detail View.

23. Save everything and go back into storyboard, close the Navigator, open up the Utilities and, in the Utilities, open up the Library. Our Table View Cell is where our web views will be shown so we need a web view located there. Go back to Storyboard and select the Table View Cell – Cell and drag a Web View onto the Detail View as shown in Figure 11–23.

Finalizing the Storyboard

We are almost done. The only thing we need to still do is connect something that was not there when we began – the webViewUIWebView connection in the code. Now that it's there, we need to go back into storyboard and connect them.

images

Figure 11–24. Select myMasterTableViewController.

24. Now go back to the Documents Outline and, inside the Detail View Controller - Detail Scene, grab the Web View and drag it up over the Navigation Item - Detail above the View into your Detail View Controller -Detail. Now your View disappears just as we did in myStory_02. Keeping the Detail View Controller - Detail selected as shown in the upper left-hand side in Figure 11–24, go back over to your Connection Inspector and control-drag from the webView to the UIWebView as shown in Figure 11–24. Save it.

NOTE: Now connect your iPad to your Mac and, rather than selecting iPad simulator, select iOS Device. You can run it on the simulator if you like but iTunes cannot run inside the simulator so all the iTunes links will not work. Once you have connected your iPad to your Mac, press run.

images

Figure 11–25. From the icon through to the Popover

25. Once your app has completed building, which may take up to 17 seconds, you will see the icon appear as shown in Figure 11–25. Once you press the icon, you will immediately see the popover screen. The first time you select it, it will not show anything underneath. However, once you select a page and then select the popover again, it keeps the underlying image below the popover as shown in Figure 11–26.

images

Figure 11–26. A beautiful Splash screen presents itself while the screen loads.

26. Once we select a cell, the splash screen appears while the page loads from the Internet or from iTunes. Here, in the right hand image, we see the popover placed on top of the first image.

images

Figure 11–27. Orientation working with iTunes

27. We need to have a little patience with orientation correcting itself with iTunes. This is something Apple needs to work on. Just be patient. Figure 11–27 shows the 2nd selection on the left hand side and the first iTunes selection on the right hand side.

In Ending

This has been a wonderful journey, but it's really only the start. As I've gone through this second edition, I cannot help but think of all the fresh minds that will read these exercises and struggle through them, then break through to create awesome apps and make money! How many more of my students and readers of this book will work at Apple!? Wow! It's been a great motivation for me to think about this.

On a sad note, as I was finishing this book, Steve Jobs passed away. God bless you, Steve.

I hope to see you all on the forum. I do not answer questions submitted to me by email but I will answer those exact same questions if you post them on the forum (http://bit.ly/oLVwpY) because then everybody can share my answers. I would also like to encourage you to help. No matter how much of a beginner you are, get into the forum and help others. Helping others speeds up your journey.

Peace.

Dr. Lewis

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset