1. iOS Frameworks

Everyone seems to have an opinion as to why their favorite mobile platform is better than the others. Some prefer iOS, others choose Android—each platform has its pros and cons. For me, however, iOS stands above the rest in large part due to its use of powerful native frameworks.

Sure, frameworks and libraries are not unique to iOS. But the scope, diversity, power, and simplicity of iOS frameworks is something I have yet to find in other platforms. Frameworks like Core Animation and Quartz Core make complicated animation effects simple and efficient in terms of power consumption, memory management, high frame rate, and so on. Core Location provides easy access to complicated GPS hardware with only a few lines of code. In short, these frameworks and others allow developers to rapidly produce the feature-rich apps users have come to expect.

Before We Begin

When it comes to iOS apps, it doesn’t matter if you’re a new developer whose crowning achievement is a simple coin-flip app, or an experienced developer who’s creating the next Flipboard. If you develop apps for iOS you’ve used frameworks, whether you were aware of it or not.

At a high level, frameworks provide access to low level services through system APIs. These services can range from the creation and management of simple runtime objects like arrays, strings, buttons, and text fields to lower hardware access of cameras, motion accelerometers, and GPS.

Frameworks are a defining characteristic that make a computer program an app for iOS. At the end of the day, all iOS apps are based on and executed in an Objective-C runtime environment. Code in this environment can be written with a mixture of C, C++, and Objective-C, but to execute a binary in iOS and run an app on the iPhone or iPad, that app must ultimately interact with iOS frameworks.


image Note

Because OS was built on the foundation of Mac OS X, many of the native frameworks carry over with very little loss in performance or function, giving you the power of a desktop platform on a mobile device.


Before we begin, you should know my assumptions and expectations about your background in iOS development. The last thing I want is for you to get half way through this book and realize it’s not what you were looking for, or even worse, to reach the end and wish there were more. So let’s take a step back and cover some prerequisites, followed by a look at my goals for this book.

Prerequisites

In iOS there are two frameworks that are absolutely essential, Foundation and UIKit. This book covers Apple developed frameworks throughout the iOS architecture including frameworks in the Cocoa Touch layer, Media layer, and Core Services layer. Because Foundation and UIKit are so essential to even the simplest iOS apps, I’m assuming a basic understanding of how these frameworks operate. This enables us to spend more time on the frameworks that will give your app an edge—taking advantage of the power of iOS to make your app unique.

Because Foundation and UIKit define the base classes for all objects in iOS, it’s impossible to develop an app that executes in the iOS runtime without them. For this reason, when a new iOS project is created in Xcode, these frameworks are automatically included by default.

iOS can be broken down into four primary layers (Figure 1.1). These layers are: Cocoa Touch, Media, Core Services, and Core OS. Frameworks are scattered throughout these layers with UIKit controlling user interface in the Cocoa Touch layer and Foundation controlling the base object in the Core Services layer. As mentioned before, iOS was born out of Mac OS X. To that end, the bottom three layers in this architecture are actually very similar on Mac OS X and in iOS.

Image

Figure 1.1. iOS system architecture showing the separation of the Cocoa Touch, Media, Core Services, and Core OS layers.


image Note

Because Mac OS X and iOS are so similar, especially with iOS 5 and OS X Lion, Apple made it much easier to move code between the two. Recognize that you’ll need to recode the top Cocoa Touch layer when porting applications to Mac.


Additionally, it’s important to understand the distinction between Foundation and UIKit. Remember, Foundation is used to define all objects in iOS inherited from the root class, NSObject. Foundation also defines the protocols for creating, managing, and releasing objects in memory. All basic User Interface (UI) elements are defined in UIKit. As a general rule of thumb, if an object relates to displaying information to the user, it’s defined in UIKit or Cocoa Touch; otherwise, all base classes and protocols are defined in Foundation.

My Goals for This Book

Instagram, Flipboard, foursquare, Facebook, and Twitter—all of these apps on the iPhone and iPad have at least one thing in common. They all take advantage of frameworks in iOS. It’s my goal in this book to teach you how to incorporate common features found in these popular apps by using native iOS frameworks. Each chapter focuses on a specific framework, beginning with a broad overview designed to teach through narrative and short examples. The second half of each chapter includes longer, more specific code samples designed to help you with common use cases.

