Dunfey · Hotel WWDC as data, est. 1983
Front desk everything
Years
Topics

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 ↗

Transcript all transcripts

Code shown on screen · 7 snippets

Implementing SetFocusFilterIntent swift · at 4:57 ↗
// 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 swift · at 7:02 ↗
// Defining your Parameters & Entities

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?

    // ...
}
Display Representation swift · at 8:43 ↗
// 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 swift · at 11:24 ↗
// 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 swift · at 11:47 ↗
// 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 swift · at 13:27 ↗
// 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 swift · at 13:53 ↗
// 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