 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. ### Terminology #### What’s an App Extension? 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. #### Extension Point 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. **Example**: 1. T_oday Extension_ is tied to _Notification Center_  1. _Share Extension_ can appear only in _UIActivityViewController._  #### Containing App The app for which the extension is created. #### Host App The app from which the extension is launched You can get clarity of the terminology in the upcoming sections. Have patience..🙂 ### Extension Lifecycle 1. User chooses the app extension from the host app. 2. System initiates the app extension. Extension displays its view within the context of host app. User performs the required task in app extension and dismisses it. 3. User returns to the previous context in the host app. Shortly after the app extension performs its task, the system terminates the extension. **Example:**  In the above screenshot, 1. _App Extension_: Facebook Share Extension 2. _Containing App_: Facebook 3. _Host App_: Photos App ### How App Extension Communicates 1. Direct communication between app extension and host app. System uses interprocess communication for communication between host app and extension. There is a request from the host app and a response from the extension. 2. No communication between containing app and host app. 3. Indirect communication between app extension and containing app. **Example,** _Shared Resources_: 1. **_Framework_** — to share code 2. **_App Group_** — to share data. ### Today Extension (Widget) 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:_** 1. Use _cached data._ 2. Move expensive operations to _background_. 3. Design a _simple UI._ ### Today Extensions in iOS 10 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.  ### How to? 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._ #### App Group — Share data with the Containing App 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. #### _NCWidgetDisplayMode_ There exist 2 modes in which you can display data in your widget. These modes are categorized under _NCWidgetDisplayMode_ as **_compact_** and **_expanded._** 1. _Compact mode_ has a _fixed height_ of _110_ and 2. _Expanded mode_ is used for _variable height_ according to your content. _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. 1. When set to _compact,_ your app will only support compact mode i.e. show more/show less functionality will no longer be supported and your widget will have a fixed height of 110. 2. When set to _expanded,_ the app will support both compact and expanded mode and show more/show less functionality will work accordingly. #### Handling Height according to Display Mode _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. #### Updating Widget 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. **_widgetPerformUpdate_** : 1. called when widget is _updated in background._ 2. called before widget _snapshot is taken._ #### Opening Containing App from Today Extension 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. #### Show/Hide Widget from Containing App 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. #### Framework — Share code with the 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 — Most common issue faced in Today Extension  Unable to load in _Today Extension_ mostly appears when: 1. You extension **crash** due to some reason. 2. It takes more memory than what is provided by the system. **(Memory Limit : max 16MB approx.)** Debug your app extension to find out the exact problem. Refer to Xcode’s **Debug Gauge** for Memory and CPU utilization. ### **Things to remember:** 1. Avoid using _scroll views_. 2. Doesn’t support _keyboard entry._ 3. Must be _light weight_. 4. Extension that launches too slowly is terminated by the system. 5. Low memory limits — _(max 16 MB approx.)_ 6. Some APIs unavailable to App Extension — sharedApplication object, camera, microphone, receive data using airdrop. ### Sample Widget [**pgpt10/Today-Widget** _Today-Widget - iOS 10 and iOS 8/iOS 9 Today's Extension (Widget)_github.com](https://github.com/pgpt10/Today-Widget "https://github.com/pgpt10/Today-Widget")[](https://github.com/pgpt10/Today-Widget) ### Promotions Don’t forget to read my other articles: 1. [Everything you’ve always wanted to know about notifications in iOS](https://medium.freecodecamp.org/ios-10-notifications-inshorts-all-in-one-ad727e03983a) 2. [Drag It & Drop It in Collection & Table — iOS 11](https://medium.com/@p.gpt10/drag-it-drop-it-in-collection-table-ios-11-6bd28795b313) 3. [Color it with GRADIENTS — iOS](https://hackernoon.com/color-it-with-gradients-ios-a4b374c3c79f) 4. [Everything about Codable in Swift 4](https://hackernoon.com/everything-about-codable-in-swift-4-97d0e18a2999 "https://hackernoon.com/everything-about-codable-in-swift-4-97d0e18a2999") 5. [UICollectionViewCell selection made easy..!!](https://hackernoon.com/uicollectionviewcell-selection-made-easy-41dae148379d "https://hackernoon.com/uicollectionviewcell-selection-made-easy-41dae148379d") Feel free to leave comments in case you have any doubts.