Some time ago, Apple created a way to expand an app’s capabilities to go beyond the app itself. This allowed developers to provide options for interacting with other apps and enabled the user to access the app’s features without having to open it!
This type of programming is called “iOS App Extensions.” These extensions are parts of the app and work independently of one another, as if they were plug-ins with their own lives, and they orbit the Apple system itself allowing for customized modifications.
This has allowed iOS developers to think beyond apps and to provide tools that create a more complete User Experience.
Today, 23 templates exist for creating extensions. They range from photo editing, file management, daytime widget actions to notifications and custom keyboards:
Each type of extension is developed for a specific task. We use a “Share Extension” to allow users to share something directly to their app from a browser. For custom notifications, including granting media control and user-customizable actions, we use a “Notification Content Extension.” We can even create a custom keyboard for your app with the “Custom Keyboard Extension.” We should choose the extension based on the function we wish to implement.
Each extension is attached to an extension point, a single, closed-scope system area that provides APIs for creating extensions specific to that area. An extension can only have one extension point, for this reason, it’s not possible to create a generic extension that functions for more than one target.
The following is a list of current iOS extension points:
How do they work?
Although extensions are included within the app, in practice, they work as independent binaries running outside the app. In xCode, they work as different implementation targets, as well as unit tests or components.
Because an extension is not an app, its lifecycle is different. In most cases, it is instantiated by the app by which it is contained, as soon as the user provides the necessary permission to do so. The system then opens a route for the extension independent from that of the app and communicates directly with it, either by custom sharing options or by UI keyboard: Siri or notifications. Access also depends on the type of extension point that the extension uses. Finally, the system closes the extension process.
Example of an Extension with notifications — EverQuiz
To demonstrate the Extension’s power, we executed a customized and interactive notification test. This type of implementation allows users to interact with the notifications as if they were part of the operational system. This provides a new way to communicate with app users:
To develop something with these capabilities, the first step is to generate ContentExtension, extensions used for custom notification, and ServiceExtension, which allows for connection to services and file upload within the notification:
In the ViewController, there is a button to register the user for the notification. Upon clicking, it asks for the client’s permission to receive notifications. Once accepted, the granted permission is registered and a “question” class notification will be shot off in 3 seconds:
At this point, the ContentExtension comes into play: the extension has a class in the archive .plist, called UNNotificationExtensionCategory, which basically states the name of the notification class that will be intercepted to produce the custom content. Other notification classes will not be interrupted and will have the default behavior:
In the notification, we have a didReceiveNotification function that receives the notification with the corresponding class and comes to the view in question:
All notification information is passed within the UserInfo object, so we receive all the outside information and use it to put together the screen. This also works for remote notifications coming from the server to the app. Finally, we instantiate a video player with the file inside the notification and wait for the user to press play:
We replace the functions of InputView, InputAcessoryView and canBecomeFirstResponser to use the input’s custom view, such as user interaction:
Finally, when the video ends, we display it, while initiating a 15-second timer and waiting for interaction.
At the moment, we use a local video file from the app. If it is necessary to download the media before playing it, in the response call-back we would send the request to the server, using the ServiceExtension as the communication port. The following is an example of an implementation of an internet video download:
It is possible to think far beyond classic apps contained within themselves and we have begun to imagine how to go beyond and offer a complete user experience for everything the app aims to do. Why not use our app as a sharing gateway? Why not customize Siri with personalized voice commands? We can use the app as the document repository that Spotlight can index, why not provide a native search system? Basically, why don’t we innovate?
By: Alexandre Abreu