How to make a Today Extension Widget in Swift

Swift Today Extension Widget

We are going to learn how to use the new feature of iOS8: Today Extension (Widget for your notification center screen). We are going to take, as the base project, the one explained here. You will learn:

  1. How to create a Today Extension in Xcode: Target
  2. How to use the method widgetPerformUpdateWithCompletionHandler
  3. How to share data between the Today Extension and the main app

At the end of the post you will have a widget that gets data from its container app. The app gets stock values from Yahoo Finance API and the widgets recovers the last one received from AAPL.

We already have an app that gives us the stock prize of APPL (from a past tutorial). But now we want a widget in our notification center that show to us the last prize of APPL that our app received:

Swift Today Extension Widget7

 

First of all: Download the initial project. We will work with it. Link HERE

1. Create a new target

In order to have a widget for our awesome app, we have to create a new Target: File ->New->Target

Swift Today Extension Widget

We select then iOS->Application Extension->Today Extension

Swift Today Extension Widget

Put the name “StockWidget” and select Swift as the language:

Swift Today Extension Widget

As you will see, Xcode has generated some new folders and files inside your main workspace:

Swift Today Extension Widget

There are two important new files:

  1. MainInterface.storyboard (the GUI of the widget)
  2. TodayViewController.swift (the controller of the widget)

We want a stock widget that show us the last value of APPL symbol that our main app has received. Just to remember us how much we were winning (or losing!) the last time we got the stock prizes.

2. Customize your Widget appareance

Open MainInterface.storyboard, and you will see you awesome “Hello World” widget ready for you. Let’s create an IBOutlet for that label in our TodayViewController.swift class. Name it: labelWidget

Swift Today Extension Widget

We are going to put a font on the label of 22 and to give to it a green color (all of this inside the storyboard interface). We are not going to customize it anymore (that will be your homework :P)

Now, add this line of code:

As you can see in the //1, we are just setting up some dummy text. Apple Documentation states “It’s expected that the widget will perform the work to update asynchronously and off the main thread as much as possible.” so I have dispatched the change of text of the label to the main thread.

Now Build and Run the widget (pay attention to the target to run, now you have one for the widget!). You should see (and accept) this:

Swift Today Extension Widget

 

Our widget should look like:

Swift Today Extension Widget8

It is a good start!

3. How to share data between the widget and the container app

Now, we want our widget to gather the last update on the prize of APPL which our app have received. To share data between and app and its widget, we have to use the “App Groups” Capabilities.

Follow these steps:

1. Go to project in the Project Navigator. Now select your app target. Go into the Capabilities tab. Turn on App Groups.

2. When prompted for a name for the group, put “group.SwiftStocks.Widget“. Group names should be unique to your developer account.

3. Now do the same with the target of your widget (this time, the app group already exist, just check on it).

See screenshots below:


Swift Today Extension Widget8

Swift Today Extension Widget8

 

With this process, you are granting permissions to your app + widget to share data. This data is going to be shared with the help of the NSUserDefaults.

Go to the class StocksTableViewController.swift and add the code to the method:

And change this method at TodayViewController.swift:

Explanations of each block:

  1. When we are painting the cells of the table, we are checking when we paint the AAPL one. When this happens, we are setting the value “AAPL X.XX%” inside a variable at the NSUserDefaults. Note how we create the defaults with the SAME name of our App Group!!!. So now every time we got a new value for AAPL, we are saving it into our “shared” data container (shared with the widget).
  2. And now in the widget, when we are going to update it, we just get that value from the userDefaults and put it on the label text.

Easy right?

Build and Run the app target (not the widget one!)

You should see how the value of AAPL is the same on the app, and the same when you turn down the notification center in the simulator:

Swift Today Extension Widget8Swift Today Extension Widget8

 

Here you have the github project and the code:

Hope you enjoyed it! Have a nice day and give it a try!

PS: If you want a better widget, you can update the value of AAPL in the widget itself (calling to Yahoo finance API like you are doing in the app). That is your homework 🙂

 

 

About @marioeguiluz

iOS Freelancer, Entrepreneur and Mobile App Expert

Categories: All, Development, Tutorial

2 comments

  • Podster123

    Thanks for the great tutorial.

    I have not been able to figure out how to make a Today Extension work with iCloud Core Data. I can make it work with Core Data alone by app groups but not with iCloud.

    Any suggestions are greatly appreciated. Its been a big stumbling block.

Leave a Reply

Your email address will not be published. Required fields are marked *