Published by
Often we believe that the best mobile experiences are ones where the user needs no assistance or introduction to their use. This belief runs counter to what most of us have experienced at one time or another; just because a feature seems intuitive to us, it does not follow that it will be intuitive to our end users.
Many of us have experienced, or even created, pre-app tutorials. As a user, I’m always looking for the “skip” button. The app hasn’t earned the right yet to tell me how it should be used. And if I’m a new user, I really don’t care about what’s new to the current version of the app.
A more fulfilling user experience would be to have hints presented to us as we use the app. This is significantly more complicated to build; we have to keep track of the user’s app experience, determine how to show tutorials as popover windows, and so on. The app should earn the right to show this information to users, and not barrage them at a convenient time for us.
In iOS 17, Apple has introduced a standardized tool set for building tutorials called TipKit, and it’s exactly designed to handle these complicated and conflicting desires. We get an easy set of tools that handle both the tracking of events and the displaying of appropriate Tips, and the user only sees them when the user should see them.
Too much code
I’m not going to focus on the code needed for this functionality; it’s incredibly straightforward to build into any app using SwiftUI, and even those still using UIKit. What I do want to show and discuss are the ways that this looks and feels in a real application.
What do Tips look like?
Tips are automatically configured for display by the OS; we don’t provide much in the way of direct control of how a Tip appears. This means that your Tip will automatically match the accent color set app-wide, and update its appearance with future versions of the OS.
We set only three visual properties on any given Tip: its title (simple text format, required), a message body (simple text, but not required), and an image (also not required).
These will automatically be laid out for us, without requiring any effort to make them look like the Tips users see in other iOS apps.
We can insert these Tips into our normal view hierarchy as standalone views, or we can present them as popover views. As we’re about to discuss, though, we don’t have to configure the conditions under which these tips will display using our own logic; we simply add them to our views, and they’ll be displayed whenever the overall Tip system determines that they should be displayed.
What are the conditions we can set?
For each Tip, we set one or more Rules to determine when the appropriate circumstances are for displaying that rule. These could be simple Rules, such as “The user has logged in”, or more complex, such as “The user has ordered four burritos in the past month”. Rules should be standalone– the Rule should not require both the user being logged in and the prior order. A tip can require multiple Rules to be true in order to display, so there’s no need to make an individual rule complicated.
Rules can be based on two factors; the first is an event, which is an action that occurs within your app. Each time that action is performed (such as reading an article), we donate the occurrence of the event to the overall TipKit system. TipKit can trigger the display of a Tip based on a single trigger of the Event, or multiple triggers.
Rules can also be based upon Parameters, which are simple variables whose value is evaluated as part of a Rule.
When the set of Rules for a Tip are all satisfied, the user may be presented with the Tip. The ultimate display of a Tip is determined not by these Rules alone, but also by a frequency setting, which is app-wide.
How often should the user see a tip?
While we can set up the conditions under which a Tip should be shown, we don’t want the user to be interrupted continuously while running the app, especially during those first days of use.
We combine the conditions for showing a Tip with a stated DisplayFrequency. These can be set anywhere from immediate (there’s no timer throttling of Tip display) up to a monthly frequency, with intermediate steps between those. This configuration of timing is a setting across the entire app. As we design these Tips, we don’t have to concern ourselves with how many Tips the user has seen on any given day, or what the precise contents of those Tips are.
For circumstances where we believe that a Tip should be displayed no matter what – for truly crucial information – a specific Tip can be set to ignore the app-wide display frequency. It’s best to use this sparingly (if at all); we don’t want to utilize this and bring ourselves back to the world of easily-ignored tutorials at the start of an application.
Testing your Tips
We have three primary tools for testing out our Tips in the context of our app. By including these in a developer-only menu, we can enable our testers to ensure that the Tips are behaving and appearing as intended.
We can set all – or a subset – of Tips to show regardless of whether they’ve met the required conditions for display. This can be done using `showAllTipsForTesting`, or `showTipsForTesting` with a smaller subset. This is the option we’re most likely to want to use to ensure that the Tips look right in the app, without regard to how they come to be displayed.
Likewise, we can prohibit all Tips from displaying by using `hideAllTipsForTesting` and `hideTipsForTesting` with a smaller subset. This ensures that we haven’t made our user interface less understandable through the addition of these Tips.
And to ensure that we haven’t changed the conditions for display, we can use `resetDatastore` to set the app to a state it would be before showing any Tips. This change must be made at app startup time, so a developer option for it would best be characterized as “reset on next launch”.
Tips can lead to greater user engagement
It can be a challenge to have users care about the new and advanced features we include in our apps. A sequence of tutorial screens won’t often have the impact we’d like, as a significant portion of users skip past these as quickly as possible. We can have better results by presenting Tips at the moment they’re most meaningful to a user.