- Creating New Projects
- Building Hello World the Template Way
- Using the Simulator
- The Minimalist Hello World
- Converting Interface Builder Files to Their Objective-C Equivalents
- Using the Debugger
- Memory Management
- Recipe: Using Instruments to Detect Leaks
- Recipe: Using Instruments to Monitor Cached Object Allocations
- Analyzing Your Code
- Building for the iOS Device
- Detecting Simulator Builds with Compile-Time Checks
- Performing Runtime Compatibility Checks
- Pragma Marks
- Preparing for Distribution
- Over-the-Air Ad Hoc Distribution
- Submitting to the App Store
- Summary
The Minimalist Hello World
While exploring the iOS SDK, and in the spirit of Hello World, it helps to know how to build parsimonious applications. That is, you should know how to build an application completely from scratch, without five source files and two interface files. Here is a walkthrough showing you exactly that—a very basic Hello World that mirrors the approach shown with the previous Hello World example but that manages to do so with one file and no .storyboard or xib files.
Start by creating a new project (File > New Project, Command-Shift-N) in Xcode. Choose Empty Application, click Next, enter Hello World as the product name, and set your company identifier as needed (mine is com.sadun). Set the device family to Universal, uncheck Use Core Data, uncheck Include Unit Tests, and click Next. Save it to your desktop.
When the project window opens, select the two App Delegate files (.h and .m) from the project navigator and click delete or backspace to delete them. Choose Delete (formerly Also Move to Trash) when prompted.
Open Hello World > Supporting Files > main.m and replace its contents with Listing 3-1. The source is included in the sample code for this book (see the Preface for details), so you don’t have to type it in by hand.
Listing 3-1. Reductionist main.m
#import <UIKit/UIKit.h> // Simple macro distinguishes iPhone from iPad #define IS_IPHONE (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) @interface TestBedAppDelegate : NSObject <UIApplicationDelegate> { UIWindow *window; } @end @implementation TestBedAppDelegate - (UIViewController *) helloController { UIViewController *vc = [[UIViewController alloc] init]; vc.view.backgroundColor = [UIColor greenColor]; // Add a basic label that says "Hello World" UILabel *label = [[UILabel alloc] initWithFrame: CGRectMake(0.0f, 0.0f, window.bounds.size.width, 80.0f)]; label.text = @"Hello World"; label.center = CGPointMake(CGRectGetMidX(window.bounds), CGRectGetMidY(window.bounds)); label.textAlignment = UITextAlignmentCenter; label.font = [UIFont boldSystemFontOfSize: IS_IPHONE ? 32.0f : 64.0f]; label.backgroundColor = [UIColor clearColor]; [vc.view addSubview:label]; return vc; } - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { window = [[UIWindow alloc] initWithFrame: [[UIScreen mainScreen] bounds]]; window.rootViewController = [self helloController]; [window makeKeyAndVisible]; return YES; } @end int main(int argc, char *argv[]) { @autoreleasepool { int retVal = UIApplicationMain(argc, argv, nil, @"TestBedAppDelegate"); return retVal; } }
So what does this application do? It builds a window, colors the background, and adds a label that says “Hello World.” In other words, it does exactly what the first Hello World example did, but it does so by hand, without using Interface Builder.
The application starts in main.m by establishing the autorelease pool and calling UIApplicationMain(). From there, control passes to the application delegate, which is specified as the last argument of the call by naming the class. This is a critical point for building a non–Interface Builder project, and one that has snagged many a new iPhone developer.
The delegate, receiving the application:didFinishLaunchingWithOptions: message, builds a new window, querying the device for the dimensions (bounds) of its screen. It creates a new view controller, assigns that controller as its rootViewController property, and orders it out, telling it to become visible. Using the device’s screen bounds ensures that the main window’s dimensions match the device. For older iPhones, the window will occupy a 320×480-pixel area, for the iPhone 4 and later, 640×960 pixels, for the first two generations of iPads, 768×1024 pixels.
The helloController method initializes its view controller’s view by coloring its background and adding a label. It uses UI_USER_INTERFACE_IDIOM() to detect whether the device is an iPhone or iPad, and adjusts the label’s font size accordingly to either 32 or 64 points. In real-world use, you may want to perform other platform-specific adjustments such as choosing art or setting layout choices.
As you can see, laying out the label takes several steps. It’s created and the text added, centered, aligned, and other features modified. Each of these specialization options defines the label’s visual appearance, steps that are much more easily and intuitively applied in Interface Builder. Listing 3-1 demonstrates that you can build your interface entirely by code, but it shows how that code can quickly become heavy and dense.
In Xcode, the Interface Builder attributes inspector fills the same function. The inspector shows the label properties, offering interactive controls to choose settings such as left, center, and right alignment. Here, that alignment is set programmatically to the constant UITextAlignmentCenter, the background color is set to clear, and the label programmatically moved into place via its center property. In the end, both the by-hand and Interface Builder approaches do the same thing, but here the programmer leverages specific knowledge of the SDK APIs to produce a series of equivalent commands.
Browsing the SDK APIs
iOS SDK APIs are fully documented and accessible from within Xcode. Choose Help > Developer Documentation (Command-Option-Shift-?) to open the Xcode Organizer > Documentation browser. The Documentation tab will be selected at the top bar of the window. Other tabs include iPhone, Repositories, Projects, and Archives, each of which plays a role in organizing Xcode resources.
The documentation you may explore in this window is controlled in Xcode’s preferences. Open those preferences by choosing Xcode > Preferences (Command-,) > Documentation. Use the GET buttons to download document sets. Keep your documentation up to date by enabling “Check for and install updates automatically.”
In the Developer Documentation organizer, start by locating the three buttons at the top of the left-hand area. From left to right these include an eye, a magnifying glass, and an open book. The eye links to explore mode, letting you view all available documentation sets. The magnifying glass offers interactive search, so you can type in a phrase and find matching items in the current document set. The open book links to bookmarks, where you can store links to your most-used documents.
Select the middle (magnifying glass) search button. In the text field just underneath that button locate another small magnifying glass. This second magnifying glass has a disclosure triangle directly next to it. Click that disclosure and select Show Find Options from the pop-up menu. Doing so reveals three options below the text field: Match Type, Doc Sets, and Languages. Use the Doc Sets pop-up to hide all but the most recent iOS documentation set. This simplifies your search results so you do not find multiple hits from SDK versions you’re not actually using.
Enter UILabel into the search field to find a list of API results that match UILabel, as well as full text and title matches. The first item in the results list should link to the iOS Library version of the documentation. Refer to the jump bar at the top of the main area to locate which library you are viewing. This should read something like iOS Library > User Experience > Windows & Views > UILabel Class Reference. The UILabel Class Reference (see Figure 3-8) displays all the class methods, properties, and instance methods for labels as well as a general class overview.
Figure 3-8. Apple offers complete developer documentation from within Xcode itself.
Apple’s Xcode-based documentation is thorough and clear. With it you have instant access to an entire SDK reference. You can look up anything you need without having to leave Xcode. When material goes out of date, a document subscription system lets you download updates directly within Xcode.
Xcode 4 lost the handy class overview that appeared to the left of documentation in Xcode 3. The jump bar at the top embeds the same organization features (namely overview, tasks, properties, and so on). If you’d rather view the material with the old-style Developer Library overview, right-click in the class reference area and choose Open Page in Browser. Figure 3-9 shows the browser-based presentation with that helpful at-a-glance class Table of Contents to the left of the core material.
Figure 3-9. The “Table of Contents” view is no longer available from within Xcode itself but can be accessed via Open Page in Browser.