2022 App Services
WWDC22 · 16 min · App Services
Meet Focus filters
Discover how you can customize app behaviors based on someone’s currently enabled Focus. We’ll show you how to use App Intents to define your app’s Focus filters, act on changes from the system, and present your app’s views in different ways. We’ll also explore how you can filter notifications and update badge counts. To get the most out of this session, we recommend first watching "Dive into App Intents" from WWDC22.
Watch at developer.apple.com ↗Code shown on screen · 7 snippets
Implementing SetFocusFilterIntent
// Implementing SetFocusFilterIntent
import AppIntents
struct ExampleChatAppFocusFilter: SetFocusFilterIntent {
static var title: LocalizedStringResource = "Set account, status & look"
static var description: LocalizedStringResource? = """
Select an account, set your status, and configure
the look of Example Chat App.
"""
} Defining your Parameters & Entities
// Defining your Parameters & Entities
import AppIntents
struct ExampleChatAppFocusFilter: SetFocusFilterIntent {
(title: "Use Dark Mode", default: false)
var alwaysUseDarkMode: Bool
(title: "Status Message")
var status: String?
(title: "Selected Account")
var account: AccountEntity?
// ...
} Display Representation
// Display Representation
struct ExampleChatAppFocusFilter: SetFocusFilterIntent {
// ...
var localizedDarkModeString: String {
return self.alwaysUseDarkMode ? "Dark" : "Dynamic"
}
var displayRepresentation: DisplayRepresentation {
var titleList: [LocalizedStringResource] = [], subtitleList: [String] = []
if let account = self.account {
titleList.append("Account")
subtitleList.append(account.displayName)
}
if let status = self.status {
titleList.append("Status")
subtitleList.append(status)
}
titleList.append("Look")
subtitleList.append(self.localizedDarkModeString)
let title = LocalizedStringResource("Set \(titleList, format: .list(type: .and))")
let subtitle = LocalizedStringResource("\(subtitleList.formatted())")
return DisplayRepresentation(title: title, subtitle: subtitle)
}
// ...
} Implementing Perform on your Focus filter
// Implementing Perform on your Focus filter
import AppIntents
struct ExampleChatAppFocusFilter: SetFocusFilterIntent {
// ...
func perform() async throws -> some IntentResult {
let myData = AppData(
alwaysUseDarkMode: self.alwaysUseDarkMode,
status: self.status,
account: self.account
)
myModel.shared.updateAppWithData(myData)
return .result()
}
// ...
} Calling Current
// Calling Current
import AppIntents
func updateCurrentFilter() async throws {
do {
let currentFilter = try await ExampleChatAppFocusFilter.current
let myData = AppData(
myRequiredBoolValue: currentFilter.myRequiredBoolValue,
myOptionalStringValue: currentFilter.myOptionalStringValue,
myOptionalAppEnum: currentFilter.myOptionalAppEnum,
myAppEntity: currentFilter.myAppEntity
)
myModel.shared.updateAppWithData(myData)
} catch let error {
print("Error loading current filter: \(error.localizedDescription)")
throw error
}
} Set a filterPredicate
// Set filterPredicate on an App context
import AppIntents
struct ExampleChatAppFocusFilter: SetFocusFilterIntent {
var appContext: FocusFilterAppContext {
let allowedAccountList = [account.identifier]
let predicate = NSPredicate(format: "SELF IN %@", allowedAccountList)
return FocusFilterAppContext(notificationFilterPredicate: predicate)
}
} Pass filterCriteria on UNNotificationContent
// Pass filterCriteria on UNNotificationContent
let content = UNMutableNotificationContent()
content.title = "Curt Rothert"
content.subtitle = "Slide Feedback"
content.body = "The run through today was great. I had few comments about slide 22 and 28."
content.filterCriteria = "work-account-identifier" Resources
Related sessions
-
31 min -
3 min