Sample CodeiOS, iPadOS, Mac CatalystReviewed 2026-07-21View on Apple Developer

Add Home Screen quick actions

At a glance

Item Summary
Purpose Publishes favorite contacts as dynamic Home Screen actions and routes selected actions into the correct UI.
App architecture SceneDelegate is the quick-action coordinator; it translates scene callbacks into navigation over a small shared contact store.
Main patterns Scene lifecycle adapter, shared in-memory store, value model, storyboard navigation, and framework delegates.
Project style One UIKit target with lifecycle/controllers at the root and contact data under Models/.

Project structure

HomeScreenQuickActions/
├── AppDelegate.swift
├── SceneDelegate.swift
├── ContactsViewController.swift
├── ContactDetailViewController.swift
├── Models/
│   ├── Contact.swift
│   └── ContactsData.swift
└── Base.lproj/Main.storyboard

Structure observations

  • Quick-action production and consumption live together in SceneDelegate because both are scene-lifecycle operations.
  • Table/detail controllers read and edit the same in-memory contact store.
  • Contact owns action-safe value conversion in a focused extension.

Overall architecture

Reference code

HomeScreenQuickActions/SceneDelegate.swift:93 — the scene converts current favorites into dynamic shortcut items before resigning active.

func sceneWillResignActive(_ scene: UIScene) {
    let application = UIApplication.shared
    application.shortcutItems = ContactsData.shared.favoriteContacts.map { contact in
        UIApplicationShortcutItem(type: ActionType.favoriteAction.rawValue,
                                  localizedTitle: contact.name,
                                  localizedSubtitle: contact.email,
                                  icon: UIApplicationShortcutIcon(systemImageName: "star.fill"),
                                  userInfo: contact.quickActionUserInfo)
    }
}

Interpretation

The app has two entry paths into the same feature: normal table navigation and a scene-delivered shortcut. SceneDelegate resolves shortcut payloads to model identity, then performs the navigation that only the scene/window layer can see.

Ownership and state

Ownership evidence

HomeScreenQuickActions/Models/ContactsData.swift:10 — a mutable value-type singleton is the sample’s process-local source of contacts.

struct ContactsData {
    static var shared = ContactsData()

    var contacts = [
        Contact(name: "John Doe", email: "john@example.com", favorite: true),
        Contact(name: "Jane Doe", email: "jane@example.com", favorite: true)
    ]
}
Owner Object or state Relationship Mutation authority
UIKit scene lifecycle SceneDelegate and window UIKit creates the delegate and supplies the window Scene callback methods
SceneDelegate savedShortCutItem Temporarily retains a launch-time shortcut Scene lifecycle methods
ContactsData.shared Contact array Global value store Any same-module caller; updates go through updateContact in this sample
Detail controller Current Contact and outlets Receives a contact value and owns edit UI Text-field/switch callbacks, then store update

Class and protocol design

Type or protocol Responsibility Depends on
SceneDelegate / UIWindowSceneDelegate Publish, receive, decode, and route quick actions UIApplication, window navigation, contact store
ContactsViewController Display contacts and pass the selected value to detail UITableViewController, shared store
ContactDetailViewController / UITextFieldDelegate Edit one contact and commit changes Form outlets, shared store
ContactsData Query favorites/identity and replace edited values [Contact]
Contact Hold stable identity and encode shortcut user info UUID, secure-coding dictionary

There is no app-defined protocol abstraction. Protocol use is limited to UIKit lifecycle and input callbacks; the model collaboration is concrete.

Access control

Symbol Access Verified effect Likely rationale
App types and properties implicit internal All target files can reach the scene, controllers, and model store. Small teaching app favors direct collaboration over an exported API.
ContactsData.shared and contacts implicit internal mutable state Any same-module code may replace the store or array. Convenience for a sample; a production store would normally narrow mutation.
Controller outlets implicit internal Storyboard wiring and target code can access them. Interface Builder integration.
No private / fileprivate declarations verified absence The source establishes no lexical privacy boundary. Simplicity, not evidence that broad access is architecturally required.

Reference code

HomeScreenQuickActions/ContactDetailViewController.swift:10 — the controller, injected model value, and outlets all use the module default.

class ContactDetailViewController: UITableViewController {
    var contact: Contact?
    @IBOutlet var nameTextField: UITextField!
    @IBOutlet var emailTextField: UITextField!
    @IBOutlet var favoriteSwitch: UISwitch!
}

Logic ownership and placement

Logic Owning type or file Placement rationale
Shortcut publication and routing SceneDelegate Requires scene/window lifecycle and navigation context.
Favorite filtering, identifier lookup, replacement ContactsData Collection-level model operations.
Secure shortcut payload conversion Contact extension Transformation belongs beside the value it represents.
Contact list presentation ContactsViewController Table data-source concern.
Editing and commit triggers ContactDetailViewController Form and text-field lifecycle concern.

Design patterns

Pattern Source evidence Purpose or tradeoff
Scene lifecycle adapter HomeScreenQuickActions/SceneDelegate.swift:25 Handles both cold-launch and already-connected shortcut delivery.
Shared in-memory store HomeScreenQuickActions/Models/ContactsData.swift:13 Gives all screens and the scene one data source, at the cost of global mutable state.
Value model HomeScreenQuickActions/Models/Contact.swift:10 Hashable/Codable contact values carry stable identifiers.
Framework delegate HomeScreenQuickActions/ContactDetailViewController.swift:43 Converts text-field completion into model updates.

Naming conventions

  • Lifecycle and screen roles use Delegate and ViewController suffixes.
  • ActionType cases end in Action; the raw values match shortcut type identifiers.
  • favoriteContacts is a derived noun, while updateContact and handleShortCutItem are commands.
  • Model files sit under Models/; controller files match their primary type.

Architecture takeaways

  • Route external launch intents at the scene boundary, where window navigation is available.
  • Store a cold-launch shortcut until the scene becomes active; handle connected-scene shortcuts immediately.
  • Put shortcut payload encoding beside the domain value and decode back to stable identity.
  • Treat the sample’s globally mutable value store as a convenience, not a production access-control model.

Source map

Source file Relevant symbols
HomeScreenQuickActions/SceneDelegate.swift ActionType, shortcut publication and routing
HomeScreenQuickActions/ContactsViewController.swift Contact list and segue injection
HomeScreenQuickActions/ContactDetailViewController.swift Editing and store updates
HomeScreenQuickActions/Models/ContactsData.swift Shared contact collection
HomeScreenQuickActions/Models/Contact.swift Contact identity and shortcut user info