Chapter 15. Instant Information with a Notification Center Widget

When Apple added the Notification Center to iOS in iOS 6, they also added some stock widgets to a section called the Today View. These widgets had limited functionality and as developers, we had no ability to add our own widgets to this view. Users were stuck with a weather widget, one for stocks, one for the calendar, and a few more.

It wasn't until iOS 8 that Apple decided that developers should be able to create extensions for the Notification Center in the form of widgets. Together with that addition, Apple has added the ability for developers to tap into multiple extension points. This chapter will focus mainly on creating a Today Extension: a widget.

You'll learn what the lifecycle of an extension looks like and how extensions integrate with the OS and your app. The basis for this extension will be a small, simple app that has content that varies throughout the day. We'll also look at how iOS 10 makes widgets even more powerful and convenient for your users.

We will cover the following topics in this chapter:

  • Understanding the anatomy of a Today Extension
  • Adding a Today Extension to your app

Even though we only have two bullet points to cover, there will be plenty of information for you to take in. Let's dive right in.

Understanding the anatomy of a Today Extension

The terms Today Extension and widget can be used interchangeably; they both refer to a component that's present in iOS's Notification Center. In this chapter, we'll mostly stick to the term widget, unless we're talking more broadly in the context of extensions.

If you swipe down from the top of the screen to open Spotlight and swipe right after that, you're presented with the Today View. On the simulator, this view tends to look rather empty, but on your device, there's probably a lot more going on. The following screenshot shows the Today View on the simulator with a couple of widgets added to it:

Understanding the anatomy of a Today Extension

Users can scroll to the bottom of this view and manage their widgets from there. They can add new widgets and remove existing ones. All these widgets have one thing in common: they attempt to provide relevant information for the current moment or day. For the calendar, this means showing events that are set up for today or tomorrow. The favorites widget in the image will usually show contacts that you interact with often.

Any widget that you add to your app should strive to provide your users with relevant, easy-to-scan information. Doing this will make your widget more useful and more likely to be added to a user's Today View.

How do these widgets work, though? And how do they relate to their corresponding apps since a widget cannot exist without a host application? To answer these questions, we'll have a broad look at extensions in general. Once you understand the app extension fundamentals, we'll move on to specifics about widgets.

Understanding app extensions

Ever since iOS 8, we've been gaining more and more opportunities to add extensions to our applications. In iOS 10, there are 19 different ways for you to integrate with iOS. Not every app can or should integrate all 19 extension points, but it's good to be aware of the fact that there are many ways for your app to stand out from the crowd:

Understanding app extensions

The preceding screenshot captures the names of all 19 extensions that you can integrate into your apps. You'll notice that there's a Spotlight Index extension. If you're indexing your app in Spotlight and you want to make sure that Spotlight can re-index items even if your app isn't running, this extension is definitely worth checking out and shouldn't be too hard to implement, since its behavior is similar to the indexing delegate you've already implemented.

The final extension on the screen is the Today Extension. This is the extension we'll be implementing in this chapter. If you examine the list of extensions closely, you'll notice that all the extensions are very different from one another. Some extensions have a lot of UI associated with them, like the Today Extension. Others involve a lot less UI, like the Share Extension or the Shared Links. Other extensions don't involve any UI at all, such as the Spotlight Index extension.

Whenever an extension is opened or instantiated, this is done through the extension framework itself. For instance, when you open a photo in the photos app and you tap the share button, there will be a couple of apps in the list that you can share the photo to. If you select one of these apps, you'll be presented with some UI, which allows you to pick a contact you want to share this with. Alternatively, you can write a status update or whatever else the target extension supports:

Understanding app extensions

When the extension's UI appears, the host application does not directly create an instance of this UI. It's actually the extension framework that takes care of this. At the same time, the extension is not inherently related to your application. So, when the photos app asks the Share Extensions framework for a certain Share Extension, the associated application could potentially not be running at all. In other words, extensions function completely independently of their corresponding apps.

Even though extensions run separately from apps, they aren't apps themselves. Most extensions you create are essentially view controllers that are added in the context of a different app. For instance, this means that extensions don't have an AppDelegate - not even the AppDelegate of their app counterparts. All of your initialization code and any lifecycle implementation detail you wish to integrate will have to be performed based on view-controller lifecycle methods.

At first it may seem counterintuitive, because you're used to creating an app that has its own lifetime and lifecycle, and in that app you add view controllers. As a sort of central hub or beating heart of the application, there's your trusty AppDelegate. Neither of these things are true in the case of extensions. A different app will load your app extension's view controller and it will add it to its own view hierarchy. So, an app extension isn't just a plain view controller because it has its own build target and even its own Info.plist file, but it's also not a full-blown app because it's always instantiated in the context of another app.

What this means exactly will become more clear in a moment when we discuss Today Extensions. The most important takeaway for you at this moment is that app extensions are neither a plain view controller nor an application; they're something in between.

Understanding Today Extensions

A Today Extension is an extension that adheres to all the rules mentioned before. Most importantly, a Today Extension isn't much more that a view controller that is embedded inside of the notification center's Today View.

This means that whenever your Today Extension is initialized, there is no AppDelegate involved at all. The extension does not have any application lifecycle methods such as application(_:didFinishLaunchingWithOptions:). The contents of your widget are added to the Today View through a technique called view-controller containment. The concept of view-controller containment means that view controllers are embedded in other view controllers. This technique isn't limited to the Today View; you can also use it in your own applications, and it's a great way to compose a complex view hierarchy.

If you're using view-controller containment, the parent view controller will notify its child view controllers of certain important events. For example, the parent will tell the child when the viewport or trait collection changes.

Because the Today View renders and contains your widget, you can't set the frame for the widget's view yourself. Chances are you're already used to this. Normally, when you're putting a view controller onscreen inside a navigation controller, tab bar, or simply as the only view controller in a single-view application, you generally don't set the frame for a view controller's view.

However, Today Extensions are somewhat different from an ordinary view controller. Usually, whenever you present a view controller, you want it to fill all the available space. And usually, the available space is just about the entire viewport. Today Extensions are a bit more complex because they don't tend to take up an entire screen. They don't take up a set amount of space, and some widgets in the Today View even grow and shrink.

Before iOS 10, a widget would resize itself based on its contents or the size that the widget would set as its preferredContentSize. In iOS 10, this behavior has changed and widgets have a user-defined compact mode and an expanded mode. The compact mode should normally be about 110 points in height, but in reality, this height varies based on the user's text-size preferences.

Because there are no real guarantees regarding the height your widget has available, it's important that you make sure to only show the most important information in your widget and it's a good idea to adopt dynamic type in your widget. This makes your widget more accessible by scaling the text inside your widget based on the user's preferences. You'll learn how to do this once we get to implement the widget.

If your widget supports it, your user can switch to the expanded state for your widget. In this state, you have a bit more freedom to set the size of the widget yourself. We'll explore supporting this a bit more when we implement our own widget.

One more key principle of Today Extensions is that the widget never communicates with its host app directly. If you have a widget that the user can tap to go into a detail view, the widget doesn't directly instruct the app to do this. Instead, URLs are used. You can use a custom URL scheme or a Universal Link to achieve this. In several snippets of example code, Apple uses custom URL schemes to achieve this effect. Because of this, the app we're going to extend will function in a similar fashion.

Now that you're completely up to speed about app extensions, and Today Extensions in particular, it's time to introduce you to the app we're going to extend in this chapter: Quote Today. The name of the app probably gives away the entire concept. It's an app that randomly displays a new quote to the user every day. Because this application has new content every day, it's a great candidate for a Today Extension. Let's dive right in.

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

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