Monday, 18 February 2013

Core Application Architecture | iPhone Apps Tutorial pdf

Core Application Architecture

From the time your application is launched by the user, to the time it exits, the UIKit framework manages the majority of the application’s key infrastructure. An iPhone application receives events continuously from the system and must respond to those events. Receiving the events is the job of the UIApplication object but responding to the events is the responsibility of your custom code. In order to understand where you need to respond to events, though, it helps to understand a little about the overall life cycle and event cycles of an iPhone application. The following sections describe these cycles and also provide a summary of some of the key design patterns used throughout the development of iPhone applications.

=> The Application Life Cycle

The application life cycle constitutes the sequence of events that occurs between the launch and termination of your application. In iPhone OS, the user launches your application by tapping its icon on the Home screen.
Shortly after the tap occurs, the system displays some transitional graphics and proceeds to launch your application by calling its main function. From this point on, the bulk of the initialization work is handed over to UIKit, which loads the application’s user interface and readies its event loop. During the event loop, UIKit coordinates the delivery of events to your custom objects and responds to commands issued by your application. When the user performs an action that would cause your application to quit, UIKit notifies your application and begins the termination process.
Figure depicts the simplified life cycle of an iPhone application. This diagram shows the sequence of events that occur from the time the application starts up to the time it quits. At initialization and termination, UIKit sends specific messages to the application delegate object to let it know what is happening. During the event loop, UIKit dispatches events to your application’s custom event handlers. Handling initialization and termination events is discussed later in “Initialization and Termination” (page 30), and the event handling process is introduced in“The Event-Handling Cycle” .
                                               Fig: Application life cycle
The Main Function
In an iPhone application, the main function is used only minimally. Most of the actual work needed to run the application is handled by the UIApplicationMain function instead. As a result, when you start a new application project in Xcode, every project template provides an implementation of the standard main function like the one in “Handling Critical Application Tasks.” The main routine does only three things: it creates an autorelease pool, it calls UIApplicationMain, and it releases the autorelease pool. With few exceptions, you should never change the implementation of this function.
The main function of an iPhone application
#import <UIKit/UIKit.h>
int main(int argc, char *argv[])
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
int retVal = UIApplicationMain(argc, argv, nil, nil);
[pool release];
return retVal;
}
Note: An autorelease pool is used in memory management. It is a Cocoa mechanism used to defer the release of objects created during a functional block of code. For more information about autorelease pools, see Memory Management Programming Guide for Cocoa. For specific memory-management guidelines  related to autorelease pools in iPhone applications.
The UIApplicationMain function at the heart of the preceding listing takes four parameters and uses them to initialize the application. Although you should never have to change the default values passed into this function, it is worth explaining their purpose in terms of starting the application. In addition to the argc and argv parameters passed into main, this function takes two string parameters that identify the principal class (that is, the class of the application object) and the class of the application delegate. If the value of the principal class string is nil, UIKit uses the UIApplication class by default. If the value of the application delegate’s class is nil, UIKit assumes that the application delegate is one of the objects loaded from your application’s main nib file (which is the case for applications built using the Xcode templates). Setting either of these parameters to a non-nil value causes the UIApplicationMain function to create an instance of the corresponding class during application startup and use it for the indicated purpose. Thus, if your application uses a custom subclass of UIApplication (which is not recommended, but certainly possible), you would specify your custom class name in the third parameter.

The Application Delegate
Monitoring the high-level behavior of your application is the responsibility of the application delegate object, which is a custom object that you provide. Delegation is a mechanism used to avoid subclassing complex UIKit objects, such as the default UIApplication object. Instead of subclassing and overriding methods, you use the complex object unmodified and put your custom code inside the delegate object. As interesting events occur, the complex object sends messages to your delegate object. You can use these “hooks” to execute your custom code and implement the behavior you need.
The application delegate object is responsible for handling several critical system messages and must be present in every iPhone application. The object can be an instance of any class you like, as long as it adopts the UIApplicationDelegate protocol. The methods of this protocol define the hooks into the application life cycle and are your way of implementing custom behavior. Although you are not required to implement all of the methods, every application delegate should implement the methods described in “Handling Critical Application Tasks”.