The primary teaching material in this book will not be code samples. Instead of presenting you with page after page of specific code examples for various use-case scenarios, I use the code as a part of the teaching narrative. My goal is to explain the fundamentals of the iOS frameworks covered so that you can take the examples provided, learn from them, and expand them further to more complicated scenarios as needed. It’s my feeling that when reading a book like this one, the reader should feel like they have a one-on-one with the author, with teaching and learning throughout.

That being said, this book will consistently teach by example, and a large percentage of each chapter will focus on code demonstrating the most common uses of the various frameworks covered. All of the code examples from this book are available free for download at iOSCoreFrameworks.com in full project form.

By the end of this book you should be able to create your own Instagram-style photo effects, Flipboard-style page-turn animations, foursquare-like location awareness, or Twitter-like single sign-on app experience using native frameworks in iOS. Of course, if I can help you make the next five-star, multi-million dollar app and you are generally happier after reading this book, that’s always good, too.


image Tip

If you get stuck at any point during this book, or need help taking an example project just a little bit further, feel free to reach out to me through the contact page at iOSCoreFrameworks.com/contact or on Twitter @shawnwelch.


iOS Frameworks Crash Course

So what is a framework?

In iOS, a framework is a library of classes (either Objective-C or C) that extends the capabilities of your project or app. At a high-level, you can think of a framework as pre-written modular code that you can include in your project to easily gain access to various services, APIs, and physical hardware available in iOS.

To put it another way, imagine if fiction and nonfiction were housed in separate buildings at the public library. When you get a new library card, you might only have access to the fiction library, much like iOS apps have access to UIKit and Foundation by default. To consult works in the nonfiction section, you would have to ask the help desk to include access to the nonfiction library on your card. Similarly, before you can use many of the additional frameworks in iOS, you must first include them in your projects (Figure 1.2).

Image

Figure 1.2. iOS apps must link to additional frameworks to take advantage of their services. Here, the Photoshop World app links to Core Location in the Core Services layer to gain location awareness.

As mentioned in the previous section, only the Foundation and UIKit frameworks are required when developing iOS applications. Because of this, Xcode imports these two framework libraries by default. All other frameworks add additional functionality beyond the most basic app and you must take a few extra steps to include these frameworks in your projects.


image Note

By default, Xcode will also import the Core Graphics framework to your project in most iOS project templates. We’ll cover the reasoning behind this decision by Apple engineers in Chapter 6, Core Graphics.


The following procedure outlines how to link the libraries of a new framework to your Xcode project. This particular example demonstrates how to add the Quartz Core framework, which is required for Core Animation effects. You can refer back to this same procedure to link other libraries such as Core Data, Core Location, or Core Image.

To Link New Frameworks in an Xcode Project:

1. Start by selecting your project at the root of your project hierarchy in Xcode’s left navigation. Next, in your right pane, select your target and then select the Build Phases section (Figure 1.3).

Image

Figure 1.3. List of linked framework libraries in Xcode.

2. Click the drop-down arrow just to the left of the label Link Binary With Libraries to expand the list of all libraries currently linked to your project.


image Note

Libraries are organized by the iOS base SDK (Software Development Kit). Be sure to select the framework listed in the same base SDK as your project. For example, if you develop a backwards compatible app for iOS 4, do not add frameworks listed in the iOS 5 base SDK. Similarly, if you upgrade an old project to a new base SDK, you should relink the libraries to match.


To add a new library, click the Plus button (also known as the Add button) located in the bottom left of this opened panel. Then, select the framework from the list (for this example, select QuartzCore.framework) and click the Add button (Figure 1.4).

Image

Figure 1.4. Linking a new framework library to your project in Xcode.

3. After you link Quartz Core to your project, you need to import that library in the header (.h) files of classes that implement APIs from the Quartz Core framework. In this case, include the following line of code in the corresponding header files so that the source files will take advantage of Core Animation.

1   #import <QuartzCore/QuartzCore.h>


image Tip

You can automatically import a library in all of the source files of your project by adding the import to the prefix header of your project. To do this, simply add the same import function to the Prefix.pch file located in the Other Sources folder of your project hierarchy.


Understanding the Impact of a Multicore Processor

Before we get to frameworks, however, I want to take a second to talk about one of the changes that has been happening in iOS devices over the last few releases.  That change is the multicore processor. As a developer of mobile apps, one of your primary responsibilities is to optimize performance. The better your performance, the more positive the user experience. Sure Angry Birds is addictive, but you can imagine how people would have reacted if the first version was choppy and the birds stuttered across the screen because of a low frame rate? What if your favorite Twitter app locked up every time you tried to see your @ replies because it was downloading the most recent data on the main application thread?

Resources are scarce on mobile devices, so it becomes incredibly important to design your apps to be efficient and elegant. Recently, Apple has started including multicore processors or CPUs in new iOS devices like the iPad 2 and iPhone 4S, both featuring the A5 chip. Unless an app is optimized to take advantage of a multicore processor, that app and all of its processes will be isolated on a single processor. When an app is isolated on a single processor, it is effectively wasting the processing power of the other processors available. While the iPad 2 and iPhone 4S are the only multicore iOS devices, more will be coming (the current generation Mac Pro desktop computers can have up to 12 cores.)

In recent years Apple paid special attention to the needs of developers and built fantastic services for effectively handling concurrency across multiple CPUs directly into the Core Services layer of iOS and Mac OS X. These services are ingrained in the building blocks of many core frameworks on iOS. Because these frameworks are fundamentally dependent on concurrency, a large portion of their APIs must also be implemented with concurrency in mind. Specifically, much of your interaction with some of the newer iOS 5 framework changes will involve both blocks and queues—but more on that later.

The Need for Concurrency

You know that multithreading allows for multiple threads of a single program to work together simultaneously and asynchronously toward a common goal. Imagine trying to download a large file from the Internet. Without multithreading, your computer would lock up when the download starts because the main application thread is busy downloading that file. This sounds obvious, but one of the common pitfalls for new iOS developers is trying to download information or allocate large objects in the tableView:didSelectRowAtIndexPath: method of a table view controller before pushing a new view controller on the navigation stack. The outcome of doing this task on the main thread is a lag in the user experience. For a brief moment, the table view controller is non-responsive while the application finishes the long loading task.

With multithreading, you can fork off a separate thread to handle the download process and update your main UI periodically. Alternatively, you can show a spinner in the table view controller indicating progress, while the app is busy allocating the next view controller. This way, the main application thread never locks up and the UI stays responsive.

Operation Queues vs. Dispatch Queues

To help lighten the workload of developers, Apple has built two key technologies directly into iOS and Mac OS X: operation queues and dispatch queues.

An operation queue is an object-oriented approach using an Objective-C wrapper. Essentially, you have a queue object (NSOperationQueue) that holds multiple operations (NSOperation, NSBlockOperation, NSInvocationOperation) that are executed according the the queue’s configuration. The operation queue object automatically handles the execution and management of the operations it contains.

A dispatch queue is actually a C-based solution using a newer central service called Grand Central Dispatch (GCD). GCD is like a hub or dispatch station for multiple operations across multiple processors built on top of the Core Services layer. When GCD dispatches a new thread, it selects which processor is most suited for that task at that time based on current resources available. Using GCD, you can set up three different types of queues:

Serial: Tasks are performed sequentially in the order they’re added, one right after the other. The next task in the queue doesn’t start until the previous task has finished. This can be very useful if you’re performing an operation like downloading a file from the Internet, and then writing or reading that file to memory. For example, you wouldn’t want to attempt to write the file until it completed download.

Concurrent: Tasks are performed in the order they’re added but can start before the next task is finished depending on the resources available at that time. This could be useful if you’re performing a series of operations such as applying the filters to multiple images. There’s no need to wait until the current image is finished processing before you start working on the next one. If GCD feels there’s sufficient resources to begin a second task, it will do so automatically.

Main Dispatch Queue: This queue is the same as the main application loop. Remember that when you perform multithreaded operations, your UI should only be modified in the main application thread. This helps guarantee that no user input is ignored by a background thread. For this reason, if you’re in a secondary queue and need to perform an action on the main thread, you can add a task to the main dispatch queue and it will be executed within the main application runtime loop.

The great thing about GCD is that it’s integrated tightly into iOS and Mac OS, directly in the Core Services layer (Figure 1.1). Because GCD is built into the DNA of the fundamental iOS operating system, the native iOS frameworks take full advantage of multicore hardware configurations by default. Further, applications designed to run through GCD will often see an instant boost in performance, simply by running on a multicore system. There’s no loss in performance by using GCD on a single-core system, rather there are only gains from the multicore system.

Blocks

As mentioned, GCD and NSOperationQueues function as thread managers, automatically creating and closing threads according to their respective queue configurations. They’re very hands off, and very efficient. Instead of developing and managing multiple threads yourself using methods and selectors, use a dispatch queue or an NSBlockOperation to pass a block to a corresponding queue—and let iOS take care of the rest.


image Tip

While using blocks is a requirement for GCD, because NSOperationQueue is object-oriented you can actually subclass NSOperation and create your own separate operation class.


The following example demonstrates a simple block. Blocks are very useful when you need to create simple threads. Instead of managing a weak delegate relationship between various living objects in the iOS runtime, blocks are simply submitted to an operation queue or dispatched using GCD.

1   NSString *demo = @"Hello";
2   //Set up the block
3   void (^helloBlock)(NSString*) = ^(NSString* param){
       NSLog(@"%@, %@", demo, param);
    };
4
5   helloBlock(@"Block");

In this example, line 1 sets up a simple NSString variable: demo. In line 3 we define a new block. And finally, in line 5 we execute the block by referencing its function name. When this code is executed, the result will be the string “Hello, Block” output to the console.


image Note

This example demonstrates how to execute a block directly. In this case, the block is not executed as part of a queue so neither GCD nor NSOperation is involved. In the next section we’ll demonstrate using a block in combination with a queue and the Core Motion framework.


So what’s really going on here? Notice that the definition of the block in line 3 only takes up one line. More importantly, notice that the line is terminated with a semicolon (;). In this example, we create and define a function as a block. Unlike selectors, this function is defined within the method structure just like any other instance variable.

In line 3 notice there’s an equals sign. The left operand of this equation, void (^helloBlock)(NSString*), defines the form of our block just like NSString defines the form of the variable demo. The right operand of this equation, ^(NSString* param){...}, adheres to the form established on the left and defines the actual function itself. So, on the left-hand side we say that the function helloBlock will have a single NSString* input parameter with a void return. On the right-hand side, we establish the function and then fill in the actual heavy lifing between the braces ({...}).

Next, let’s walk through how this code actually executes. Note, the numbers in the following illustration indicate the step of the program, not the line number of the code sample.

1. Create a new NSString variable, demo, storing the value “Hello.”

2. Define a block with function name helloBlock.

3. Execute the block function helloBlock with the parameter “Block.”

4. Execute the NSLog statement contained within the braces of the block helloBlock, and print “Hello, Block” to the console.

Using Blocks in iOS Frameworks

A great example of using blocks in conjunction with iOS frameworks is while interacting with the gyroscope through Core Motion. Consider what’s at play here. It’s inefficient to write a piece of code that periodically queries the gyroscope to retrieve the most recent data. Similarly, using the traditional delegate method—to have the gyroscope itself call a selector in our controller—is just too heavy. While these cases might work if we wanted to ping the gyroscope every few seconds, an accurate motion sampling requires anywhere from 20 times to 60 times per second, so our solution needs to be very lightweight.

This is where blocks and operation queues come in handy. The Core Motion framework has a class called CMMotionManager. This manager can be configured with a frequency and block handler. The handler is simply a block that will be dispatched in the provided operation queue. Every time the CMMotionManager is due for an update, it references the defined handler block and dispatches a process through GCD.

1   gyroHandler = ^ (CMGyroData *gyroData, NSError *error) {
2     CMRotationRate rotate = gyroData.rotationRate;
3     up.transform = CGAffineTransformMakeScale(rotate.y, 1);
4   };

In lines 1 through 4, we have defined a simple block. Unlike our previous example, instead of setting this block up as a function that can be called, we’re assigning the right-hand operand to a variable called gyroHandler. When the time comes, we’ll pass this gryoHandler to our CMMotionManager.

 1   motionManager = [[CMMotionManager alloc] init];
 2   motionManager.gyroUpdateInterval = 1.0/60.0;
 3   if (motionManager.gyroAvailable) {
 4     opQ = [[NSOperationQueue currentQueue] retain];
 5     gyroHandler = ^ (CMGyroData *gyroData, NSError *error) {
 6       CMRotationRate rotate = gyroData.rotationRate;
 7       up.transform = CGAffineTransformMakeScale(rotate.y, 1);
 8     };
 9   }
10   else{
11     NSLog(@"No gyroscope on device.");
12     [motionManager release];
13   }
14   [motionManager startGyroUpdatesToQueue:opQ
                                withHandler:gyroHandler];

In this code block, lines 1 and 2 allocate our CMMotionManager and set the update frequency—in this case, our gyroscope will update 60 times per second. In line 3 we check to see if the gyroscope is available. If it is, we create an operation queue in line 4, define our gyroHandler block in lines 5 through 8, and then a start the gyroscope updates in line 14.

As you can see, we do not need to set up separate delegate methods to handle a gyroscopeDidChange event, or something similar. You can see in line 7 we adjust the transform of a UIView based on the gyroscope’s rotation data. Every time the motion manager dispaches a new block, this code executes and our view updates.

The iOS 5 Top Ten Technologies

This book will focus on what I see as the Top Ten Technologies of iOS 5. Accessed through various frameworks throughout the iOS architecture, these ten technologies will bring your apps to the next level by giving you access to some of the best that iOS has to offer. We’ll start in the lower levels of the iOS architecture, focusing on data-oriented technologies, and slowly move our way up through the Media layer covering technologies that provide a rich user experience. Finally, we’ll finish off with a new application type available in iOS 5, Newsstand Apps.

Starting with the Core Services layer and working our way up to the application layer, in my eyes, the Top Ten Technologies in iOS 5 are

1. Core Data: Used to provide easy access to persistent data stores of your application model.

2. iCloud: A cloud-based storage system that automatically manages content synchronization, document storage, and data merging (with automatic conflict resolution).

3. Core Location: Provides access to location services including forward and reverse geocoding of location data. New to iOS 5, Core Location now includes region monitoring allowing your app to generate notifications when a user enters and exits a specified region.

4. Accounts/Twitter: New to iOS 5, Apple has included the APIs needed to access a centralized accounts database stored in the protected file system. Using the Accounts framework in combination with the new Twitter framework, developers can provide a single sign-on experience with Twitter services, letting iOS automatically handle the complex OAuth workflows.

5. Core Graphics: Core Graphics is essential when creating custom UI elements. Using Core Graphics you can draw custom user interface elements giving your app a unique look-and-feel.

6. Core Image: Starting out as a powerful image processing and analysis library on Mac OS X, Core Image is now available on iOS providing you access to professional quality image editing filters and operations. Additionally, Core Image lets you easily analyze images using face detection algorithms or automatic image enhancement.

7. Core Animation: Core Animation (Quartz Core) has been at the heart of the superfluous animation effects available on iOS since day one. New to iOS 5, however, comes the unique ability to create particle emitters for even more impressive animation effects.

8. Core Audio: Audio adds an intangible aspect to your apps that helps users connect with their data or your game. By using audio effectively, you draw users into your app, providing the best user experience possible.

9. AV Foundation: AV Foundation is the backbone of most high-level audio and video operations. By implementing AV Foundation directly, however, you have more access to your video data than ever before. Using AV Foundation you can incorporate other technologies mentioned previously to build in-camera effects and real-time processing of data.

10. Newsstand Kit: New to iOS 5, Newsstand apps are designed to bring periodical content to a user’s doorstep. Using the new Newsstand Kit, you can create a special class of application that automatically downloads new content providing users with offline access.

Wrapping Up

This book sets out to teach you how to use native iOS frameworks in your apps. But taking that one step further, I want you to come out on the other side of this book with an understanding of how these frameworks work, not just how to copy and paste code into your apps. iOS frameworks are remarkably consistent. Once you have a firm grasp of how one works, you’ll be able to transfer knowledge into how others work.

Remember that iOS frameworks, specifically those new to iOS 5, are built from the ground up with multicore processors in mind. Because of this, many of your interactions with these new frameworks will be based on Grand Central Dispatch (GCD) and blocks.

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

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