Apple introduced App Extensions in iOS 8 and since then they are making a big difference in the world of iOS App Development. Lets get started with some extensions related terminology first.
An app extension lets you extend custom functionality and content beyond your app and make it available to users while they’re interacting with other apps or the system. It is used for some specific task. It is not an independent app.
An extension is tied to a particular area of the system refered to as the extension point. Each extension can have atmost 1 extension point.
The app for which the extension is created.
The app from which the extension is launched
You can get clarity of the terminology in the upcoming sections. Have patience..🙂
In the above screenshot,
Widgets are Notification Center extensions. These are simple view controllers with some additional functionality and hence their lifecycle works normally as for other view controllers.
Performance is most important:
Initially Today Extension was introduced in iOS 8. Later in iOS 10, some significant changes were made to it.
Example: In iOS 8 and iOS 9, Show More/Show Less needed to be handled explicitly by the developers. It was a tedious task since it required constraint and layout handling to adjust the widget’s height according to the content. But in iOS 10, Apple provided APIs to handle such functionality without taking much pain.
Here I’ll provide you the basic constructs that you require to implement a Today Extension in iOS 10. At the end of this article you can find a link to the Sample.
As stated earlier, you cannot directly share data between your extension and its containing app. To share data, you need to use App Group.
Even though an app extension bundle is nested within its containing app’s bundle, the running app extension and containing app have no direct access to each other’s containers.
To enable data sharing, use Xcode or the Developer portal to enable app groups for the containing app and its contained app extensions. Next, register the app group in the portal and specify the app group to use in the containing app.
You cannot use standard UserDefaults to share data between App Extension and the Containing App.
Use standard one for data that is only for Containing App. Use suiteName for data that you want to share between Extension and Containing App. Just don’t persist the same data in both of them. Avoid data redundancy. Use both of them according to the context.
There exist 2 modes in which you can display data in your widget. These modes are categorized under NCWidgetDisplayMode as compact and expanded.
Show More or Show Less buttons are shown in the widget’s top right corner according to the widget’s active display mode i.e. in compact mode, show more is visible and in expanded mode, show less is visible.
widgetLargestAvailableDisplayMode signifies the largest display mode supported by your app.
NCWidgetProviding protocol provides a delegate method widgetActiveDisplayModeDidChange(_: maxSize:) that handles the size of the widget in compact and expanded mode.
Width of the widget remains same according to the device you are using. There is no provision provided to change it.
Height of the widget can be changed according to the active display mode.
Note: In expanded mode, the maximum height that you can provide to a widget cannot be more than the visible space provided to widgets in the Notification Center.
To help your widget look up to date, the system occasionally captures snapshots of your widget’s view. When the widget becomes visible again, the most recent snapshot is displayed until the system replaces it with a live version of the view.
You can open your containing app from the extension using open(_ URL:, completionHandler:)
You also need to define YOUR_URL_SCHEME in the URL Types of your containing app.
When the containing app is opened from extension, you can get the handle in AppDelegate’s application(_ : url: sourceApplication: annotation: ) method.
In case you need to show or hide the extension depending to the content you want to show, you can do it from your containing app.
You cannot directly share the code between your extension and its containing app. To share data, you need to use Framework.
You can create an embedded framework to share code between your app extension and its containing app.
Make sure your embedded framework does not contain APIs unavailable to app extensions. If you have a custom framework that does contain such APIs, you can safely link to it from your containing app but cannot share that code with the app’s contained extensions. The App Store rejects any app extension that links to such frameworks or that otherwise uses unavailable APIs.
To configure an app extension target to use an embedded framework, set the target’s “Require Only App-Extension-Safe API” build setting to Yes.
Unable to load in Today Extension mostly appears when:
Debug your app extension to find out the exact problem.
Refer to Xcode’s Debug Gauge for Memory and CPU utilization.
Don’t forget to read my other articles:
Feel free to leave comments in case you have any doubts.