The Main Nib File
Another task that occurs at initialization time is the loading of the application’s main nib file. If the  application’s information property list (Info.plist) file contains the NSMainNibFile key, the UIApplication object loads the nib file specified by that key as part of its initialization process. The main nib file is the only nib file that is loaded for you automatically; however, you can load additional nib files later as needed.
Nib files are disk-based resource files that store a snapshot of one or more objects. The main nib file of an iPhone application typically contains a window object, the application delegate object, and perhaps one or more other key objects for managing the window. Loading a nib file reconstitutes the objects in the nib file, converting each object from its on-disk representation to an actual in-memory version that can be  manipulated by your application. Objects loaded from nib files are no different than the objects you create programmatically.
For user interfaces, however, it is often more convenient to create the objects associated with your user interface graphically (using the Interface Builder application) and store them in nib files rather than create them programmatically.

=> The Event-Handling Cycle

After the UIApplicationMain function initializes the application, it starts the infrastructure needed to manage the application’s event and drawing cycle, which is depicted in Figure. As the user interacts with a device, iPhone OS detects touch events and places them in the application’s event queue. The event-handling infrastructure of the UIApplication object takes each event off the top of this queue and delivers it to the object that best suited to handle it. For example, a touch event occurring in a button would be delivered to the corresponding button object. Events can also be delivered to controller objects and other objects indirectly responsible for handling touch events in the application.
                                                    Fig: The event and drawing cycle
In the iPhone OS Multi-Touch event model, touch data is encapsulated in a single event object (UIEvent).
To track individual touches, the event object contains touch objects (UITouch), one for each finger that is touching the screen. As the user places fingers on the screen, moves them around, and finally removes them from the screen, the system reports the changes for each finger in the corresponding touch object.
When it launches an application, the system creates both a process and a single thread for that application. This initial thread becomes the application’s main thread and is where the UIApplication object sets up the main run loop and configures the application’s event-handling code. Figure shows the relationship of the event-handling code to the main run loop. Touch events sent by the system are queued until they can be processed by the application’s main run loop.
                              Fig: Processing events in the main run loop
 Note: A run loop monitors sources of input for a given thread of execution. When an input source has data to process, the run loop wakes up the thread and dispatches control to the handler for that input source.
When the handler finishes, control passes back to the run loop, which processes the next event or puts the thread to sleep if there is nothing more to do. You can install your own input sources, including ports and timers, on a run loop using the NSRunLoop class of the Foundation framework. For more on NSRunLoop and run loops in general, see Threading Programming Guide.
The UIApplication object configures the main run loop with an input source that processes touch events by dispatching them to the appropriate responder objects. A responder object is an object that inherits from the UIResponder class and that implements one or more methods for processing the different phases of a touch event. Responder objects in an application include instances of UIApplication, UIWindow, UIView, and all UIView subclasses. The application typically dispatches events to the UIWindow object representing the application’s main window. The window object, in turn, forwards the event to its first responder, which is typically the view object (UIView) on which the touch took place.
In addition to defining the methods you use to handle events, the UIResponder class also defines the programmatic structure of the responder chain, which is the Cocoa mechanism for cooperative event handling. The responder chain is a linked series of responder objects in an application, which usually starts at the first responder. If the first responder object cannot handle the event, it passes it to the next responder in the chain. The message continues traveling up the chain toward higher-level responder objects such as the window, the application, and the application’s delegate until the event is handled. If the event isn't handled, it  is discarded.
The responder object that handles the event tends to set in motion a series of programmatic actions that result in the application redrawing all or a portion of its user interface (as well as other possible outcomes, such as the playing of a sound). For example, a control object (that is, a subclass of UIControl) handles an event by sending an action message to another object, typically the controller that manages the current set of active views. While processing the action message, the controller might change the user interface or adjust the position of views in ways that require some of those views to redraw themselves. When this happens, the view and graphics infrastructure takes over and processes the required redraw events in the most efficient manner possible.

=> Fundamental Design Patterns

The design of the UIKit framework incorporates many of the design patterns found in Cocoa applications in Mac OS X. Understanding these design patterns is crucial to creating iPhone applications, so it is worth  taking a few moments to learn about them. The following sections provide a brief overview of these design patterns.
                       Table : Design patterns used by iPhone applications

No comments: