By Jonathan A. Zdziarski
Book Price: $39.99 USD
£24.99 GBP
PDF Price: $27.99
Cover | Table of Contents | Forum | Colophon
ls and cp. This allows you to navigate and manage the iPhone's operating system, which is believed to be a version of Mac OS X 10.5 (Leopard) for the arm processor. Finally, you'll get a secure login command environment, SSH, up and running. This is useful for copying files to and from your iPhone, and we'll use it to install applications and run examples.
drwxr-xr-x root admin Terminal.app/
-rw-r--r-- root admin Default.png
-rw-r--r-- root admin Info.plist
-rwxr-xr-x root admin Terminal
-rw-r--r-- root admin icon.png
-rw-r--r-- root admin pie.png
gcc in the past. You'll want to make sure /usr/local/bin is in your path before you try to use the cross-compiler.
$ export PATH=$PATH:/usr/local/bin
$ arm-apple-darwin-gcc -o MyExample MyExample.m -lobjc \
-framework CoreFoundation -framework Foundation
arm-apple-darwin-gcc-o MyExampleMyExample.m-lobjc-framework CoreFoundation -framework FoundationBuild button on the toolbar. XCode will call the tool chain's compiler and place a binary in the project's build folder.myWidget, a message can be sent to its powerOn method this way:returnValue = [ myWidget powerOn ];
returnValue = myWidget->powerOn( );
returnValue = widget_powerOn(myWidget);
main( ) function instantiates a UIApplication object within UIKit. This class is the base class for all applications having a user interface on the iPhone, and it provides the application access to the iPhone's higher-level functions. In addition to this, common application-level services such as suspend, resume, and termination are functions of the UIApplication object.
$ arm-apple-darwin-gcc -o MyApp MyApp.m -lobjc \
-framework CoreFoundation \
-framework Foundation \
-framework UIKit
LDFLAGS = -lobjc \
-framework CoreFoundation \
-framework Foundation \
-framework UIKit
UIWindow is the iPhone's base window class and is derived from lower level functions that respond to mouse events, gestures, and other types of events that would be relevant to a window. The UIWindow class is ultimately responsible for holding the contents of a UIView object (the picture that fits in the window's frame). UIView is a base class from which many other types of display classes are derived. The window itself can only hold one object, whereas the UIView object is designed to accommodate many different types of subobjects, including other views. The two classes go hand-in-hand with each other, and both are required to display anything on the iPhone screen.CGRect that contains two pieces: the coordinates for the upper-left corner of the window and the window's size (its width and height). Every object displayed on the screen has a display region defining its display area. Most are set when the object is initialized, via an initWithFrame method. Others must be set after the fact using a ubiquitous method named setFrame. In the case of the main window, the region's coordinates are offset to the screen itself; however, all subsequent objects (including the window's view) are offset to the object that contains it. As other objects are nested inside the view, those objects' regions will be offset to the view, and so on.UIHardware.CGRect windowRect = [ UIHardware fullScreenApplicationContentRect ];
UIView class is just a container class, it can't even display any text for you. All you'll see is a black screen. What this application does do is serve as the first few lines of code any GUI application on the iPhone will use.
$ arm-apple-darwin-gcc -o MyExample MyExample.m -lobjc \
-framework CoreFoundation -framework Foundation -framework UIKit
#import <CoreFoundation/CoreFoundation.h>
#import <UIKit/UIKit.h>
@interface MyApp : UIApplication
{
UIWindow *window;
UIView *mainView;
}
- (void)applicationDidFinishLaunching:
(NSNotification *)aNotification;
@end
#import "MyExample.h"
int main(int argc, char **argv)
{
NSAutoreleasePool *autoreleasePool = [
[ NSAutoreleasePool alloc ] init
];
int returnCode = UIApplicationMain(argc, argv, [ MyApp class ]);
[ autoreleasePool release ];
return returnCode;
}
@implementation MyApp
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
window = [ [ UIWindow alloc ] initWithContentRect:
[ UIHardware fullScreenApplicationContentRect ]
];
CGRect windowRect =
[ UIHardware fullScreenApplicationContentRect ];
windowRect.origin.x = windowRect.origin.y = 0.0f;
mainView = [ [ UIView alloc ] initWithFrame: windowRect ];
[ window setContentView: mainView ];
[ window orderFront: self ];
[ window makeKey: self ];
[ window _setHidden: NO ];
}
@end
main( ) function is called, just as in a regular C program. This hooks into Objective-C land and instantiates an application class named MyApp, which is derived from UIKit's UIApplication class. The UIView class itself is merely a base class, it didn't actually display anything. To create a useful application, a new class can be derived from UIView, allowing its methods to be overridden to add functionality. This controlling view can then display other objects, such as text boxes, images, etc.UIView, write a new interface and implementation declaring the subclass. The following snippet creates a subclass named MainView:
@interface MainView : UIView
{
}
- (id)initWithFrame:(CGRect)rect;
- (void)dealloc;
@end
UIView class methods should be overridden. The initWithFrame method is called when the view is first instantiated and is used to initialize the view class. A display region is passed in to define its coordinates (offset to its parent) and size it should display as. Any code that initializes variables or other objects can go into this method. The second method, dealloc, is called when the UIView object is disposed of. Any resources previously allocated within your class should be released here.
@implementation MainView
- (id)initWithFrame:(CGRect)rect {
if ((self == [ super initWithFrame: rect ]) != nil) {
/* Initialize member variables here */
/* Allocate initial resources here */
}
return self;
}
- (void)dealloc
{
/* Deallocate any resources here */
[ self dealloc ];
[ super dealloc ];
}
@end
UIView class, you've got everything you need to write an application that does something—albeit a mostly useless something. In the tradition of our ancestors, we now present the official useless "Hello, World!" application.
$ arm-apple-darwin-gcc -o MyExample MyExample.m -lobjc \
-framework CoreFoundation -framework Foundation -framework UIKit
#import <CoreFoundation/CoreFoundation.h>
#import <UIKit/UIKit.h>
#import <UIKit/UITextView.h>
@interface MainView : UIView
{
UITextView *textView;
}
- (id)initWithFrame:(CGRect)frame;
- (void)dealloc;
@end
@interface MyApp : UIApplication
{
UIWindow *window;
MainView *mainView;
}
- (void)applicationDidFinishLaunching:
(NSNotification *)aNotification;
@end
#import "MyExample.h"
int main(int argc, char **argv)
{
NSAutoreleasePool *autoreleasePool = [
[ NSAutoreleasePool alloc ] init
];
int returnCode = UIApplicationMain(argc, argv, [ MyApp class ]);
[ autoreleasePool release ];
return returnCode;
}
@implementation MyApp
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
window = [ [ UIWindow alloc ] initWithContentRect:
[ UIHardware fullScreenApplicationContentRect ]
];
CGRect rect = [ UIHardware fullScreenApplicationContentRect ];
rect.origin.x = rect.origin.y = 0.0f;
mainView = [ [ MainView alloc ] initWithFrame: rect ];
[ window setContentView: mainView ];
[ window orderFront: self ];
[ window makeKey: self ];
[ window _setHidden: NO ];
}
@end
@implementation MainView
- (id)initWithFrame:(CGRect)rect {
if ((self == [ super initWithFrame: rect ]) != nil) {
textView = [ [ UITextView alloc ] initWithFrame: rect ];
[ textView setTextSize: 18 ];
[ textView setText: @"Hello, World!" ];
[ self addSubview: textView ];
}
return self;
}
- (void)dealloc
{
[ self dealloc ];
[ super dealloc ];
}
@end
UITextView class is based on a UIView, however, its functionality has been extended to present and allow editing of text, provide scrolling, and handle various fonts and colors. Text views can be easily abused, and are only recommended for text-based portions of an application, such as an electronic book, notes section of a program, or informational page to present unstructured information.UITextView object inherits from UIScroller, which is a generic scrollable class. This means that the text view itself comes pre-equipped with all scrolling functionality, so the developer can focus on presenting content rather than programming scroll bars. The UIScroller class inherits from UIView, which, as discussed in the last section, is the base class for all view classes.UITextView is ultimately derived from UIView, it is created in the same fashion as the main view objects created in the last section—using an initWithFrame method.
UITextView *textView = [ [ UITextView alloc ]
initWithFrame: viewRect ];
[ textView setEditable: YES ];
[ textView setMarginTop: 20 ];
[ textView setTextSize: 12 ];
[ textView setTextFont: @"font-family: Helvetica; font-style: italic; font-weight: bold" ];
initWithFrame method—just like a UIView.
UINavigationBar *navBar = [ [UINavigationBar alloc]
initWithFrame: CGRectMake(0, 0, 320, 48)
];
0x0 (the upper-left corner of its parent view). This is the general convention, but a navigation bar can be created anywhere within the window. By using a different vertical offset, you can place the navigation bar at the bottom of the window or underneath another navigation bar.self, you can have it send events such as button presses to the object that created the navigation bar.[ navBar setDelegate: self ];
enableAnimation uses these smoother transitions instead of an instantaneous change.[ navBar enableAnimation ];
UIView, so they have most of the properties of a regular view, including a frame. To create a transition, the display region belonging to the view is passed to the transition's initWithFrame method.
UITransitionView *transitionView = [ [ UITransitionView alloc ]
initWithFrame: viewRect ];
UITransitionView *transitionView = [ [ UITransitionView alloc ]
initWithFrame:
CGRectMake(viewRect.origin.x, viewRect.origin.y + 48.0,
viewRect.size.width, viewRect.size.height − 48.0
];
[ self addSubview: transitionView ];
transition method. You'll supply the transition style and pointers to the two views between which you are transitioning.[ transitionView transition: 0 fromView: myOldView toView: myNewView ];
[ transitionView transition: 0 toView: myNewView ];
UIView objects, using an initWithFrame method. Because alert sheets appear at the bottom, the window's origin can begin halfway down the screen (Y = 240).
UIAlertSheet *alertSheet = [ [ UIAlertSheet alloc ]
initWithFrame: CGRectMake(0, 240, 320, 240) ];
[ alertSheet setTitle:@"Computer doesn't like people" ];
[ alertSheet setBodyText: [ NSString stringWithFormat:
@"I did not complete your request because I don't like humans." ]
];
[ alertSheet setDelegate: self ];
Style | Description |
|---|---|
0 | Default style, gray gradient background with white text |
1 | Solid black background with white text |
2 | Transparent black background with white text |
setAlertSheetStyle.[ alertSheet setAlertSheetStyle: 0 ];
UITable class to display their lists of items. In addition to being a basic list selector, the UITable class includes built-in functionality to add disclosures, swipe-to-delete, animations, labels, and even images.UITable object to create a new class for your data. In the following example, a subclass named MyTable is created. The base class methods used to initialize and destroy the object are overridden to provide the table portion of the class:
@interface MyTable : UITable
{
}
-(id)initWithFrame:(struct CGRect)rect;
-(void) dealloc;
numberOfRowsInTable and cellForRow. Because the table is acting as its own data source, you must write these methods into your subclass, where the methods will be responsible for returning column and row data for the table.
- (int)numberOfRowsInTable:(UITable *)_table;
- (UITableCell *)table:(UITable *)table
cellForRow:(int)row
column:(UITableColumn *)col;
UIApplication and UIHardware classes.setStatusBarMode methods can be used from within the instance of your application, a UIApplication object.
- (void)setStatusBarMode:(int)mode duration:(float)duration
- (void)setStatusBarMode:(int)mode orientation:(int)orientation
duration:(float)duration
- (void)setStatusBarMode:(int)mode orientation:(int)orientation
duration:(float)duration fenceID:(int)fenceID
- (void)setStatusBarMode:(int)mode orientation:(int)orientation
duration:(float)duration fenceID:(int)fenceID
animation:(int)animation;
Mode | Description |
|---|---|
0 | Default, white status bar |
1 | Black transparent status bar |
2 | Removes status bar image entirely (be sure to also use _setStatusBarSize) |
3 | Solid black status bar |
4 | Entirely transparent status bar |
5 | Flashing green status bar with "Touch to return to call" text |
6 | Red transparent status bar |
Angle | Description |
|---|---|
0 | Status bar is displayed at the natural top of the iPhone |
90 | Status bar is displayed in landscape across the right portion of the screen |
−90 |
UIApplication class.[ UIApp setApplicationBadge: @"Hi!" ];
setApplicationBadge method takes an NSString object, which can be built with standard string formatting.
NSString *badgeText = [ [ NSString alloc ]
initWithFormat:@"%d", numNewMessages ];
[ UIApp setApplicationBadge: badgeText ];
[ transitionView transition: 0 toView: missedCalls ]; [ UIApp removeApplicationBadge ];
removeApplicationBadge in the application's applicationWillTerminate method.
- (void)applicationWillTerminate {
/* We are about to exit, so remove the application badge */
[ UIApp removeApplicationBadge ];
}
UIApplication base class contains many functions for application state changes, which can be overridden by the application. While there's nothing the application can generally do about the state it's about to enter, it can at least take whatever actions are appropriate to prepare for it.applicationWillSuspendUnderLockapplicationWillSuspendForEventsOnlyapplicationWillSuspendUnderLock method is overridden, this method gets called instead.applicationSuspend