12. Extensions

Since the dawn of the iOS platform, apps have been sandboxed. Third-party apps could not influence any other app with the exception of some simple URL scheming. With the introduction of iOS 8, Apple has given developers the ability to run code from their apps outside of the sandbox for the first time. Although extensions are limited in functionality, they add a great amount of flexibility to the developer’s tool belt. Six types of extensions are available on the iOS platform (Finder Sync is uniquely OS X), each with its own specific function. This doesn’t include Apple’s choice to use extensions to power WatchKit, which is discussed in the “Apple Watch Extension” section of this chapter.

This chapter covers two of the most popular extensions. The first is a Today widget, which enables the app to post quick at-a-glance information in the Notification Center. The second extension is an Apple Watch Extension, which enables an iOS app to post information and receive feedback to the Apple Watch.

Types of Extensions

Apple has broken out extensions into seven unique types (six of which are available on iOS). Each extension is limited and restricted to protect the user from malicious activity and provides a unique type of functionality. It is possible for a single app to provide more than one type of extension. The types of extensions are detailed in this section.

Today

Today Extensions, often simply referred to as widgets, appear in the Notification Center of an iOS device. They are called Today Extensions because the section of the Notification Center they appear in is the Today area. These widgets are designed to provide quick at-a-glance information or accept a quick action like a button press.

Some developers are already pushing the limits of what Apple intended with Today Extensions. When the popular calculator app PCCalc added a full calculator to the Notification Center through a Today Extension, Apple initially rejected the app, only later reversing their decision due to public outcry.

Share

The Share Extension gives the user an easy and convenient method to share content with other services or Web sites. The extension will add functionality to the built-in share dialog on iOS. For example, if developers were to create a new service that competed with Twitter, they could write an extension into their native iOS app. That extension would allow other apps to share content through the extension directly with their service by appearing directly in the sharing sheet.

Action

An Action Extension helps users view or transform content from the originating app. For example, if you have an app that enables the user to edit a selection of text, a new Action Extension can be created to bring in text from other apps. For example, a developer could write an extension that translated Spanish text into English. An Action Extension must specify the type of data that it is designed to work with such as text, video, or PDFs.

Photo Editing

The Photo Editing Extension enables the user to edit a photo or video within Photos.app. In a sense, this creates a custom modification plug-in that the user can then access from the standard Photo app. For example, a developer could create a Photo Editing Extension that applies a set of custom filters that would become available to the user on his photo library. As with any other changes to images in Photos.app, the original is always saved so that the user can easily revert any changes.

Document Provider

The Document Provider Extension enables a developer to share a custom type of file across multiple apps. The Document Provider Extension stores all these associated files in a shared location. For example, Adobe could release a Photoshop Document Extension, which would enable apps to work with and share PSD documents.

Custom Keyboard

One of the most requested features from iOS users before iOS 8 was to be able to install custom keyboards. The Custom Keyboard Extension does exactly this, and enables users to install third-party keyboards with varying purposes into the system keyboard selector. The Keyboard Extension is limited to inputting data into the user’s selected text field or other text input area.

Understanding Extensions

There are many types of extensions; however, they all share something in common: They allow the execution of functionality inside an app that might not be created by the same developer who made the extension. This is a radical shift from the first six years of iOS development.

Previously, to get functionality like extensions, the user was required to be running a jailbroken device. Apple has made tremendous efforts to ensure that extensions do not cross the line into malware, and in doing so has placed various limitations on developing extensions. To work effectively with extensions, you need to first understand how they function.

Extensions are not standalone apps; they are attached to another app, called the host app, through which the user installs and activates the extension. If the user uninstalls the host app, the extension is removed along with it. Because the extension isn’t a standalone app, it isn’t constantly running in the background; the extension remains unlaunched until the user chooses it from an app’s interface or from a presented activity view controller. The host app defines the parameters of the extension and waits for the user to activate it. After the extension is activated, it performs its duty and then terminates. Extensions are not designed to continue running in the background and performing long processes.

While an extension is running, there is no direct communication between the extension and the containing app. The containing app will pass any information required for the extension to perform its duties upon launch and then wait for the extension to terminate.


Note

An app extension can be run only at the request of a user; there is no way to auto-launch or auto-execute an extension based on the state of the app.


API Limitations

App extensions have limitations that are unique when dealing with iOS development. Many APIs cannot be accessed from within an extension due to security or other concerns:

Image Extensions cannot access sharedApplication or any of the associated methods such as openURL, delegate, applicationState, or accessing push or local notification settings.

Image Apple has also marked certain APIs with the NS_EXTENSION_UNAVAILABLE macro, which will restrict use within an extension. Examples of these APIs include calendar events and HealthKit interaction.

Image An extension might not activate or work directly with the camera or microphone.

Image Extensions might not perform long-running background tasks and are subject to app store rejection or runtime termination for processes that take too long to run in the background.

Image AirDrop is not accessible from within the extension; however, the extension can access data sending through AirDrop via the UIActivityViewController.

Extensions are brand-new technology from both a code standpoint and a user-interaction standpoint. Apple has been known to adapt the rules for their developer technologies on the fly to ensure the best possible user experience.

Creating Extensions

Because extensions are a separate target that belongs to a host app, that new host app must first be created. Extensions can be added to any normal iOS project. To create a new extension in Xcode 6, select File, New, Target. This opens a new window (see Figure 12.1); select Application Extension from the list on the left. The six types of iOS extensions will be presented, so select the type of extension that will be added to your project.

Image

Figure 12.1 Adding a new extension to a project.

Upon creation of the extension, a new group will be created in the project with the extension’s name. This group will contain a class file and an associated storyboard. If a Today Extension was chosen, running the project now will display a Hello World widget to the Notification Center (see Figure 12.2). Each extension has default properties and will show up differently when testing.

Image

Figure 12.2 A Hello World Today Extension running on the iOS Simulator.

When an extension is being run, it is important that the simulator already be running and that your host app has been installed. Failing to do so might result in an error, as shown in Figure 12.3. If an extension fails to load or compiles new source, try cleaning the project and rebuilding the host app and then the extension again.

Image

Figure 12.3 An unable-to-launch-extension error due to the iOS Simulator not being launched.

Today Extension

The first of two sample apps for this chapter will create a Today Extension. ICFToday will be the host app but has no specific functionality itself other than hosting the extension. As for the extension, it will use Yahoo’s Finance API to pull down the most recent ask price for Apple’s Stock and display it to the Notification Center. A refresh button is also provided to demonstrate user action from the Today Extension.

Following the directions from the preceding section, a new project is created and a new Today Extension is added to it. The extension storyboard is set up with a single label to reflect the price of the stock and a single button to force a refresh of the price.

A new method is created by default, widgetPerformUpdateWithCompletionHandler. This method will be called when the Today Extension or Widget is ready to be updated. This usually occurs when the Notification Center is presented for display. Setting a breakpoint on this method will cause it to fire every time Notification Center refreshes or is reloaded. The first thing that needs to be done is to set the dimensions that will be used for the extension; since this is a very small extension it needs a height of only 20 points. The second line of this method performs a call to refresh the stock price.

- (void)widgetPerformUpdateWithCompletionHandler: (void (^)(NCUpdateResult))completionHandler
{
          self.preferredContentSize = CGSizeMake(0, 20);
         [self refreshAction: nil];

         completionHandler(NCUpdateResultNewData);
}

Yahoo provides a simple API to fetch the stock price of any listed company. The URL provided in the following method simply requests the current ask price of the AAPL stock. The results are delivered in a CSV file; however, with only one line item in that file, it can be treated as plain text.

-(NSString *)getStockPrice
{
         NSURL *url = [NSURL URLWithString: @"http://finance.yahoo.com/d/quotes.csv?s=AAPL&f=a"];

         NSError *error = nil;

         NSString *quote = [NSString stringWithContentsOfURL:url encoding:NSASCIIStringEncoding error:&error];

        return quote;
}

Running the extension target will now launch into the Notification Center and display the current asking price for AAPL, as shown in Figure 12.4.

Image

Figure 12.4 Viewing a Today Extension that shows the current stock price for AAPL.

Sharing Code and Information between Host App and Extension

An extension cannot directly communicate with its host app, nor can it share code in the typical sense. In the real world, both of these requirements are often necessary. To share code between the extension and the host app, an embedded framework can be created. The embedded framework can then be referenced from both targets and code can effectively be shared between the host app and the extension.

To create a new framework, select the project in the Project Navigator and add a new target by selecting Editor, Add Target. Select iOS, Framework & Library, and then Cocoa Touch Framework from the prompt window. The Framework can now be added to both targets, and class files can be shared between the extension and the host app.

Often, an extension needs to be able to share data between itself and the host app. Because both targets do not share the same sandbox, they cannot directly interact with each other. However, with the leveraging of another iOS 8 technology, simple data sharing becomes possible.

Apple allows for App Groups that allow a set of apps from the same developer to share limited data. The same technology can be used to share data between an extension and an app. App Groups can be turned on through the capabilities section of the project editor. Sharing NSUserDefaults through App Groups after it’s enabled is as easy as working with NSUserDefaults on older versions of iOS. A new instance of NSUserDefaults is created and stored using the group identifier that was created in the App Groups project settings.

[[NSUserDefaults alloc] initWithSuiteName:@"<group identifier>"];


Note

When you are using App Groups and NSUserDefaults, it is important to remember that NSUserDefaults for both targets still exist and this is different than referencing the shared groups NSUserDefaults. Items saved into each target’s defaults do not automatically become available in the shared defaults.


Apple Watch Extension

The Apple Watch was announced at a special Apple event on September 9, 2014. There had been rumors of an Apple-branded watch for several years before the release. Those rumors were put to bed when Tim Cook showed the first device onstage. Apple has had a history of revolutionizing industries, from the personal computer to MP3 player, smartphones, and tablet computing. Whether the Apple Watch will be the next great technology revolution ushered in by Apple remains to be seen.

Apple has promised two software development rollouts for the Apple Watch. The first WatchKit is available in Xcode 6.2 or newer; the second, a true native SDK, is expected sometime in 2015. This first phase of Apple rolling out Apple Watch app development centers on extensions. The current WatchKit development package works much like a Today Extension, covered earlier in this chapter.


Note

Apple WatchKit Development requires Xcode 6.2 Beta 3 or newer.


To create a new WatchKit project, a host app needs to be first created. Apple has not allowed for standalone apps on the Apple Watch yet. Every third-party app currently allowed on the Apple Watch must be hosted on another external iOS device. The process for adding a WatchKit component to an existing app is the same as for the Today Extension, with the difference of selecting Apple Watch from the template target menu (see Figure 12.5).

Image

Figure 12.5 Creating a new WatchKit app.

Creating the new WatchKit app target will also generate several new files, an InterfaceController and NotificationController, as well as supporting files such as info.plist and asset catalogs. Unlike with a Today Extension, no WatchKit storyboard is created. Running the WatchKit app will produce a blank AppleWatch interface (see Figure 12.6). The interface contains just a clock and power indicator. Create a new storyboard from the Add File menu, and select a WatchKit storyboard from the available options.

Image

Figure 12.6 A WatchKit Extension running on the iOS Simulator.

The WatchKit storyboard contains a whole different set of controls than standard iOS development. Although there are many familiar items to a veteran iOS developer, there is a significant amount of difference in their appearance and behavior. Familiar controls such as labels, tables, and standard controls are available. Some customized controls such as steppers, date display, and date pickers are made available as well.

When you are working with the storyboard file, it will quickly become apparent not only that items snap into position unlike iOS but also that there are no standard autolayout controls. However, this might certainly change as Xcode 6.2 progresses through betas and WatchKit is refined. Instead, WatchKit uses several positioning controls (see Figure 12.7).

Image

Figure 12.7 Positioning controls on WatchKit differ from the standard autolayout approach found on iOS.

Hooking up controls like outlets and actions is identical to standard iOS development practices. In the sample app, a new label and button are created. The only difference is that UILabel is called WKInterfaceLabel on the Apple Watch. The WatchKit simulator has significant lag between interactions and responses. Whether this will carry over to physical devices or is a symptom of the simulator is currently unknown. However, since WatchKit is functioning as an extension that runs on another device, some lag would be expected.

This simple WatchKit app should provide the groundwork required to expand on the interface and functionality with existing iOS development knowledge. The platform, though in its infancy, already provides a lot of functionality and options.


Note

Apple WatchKit Development has been rapidly changing since introduction. The materials in this chapter were written while WatchKit was in early stages of beta. A number of bugs are being worked out in each release, and the material in this section was kept as simple as possible in the hopes that it will remain functional through future releases.


Summary

Extensions are a new and exciting shift in thinking on iOS. Extensions are expected to continue to be refined and adapted in the future. The basic initial functionality of extensions allows for a great amount of flexibility and features that were not previously available in iOS development. The use of extension-like behavior for the Apple Watch shows that Apple is behind this technology and that they are taking the slow and proper approach to allowing cross-app interaction. Security, stability, and user safety have always been of the utmost importance for Apple, and extensions enable them to maintain that focus while giving developers functionality that has been requested since the initial iOS release.

Although extensions are a fairly large topic covering various types of interactions, the material provided in this chapter should provide a comfort level enabling a developer to dig into and begin working with and exploring the power of app extensions. There have been only a handful of times in the evolution of the iOS developer platform when a new technology allows for a radical change in the flexibility of the developer. Extensions are one of these few giant leaps forward. No one, including Apple, has any idea what developers will do with this technology, and that always makes for a very interesting development platform.

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

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