Focus filter
new way for users to customize app behavior based on the currently enabled Focus
Examples:
Calendar.app can show different calendars based if it’s weekend (Weekend focus) or if it’s work time (Work focus)
Mail.app can show different mailboxes and notifications based on the active focus
When to adopt focus filters
when your app manages multiple accounts (e.g., for leisure and work)
when your app has lots of content that can be filtered
when your app should be less distracting (e.g., by turning of badges) for certain focus modes
How Focus filter work:
Your app defines what can be customized via AppIntents
The system exposes to the user what can be configured as a Focus filter
The user will configure Focus filter settings in your app
Defining a Focus filter in your app
implement
SetFocusFilterIntent- this tells the system that your app is interested in having custom settings per Focus
import AppIntents
struct ExampleChatAppFocusFilter: SetFocusFilterIntent {
/// Title and description help users discover what your Focus is about.
///
/// Title and description are static and are ready by the system when
/// your app is installed.
static var title: LocalizedStringResource = "Set account, status & look"
static var description: LocalizedStringResource? = "..."
}define your app parameters - these will represent what can be configured within your app by the user
each parameter must have a name and a data type (
Bool,String, etc.)custom data types are supported via App Intents entities (
AppEntity)parameter can be marked optionals, meaning that they do not have to be configured
non-optional parameters should provide default values
import AppIntents
struct ExampleChatAppFocusFilter: SetFocusFilterIntent {
// ...
@Parameter(title: "Use Dark Mode", default: false)
var alwaysUseDarkMode: Bool
@Parameter(title: "Status Message")
var status: String?
@Parameter(title: "Selected Account")
var account: AccountEntity?
// ...
}set display representation - making your Focus filter appears in system settings with the correct content
struct ExampleChatAppFocusFilter: SetFocusFilterIntent {
// ...
/// This should return a dynamic representation of the current user configuration to
/// be displayed in the Settings.app.
var displayRepresentation: DisplayRepresentation {
...
return DisplayRepresentation(title: title, subtitle: subtitle)
}
// ...
}Acting on a Focus filter
The system will deliver relevant focus updates to your app in two ways:
If the app is running, you will receive a call to the perform method in your
FocusFilterIntent(if you’ve implemented it)If the app is not running, you can implement an extension that will be triggered when needed
at the end,
perform()in your FocusFilterIntent will get called (in your extension)an AppIntent extension is not necessary if you only need to act upon the changes in your main app
however, if you need to control widgets, notifications and/or badges, you should implement the extension
struct ExampleChatAppFocusFilter: SetFocusFilterIntent {
// ...
func perform() async throws -> some IntentResult {
let myData = AppData(
alwaysUseDarkMode: self.alwaysUseDarkMode, // 👈🏻 you access to the user configuration
status: self.status, // by accessing the @Parameter properties
account: self.account // values
)
myModel.shared.updateAppWithData(myData)
return .result()
}
}