Problem #1: Understanding UIVisualEffectView

Oops, always remember to read the docs!

Cool vibrancy, weird animation

The fancy blur and backlit text effects in Notification Center don’t happen by accident. With iOS 8, we have access to a new class called UIVisualEffectView. I fought with this for a bit, because I didn’t realize there was a notificationCenterVibrancyEffect class method in a NotificationCenter category. The other trick with UIVisualEffectView, is that views that should be blurred/vibrant must be added to the visualEffectView.contentView, not the other way around.

The restaurant names in the GIF are UIButtons added to a visualEffectView.contentView.

Problem #2: This is Not Your Normal View Controller

From NCWidgetProviding.h:

// Instead, widgets should load cached state in ‘viewWillAppear:’ in order to match the state of the view from the last ‘viewWillDisappear:’, then transition smoothly to the new data when it arrives.

With a normal view controller, UI is setup in viewDidLoad and handle animations and loading data in viewWillAppear. Not so with a Today view controller conforming to the NCWidgetProviding protocol.

Nice fade animation from old content to new.

Now I know to reload the view in viewWillAppear. What I didn’t realize is that the viewController is deallocated each time it is dismissed, so it can’t persist data in a NSArray property. Since this is a simple app, I thought I would just use NSUserDefaults, but its not as simple as it seems.

Problem #3: Standard User Defaults Don’t Persist Between App & Extension

I already have a system storing important data in NSUserDefaults in my app to configure how the app should search. I assumed that [NSUserDefaults standardUserDefaults] would return the same thing for both the app and extension, but not so. This great article informed me that I need to create a group in the iOS Developer Portal, then initialize NSUserDefaults with a suite name of the group, i.e. [[NSUserDefaults alloc] initWithSuiteName:@”group.com.mycompany.myapp”].

Problem #4 No Keyboard Access & More

From the HIG:

As much as possible, let users perform a task or open your app with a single tap (note that the keyboard is not available within a Today widget).

This is not so much a problem, as an intentional limitation. Today widgets are meant to be quick to view and interact with, so typing is right out. I had intended to provide a quick search box, but found that this feature was impossible. Don’t try and use SLComposeViewController, MFMailComposeViewController, or any other UI that requires text entry. For the full list of API that have “NS_EXTENSION_UNAVAILABLE” defined on them, see this Gist.

Problem #5 What Should Today Widgets Be?

Inspiring? Or pointless?

Within hours of iOS 8's public launch, someone started a tumblr called “Shitty iOS 8 Widgets” pointing a finger at apps that had less than useful widgets. While I don’t condone “design shaming”, I want designers to be intentional about what makes a Today view useful. Not everyone wants a today view that shows motivational quotes, but Today views are opt-in. A user has to add it manually. Those who need a little motivation can put the view right at the top and those who are self motivated won’t add it at all.

From the “App Extensions” section of the iOS Human Interface Guidelines:

People visit Notification Center to get brief updates or to perform a very simple task, so it’s best when your Today widget displays the right amount of information and limits interactivity. Giving users a way to open your app from your Today widget can work well, but it’s essential that you continue to provide useful, timely information in the widget. People may not appreciate a Today widget whose only function is to launch your app.

As usual, Apple gives some pretty specific guidelines about how a Today view should behave and appear. These are just guidelines however, and there are possibilities to make much more complex Today views, such as PCalc:

PCalc provides a full calculator in the Today view. It breaks guidelines all over the place! It is too tall, too many buttons/taps, and doesn’t provide quick glanceable information. It has a nice use of the vibrancy effect, while making the button text a solid white color. It is definitely a tool meant for power users. Yet Apple has approved it and even featured it in the “Extend Your Apps” section. PCalc got lucky. Some apps with advanced features were not so lucky.

Problem #6 What Can Today Widgets Be?

As usual, we developers have to live in a world where Apple makes the rules. Apple is still deciding what should and should not be in the Today View. A great app called “Launcher” was approved in the store and saw great success, only to be rejected a few days later.

Apple is still inconsistent about what will be approved. Another app called “Launch +” is still live on the app store. It will take some time for developers to have confidence about what is acceptable Today widget behavior. I am a bit worried my widget may be rejected as it opens an app other than itself (Maps).

I will submit Terrific in its current state and see if it is accepted. It is still the early days for iOS 8. I am sure Apple’s app approval rules will change as new apps create today widgets.

Demo of the current progress on the Today Widget:

The ‘Terrific’ sample project is on Github here: https://github.com/jstart/Terrific

For a deeper dive on debugging and radars with today widget extensions, see this article on Atomic Bird.

Follow me @iAmChrisTruman for updates on my work with Today Widgets.