- •C and Objective-C
- •How this book works
- •How the life of a programmer works
- •Installing Apple’s developer tools
- •Getting started with Xcode
- •Where do I start writing code?
- •How do I run my program?
- •So what is a program?
- •Don’t stop
- •Types
- •A program with variables
- •Challenge
- •Boolean variables
- •When should I use a function?
- •How do I write and use a function?
- •How functions work together
- •Local variables, frames, and the stack
- •Recursion
- •Looking at the frames in the debugger
- •return
- •Global and static variables
- •Challenge
- •printf()
- •Integer operations
- •Integer division
- •Operator shorthand
- •Floating-point numbers
- •Tokens for displaying floating-point numbers
- •The while loop
- •The for loop
- •break
- •continue
- •The do-while loop
- •Challenge
- •Getting addresses
- •Storing addresses in pointers
- •Getting the data at an address
- •How many bytes?
- •NULL
- •Stylish pointer declarations
- •Challenges
- •Writing pass-by-reference functions
- •Avoid dereferencing NULL
- •Creating and using your first object
- •Message anatomy
- •Objects in memory
- •Challenge
- •Nesting message sends
- •Multiple arguments
- •Sending messages to nil
- •Challenge
- •Challenge
- •NSMutableArray
- •Reference pages
- •Quick Help
- •Other options and resources
- •Accessor methods
- •Dot notation
- •Properties
- •self
- •Multiple files
- •Challenge
- •Overriding methods
- •super
- •Challenge
- •Object ownership and ARC
- •Creating the Asset class
- •Adding a to-many relationship to Employee
- •Challenge
- •Retain cycles
- •Weak references
- •Zeroing of weak references
- •For the More Curious: Manual reference counting and ARC History
- •Retain count rules
- •NSArray/NSMutableArray
- •Immutable objects
- •Sorting
- •Filtering
- •NSSet/NSMutableSet
- •NSDictionary/NSMutableDictionary
- •Preprocessor directives
- •#include and #import
- •#define
- •Global variables
- •enum
- •#define vs global variables
- •Writing an NSString to a file
- •Reading files with NSString
- •Writing an NSData object to a file
- •Reading an NSData from a file
- •Target-action
- •Helper objects
- •Notifications
- •Which to use?
- •Callbacks and object ownership
- •Challenge
- •Getting started with iTahDoodle
- •BNRAppDelegate
- •Adding a C helper function
- •Objects in iTahDoodle
- •Model-View-Controller
- •The application delegate
- •Setting up views
- •Running on the iOS simulator
- •Wiring up the table view
- •Adding new tasks
- •Saving task data
- •For the More Curious: What about main()?
- •Edit BNRDocument.h
- •A look at Interface Builder
- •Edit BNRDocument.xib
- •Making connections
- •Revisiting MVC
- •Edit BNRDocument.m
- •Writing init methods
- •A basic init method
- •Using accessors
- •init methods that take arguments
- •Deadly init methods
- •Property attributes
- •Mutability
- •Lifetime specifiers
- •copy
- •More about copying
- •Advice on atomic vs. nonatomic
- •Key-value coding
- •Non-object types
- •Defining blocks
- •Using blocks
- •Declaring a block variable
- •Assigning a block
- •Passing in a block
- •typedef
- •Return values
- •Memory management
- •The block-based future
- •Challenges
- •Anonymous block
- •NSNotificationCenter
- •Bitwise-OR
- •Bitwise-AND
- •Other bitwise operators
- •Exclusive OR
- •Complement
- •Left-shift
- •Right-shift
- •Using enum to define bit masks
- •More bytes
- •Challenge
- •char
- •char *
- •String literals
- •Converting to and from NSString
- •Next Steps
- •Index
Chapter 27 Your First iOS Application
// Otherwise, just create an empty one to get us started. tasks = [[NSMutableArray alloc] init];
}
}
Wondering about the #pragma mark at the start of this code? Objective-C programmers often use this construct to group their methods within a class. Xcode knows about it, too. On the navigation bar at the top of the editor, find the item to the right of BNRAppDelegate.m. (Right now, this item probably reads @implementation AppDelegate, but it depends on where your cursor is in the code.) Click on this item, and Xcode will show you a list of locations in this file. You can click on any of these to be taken to that location in the code. Notice that your new pragma mark shows up on this list. This is very handy when you have many methods in a class.
Setting up views
Another thing we need to do before the application is ready for action is set up our view objects. This includes creating them, configuring them, and putting them on the screen. Makes sense, right? The user can’t tap a button that doesn’t exist or is not on the screen.
In iTahDoodle, you’re going to set up your views programmatically in application:didFinishLaunchingWithOptions:. There is also a visual “drag-and-drop” tool for setting up views that we’ll use in the next chapter.
I should warn you that here’s where the code starts getting dense. The detailed syntax of creating and showing views on the screen is a topic for a book specifically about iOS application programming. Try to follow the gist of what’s going on as you type in the code. You create each object and then configure it by setting some of its properties. Next, the configured view objects are added as subviews of the window object, and, finally, the window is placed on the screen.
#pragma mark - Application delegate callbacks
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Attempt to load an existing to-do dataset from an array stored to disk. NSArray *plist = [NSArray arrayWithContentsOfFile:docPath()];
if (plist) {
//If there was a dataset available, copy it into our instance variable. tasks = [plist mutableCopy];
}else {
//Otherwise, just create an empty one to get us started.
tasks = [[NSMutableArray alloc] init];
}
//Create and configure the UIWindow instance
//A CGRect is a struct with an origin (x,y) and size (width,height) CGRect windowFrame = [[UIScreen mainScreen] bounds];
UIWindow *theWindow = [[UIWindow alloc] initWithFrame:windowFrame]; [self setWindow:theWindow];
//Define the frame rectangles of the three UI elements
//CGRectMake() creates a CGRect from (x, y, width, height)
CGRect tableFrame = CGRectMake(0, 80, 320, 380);
CGRect fieldFrame = CGRectMake(20, 40, 200, 31);
CGRect buttonFrame = CGRectMake(228, 40, 72, 31);
184
Running on the iOS simulator
// Create and configure the table view
taskTable = [[UITableView alloc] initWithFrame:tableFrame style:UITableViewStylePlain];
[taskTable setSeparatorStyle:UITableViewCellSeparatorStyleNone];
//Create and configure the text field where new tasks will be typed taskField = [[UITextField alloc] initWithFrame:fieldFrame]; [taskField setBorderStyle:UITextBorderStyleRoundedRect];
[taskField setPlaceholder:@"Type a task, tap Insert"];
//Create and configure a rounded rect Insert button
insertButton = [UIButton buttonWithType:UIButtonTypeRoundedRect]; [insertButton setFrame:buttonFrame];
//Buttons behave using a target/action callback
//Configure the Insert button's action to call this object's -addTask: method [insertButton addTarget:self
action:@selector(addTask:)
forControlEvents:UIControlEventTouchUpInside];
//Give the button a title [insertButton setTitle:@"Insert"
forState:UIControlStateNormal];
//Add our three UI elements to the window [[self window] addSubview:taskTable]; [[self window] addSubview:taskField]; [[self window] addSubview:insertButton];
//Finalize the window and put it on the screen
[[self window] setBackgroundColor:[UIColor whiteColor]]; [[self window] makeKeyAndVisible];
return YES;
}
Running on the iOS simulator
Now that you’ve set up your views, we can build the application to see how they look. In Xcode, find the Scheme dropdown menu near the Run button. Select iPhone 5.X Simulator for the latest version of the iOS simulator:
Figure 27.6 Scheme selector
Build and run the application. You’ll get a warning from the compiler that you that you haven’t implemented addTask:. Ignore that for now; you’ll implement addTask: shortly.
The simulator lets you run Cocoa Touch applications on your desktop. This is a quick and easy way to see what your program should look and act like when it runs on an iOS device.
185