Swift: How to create iOS Today extension and share data with containing app

Do you happen had a chance to see the 3d touch icon widget or iOS Today Extension, let’s take a look at how to create an Extension in swift, how to open containing app and how to share data with containing app.

To add Today Extension to the project click “file” -> “new” -> “target”: chose “Today Extension”.
Let’s go to “Capabilities” tab and enable “App Groups” for both AppWithExtension and Extension targets, for both app and extension you need to click “+” icon under the “App Groups” and add Groups to you app id, e.g. like here


Shared Default Settings

Now you can use shared Default Settings for both Application and Todays Extension, let’s take a look at how to write and read to these share settings.

Let say we want to save some score in the main Application:

static func setSharedScoreNumber(score: Int) {
    let defaults = UserDefaults(suiteName: "group.bubblewrapSharedDefaults") // this is the name of the group we added in "App Groups"
    defaults?.set(String(score), forKey: "score")
    defaults?.synchronize()
}

And to read from the Todays Extension we just need to:

private func getScore() -> String {
    let defaults = UserDefaults(suiteName: "group.bubblewrapSharedDefaults")
    defaults?.synchronize()
    return String(describing: defaults!.object(forKey: "score") ?? "0")
}

That’s pretty much it!

How to open from Todays Extension containing application

We are going to use URL mechanism to open Application from Extension, first of all we need to add to Application’s info.plist the following (right click -> open as -> source code):

    <key>CFBundleURLTypes</key>
    <array>
        <dict>
            <key>CFBundleURLName</key>
            <string>com.mikitamanko.bubblewrap</string>
            <key>CFBundleURLSchemes</key>
            <array>
                <string>main-screen</string>
            </array>
        </dict>
    </array>

Feel free to add this right after

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>

This is required to let application know which URLs it should process. Now, to open Application let’s use the following code:

let myAppUrl = URL(string: "main-screen:")!
extensionContext?.open(myAppUrl, completionHandler: { (success) in
    if (!success) {
        print("error: failed to open app from Today Extension")
    }
})

This is it!

Social Share Toolbar