Skip to content

Commit e1c4445

Browse files
committed
docs: improve documentation
1 parent e6a496d commit e1c4445

14 files changed

Lines changed: 286 additions & 95 deletions

Sources/QuickActionsKit/QuickActions.swift

Lines changed: 52 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,32 +7,69 @@
77

88
import UIKit
99

10-
/// The protocol defining the quick actions list and actions for your application.
11-
///
12-
/// ```swift
13-
/// enum MyQuickActionsType: String, QuickActionsType {
14-
/// // …
15-
/// }
10+
/// A protocol that defines a collection of Quick Actions to expose to the system.
1611
///
17-
/// final class MyQuickActions: QuickActions<MyQuickActionsType> {
18-
/// // …
19-
/// }
20-
/// ```
12+
/// Conform to `QuickActions` to provide a set of app-specific quick actions
13+
/// (e.g., Home screen quick actions on iOS) that can be transformed into
14+
/// `UIApplicationShortcutItem` instances and presented to the user.
15+
///
16+
/// The protocol is generic over an `ActionType` that must conform to
17+
/// `QuickActionType`, allowing you to define a strongly-typed domain of actions
18+
/// for your feature or application.
19+
///
20+
/// Usage:
21+
/// - Implement `actions()` to return a unique set of `QuickActionsItem<ActionType>`.
22+
/// - The items will be mapped to `UIApplicationShortcutItem` and truncated to `limit`.
23+
///
24+
/// - Note: The order of the returned items may affect which actions are shown
25+
/// when exceeding the limit; ensure `actions()` returns items in your desired priority.
26+
///
27+
/// - SeeAlso: `QuickActionType`, `QuickActionsItem`, `UIApplicationShortcutItem`
2128
public protocol QuickActions<ActionType> {
29+
/// The associated action type describing the domain of quick actions.
30+
///
31+
/// This type must conform to `QuickActionType` and typically represents
32+
/// the cases or identifiers for the actions your app supports.
2233
associatedtype ActionType: QuickActionType
23-
24-
/// The limit of actions to display.
34+
35+
/// The maximum number of quick actions to expose.
36+
///
37+
/// This value is used to limit the number of actions that are
38+
/// ultimately surfaced to the system. Implement to customize based on your
39+
/// product needs or platform constraints.
40+
///
41+
/// - Default: `Int.max`
2542
var limit: Int { get }
26-
27-
/// The list of dynamic actions.
43+
44+
/// Provides the full set of available quick actions for this context.
45+
///
46+
/// - Returns: A `Set` of `QuickActionsItem<ActionType>` representing unique actions.
47+
/// - Important: Use a `Set` to avoid duplicate actions and to emphasize uniqueness.
48+
/// - Note: The resulting set may be truncated to `limit` before being surfaced.
2849
func actions() -> Set<QuickActionsItem<ActionType>>
2950
}
3051

52+
/// The default implementations for `QuickActions`.
3153
public extension QuickActions {
32-
var limit: Int { 4 }
54+
/// The default maximum number of quick actions.
55+
///
56+
/// - Note: Implement in your conforming type to change the limit.
57+
var limit: Int { Int.max }
3358
}
3459

60+
/// Internal conveniences for transforming actions into system shortcut items.
3561
extension QuickActions {
62+
63+
/// A mapped array of `UIApplicationShortcutItem` created from `actions()`,
64+
/// limited to `limit` items.
65+
///
66+
/// - Discussion: This property maps each `QuickActionsItem` to a
67+
/// `UIApplicationShortcutItem` using `QuickActionsMapper.map`, filters out
68+
/// any that cannot be mapped, preserves the original ordering provided by
69+
/// `actions()`, and then truncates to the configured `limit`.
70+
///
71+
/// - Important: This property is intended for internal use when integrating
72+
/// with system APIs. Prefer implementing `actions()` when defining behavior.
3673
var shortcutItems: [UIApplicationShortcutItem] {
3774
Array(
3875
actions()

Sources/QuickActionsKit/QuickActionsHandler.swift

Lines changed: 59 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,66 @@
77

88
import Foundation
99

10+
/// A protocol that defines a handler for executing quick actions within your app.
11+
///
12+
/// Conform to `QuickActionsHandler` to process and respond to a specific set of quick actions,
13+
/// typically originating from system integrations such as Home screen quick actions, widgets,
14+
/// notifications, or app-specific shortcuts. Implementers specify the concrete action type via
15+
/// the `ActionType` associated type and provide logic to handle those actions asynchronously.
16+
///
17+
/// This protocol is annotated with `@MainActor`, which means conforming types and their methods
18+
/// are isolated to the main actor. This ensures UI updates and other main-thread–bound work
19+
/// can be performed safely while handling actions.
20+
///
21+
/// - Note: `ActionType` must conform to `QuickActionType`, which defines the model or descriptor
22+
/// for an action that can be invoked. Make sure your `ActionType` encapsulates all the
23+
/// information needed to execute the action.
24+
///
25+
/// - SeeAlso: `QuickActionType`
26+
///
27+
/// ### Example
28+
/// ```swift
29+
/// enum MyQuickActionsType: String, QuickActionType {
30+
/// case foo, bar
31+
/// }
32+
///
33+
/// extension SceneDelegate: QuickActionsHandler {
34+
/// func handle(_ action: MyQuickActionsType, userInfo: [String:NSSecureCoding]?) async -> Bool {
35+
/// switch action {
36+
/// case .foo:
37+
/// // …
38+
/// case .bar:
39+
/// // …
40+
/// }
41+
///
42+
/// return true
43+
/// }
44+
/// }
45+
/// ```
1046
@MainActor
1147
public protocol QuickActionsHandler {
48+
/// The concrete quick action type that this handler can process.
49+
///
50+
/// Conforming types set `ActionType` to a specific type that models the action
51+
/// to handle. This type must conform to `QuickActionType`.
1252
associatedtype ActionType: QuickActionType
13-
14-
func handle(_ action: ActionType, userInfo: [String: NSSecureCoding]?) async -> Bool
53+
54+
/// Handles a quick action asynchronously on the main actor.
55+
///
56+
/// Implement this method to execute the logic associated with the given `action`.
57+
/// Use `userInfo` to receive additional, optional metadata that may be required
58+
/// to complete the action (for example, identifiers, prefilled content, or flags).
59+
///
60+
/// - Parameters:
61+
/// - action: The quick action to be handled. Its type is defined by `ActionType`.
62+
/// - userInfo: An optional dictionary of additional information provided with the
63+
/// action. Values must conform to `NSSecureCoding` to ensure secure
64+
/// serialization and transport.
65+
///
66+
/// - Returns: `true` if the action was recognized and successfully handled; `false`
67+
/// if the action could not be handled or was not applicable.
68+
///
69+
/// - Note: Since this method is `async` and the protocol is `@MainActor`,
70+
/// you can safely perform UI operations directly within the handler.
71+
func handle(_ action: ActionType, userInfo: [String:NSSecureCoding]?) async -> Bool
1572
}
16-

Sources/QuickActionsKit/QuickActionsItem.swift

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,72 @@
88
import UIKit
99

1010
/// Represents the enum containing all the quick action types available for your application.
11+
/// A marker protocol that identifies a type-safe identifier for Home Screen quick actions.
12+
///
13+
/// Conform your enumeration to `QuickActionType` to declare the complete, strongly-typed
14+
/// set of quick actions your app supports. The protocol refines several standard Swift
15+
/// protocols to ensure identifiers are safe to use across threads, easy to store, and
16+
/// stable to serialize:
17+
/// - `RawRepresentable` with `RawValue == String`: Each case must map to a unique string
18+
/// value, which is used by the system (e.g., `UIApplicationShortcutItem.type`) and for
19+
/// persistence or deep linking.
20+
/// - `Hashable`: Enables use in sets, dictionaries, and as stable identifiers.
21+
/// - `Sendable`: Ensures values can safely cross concurrency boundaries.
22+
///
23+
/// Typical usage:
24+
/// ```swift
25+
/// enum AppQuickAction: String, QuickActionType {
26+
/// case note, search, favorites
27+
/// }
28+
/// ```
29+
///
30+
/// See also:
31+
/// - ``QuickActionsItem`` for modeling a full quick action entry presented to the user.
1132
public protocol QuickActionType: Sendable, RawRepresentable, Hashable where RawValue == String {}
1233

1334
/// Represents a quick action item shown in the menu.
35+
/// A value type that models a single Home Screen quick action entry for your app.
36+
///
37+
/// Use `QuickActionsItem` to describe the content and behavior of a quick action that
38+
/// appears in the system-provided menu (for example, via Home Screen icon context menu).
39+
/// Each item carries a strongly-typed identifier (`type`), user-visible strings (`title`
40+
/// and optional `subtitle`), an optional icon, and a Boolean that indicates whether the
41+
/// action is currently available.
42+
///
43+
/// - Generic Parameter:
44+
/// - T: A concrete type conforming to ``QuickActionType`` that uniquely identifies
45+
/// the action. This enables type-safe handling and pattern matching of actions.
46+
///
47+
/// The struct conforms to `Hashable`. Two `QuickActionsItem` values are considered equal
48+
/// if, and only if, their `type` values are equal. This makes `type` the logical unique
49+
/// identifier for items, which is useful when storing items in sets or using them as
50+
/// dictionary keys.
51+
///
52+
/// Typical usage includes:
53+
/// - Defining an enum that conforms to ``QuickActionType`` to enumerate all actions.
54+
/// - Creating one `QuickActionsItem` per action with localized titles, optional subtitles,
55+
/// and an appropriate icon.
56+
/// - Toggling `availability` to dynamically include or exclude an action from the menu.
57+
///
58+
/// Example:
59+
/// ```swift
60+
/// enum AppQuickAction: String, QuickActionType {
61+
/// case note, search, favorites
62+
/// }
63+
///
64+
/// let item = QuickActionsItem<AppQuickAction>(
65+
/// type: .note,
66+
/// title: "New Note",
67+
/// subtitle: "Create a blank note",
68+
/// icon: .systemName("square.and.pencil"),
69+
/// availability: true
70+
/// )
71+
/// ```
72+
///
73+
/// - Note: The `icon` supports multiple representations, including system icon names and
74+
/// `UIApplicationShortcutIcon.IconType`, to integrate with the system quick action UI.
75+
///
76+
/// - SeeAlso: ``QuickActionType`` and ``QuickActionsItem/Icon``
1477
public struct QuickActionsItem<T>: Hashable where T: QuickActionType {
1578
// MARK: Properties
1679
/// The unique quick action type.
@@ -51,6 +114,25 @@ public struct QuickActionsItem<T>: Hashable where T: QuickActionType {
51114

52115
extension QuickActionsItem {
53116
// MARK: Data
117+
/// Represents the visual symbol displayed alongside a quick action in the system menu.
118+
///
119+
/// Use `Icon` to describe how the quick action should appear visually. The enum supports
120+
/// multiple representations to align with system-provided icons and custom assets.
121+
///
122+
/// Cases:
123+
/// - `type(UIApplicationShortcutIcon.IconType)`: Uses a predefined system shortcut icon
124+
/// provided by UIKit. This is the most native option and ensures visual consistency
125+
/// with system quick actions.
126+
/// - `systemName(String)`: Uses an SF Symbols system image by name (e.g., "square.and.pencil").
127+
/// Prefer this when you want a modern, scalable symbol that follows system design.
128+
/// - `template(String)`: Uses the name of a templated image asset in your app bundle.
129+
/// The image should be a monochrome, template-rendered asset suitable for tinting.
130+
///
131+
/// Notes:
132+
/// - Not all SF Symbols are available on all platform versions. Ensure compatibility for
133+
/// targeted iOS, iPadOS, or other Apple platforms.
134+
/// - Template images should be provided as single-color assets intended for tinting.
135+
/// - The exact rendering of the icon may vary based on the system UI and context.
54136
public enum Icon: Hashable {
55137
case type(UIApplicationShortcutIcon.IconType)
56138
case systemName(String)

Sources/QuickActionsKit/QuickActionsKit.docc/Configuration/ConfigurationStep2.swift

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,15 @@ enum MyQuickActionsType: String, QuickActionType {
55
case create
66
}
77

8-
class MyQuickActions: QuickActions {
9-
var actions: Set<QuickActionsItem<MyQuickActionsType>> = [
10-
QuickActionsItem<MyQuickActionsType>(
11-
type: .home,
12-
title: "Go Home",
13-
subtitle: "Redirect to Home",
14-
icon: nil
15-
)
16-
]
8+
final class MyQuickActions: QuickActions {
9+
func getActions() -> Set<QuickActionsItem<MyQuickActionsType>> {
10+
[
11+
QuickActionsItem<MyQuickActionsType>(
12+
type: .home,
13+
title: "Go Home",
14+
subtitle: "Redirect to Home",
15+
icon: nil
16+
)
17+
]
18+
}
1719
}

Sources/QuickActionsKit/QuickActionsKit.docc/Configuration/ConfigurationStep3.swift

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,22 @@ enum MyQuickActionsType: String, QuickActionType {
55
case create
66
}
77

8-
class MyQuickActions: QuickActions {
9-
var actions: Set<QuickActionsItem<MyQuickActionsType>> = [
10-
QuickActionsItem<MyQuickActionsType>(
11-
type: .home,
12-
title: "Go Home",
13-
subtitle: "Redirect to Home",
14-
icon: nil
15-
),
16-
QuickActionsItem<MyQuickActionsType>(
17-
type: .create,
18-
title: "Create",
19-
subtitle: nil,
20-
icon: .systemName("plus"),
21-
availability: MyApplicationSingleton.current.isUserLogged
22-
)
23-
]
8+
final class MyQuickActions: QuickActions {
9+
func getActions() -> Set<QuickActionsItem<MyQuickActionsType>> {
10+
[
11+
QuickActionsItem<MyQuickActionsType>(
12+
type: .home,
13+
title: "Go Home",
14+
subtitle: "Redirect to Home",
15+
icon: nil
16+
),
17+
QuickActionsItem<MyQuickActionsType>(
18+
type: .create,
19+
title: "Create",
20+
subtitle: nil,
21+
icon: .systemName("plus"),
22+
availability: MyApplicationSingleton.current.isUserLogged
23+
)
24+
]
25+
}
2426
}

Sources/QuickActionsKit/QuickActionsKit.docc/Configuration/ConfigurationStep4.swift

Lines changed: 0 additions & 34 deletions
This file was deleted.

Sources/QuickActionsKit/QuickActionsKit.docc/Configuration/Defining-Your-QuickActions.tutorial

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -32,14 +32,6 @@
3232

3333
@Code(name: "MyQuickActions.swift", file: ConfigurationStep3)
3434
}
35-
36-
@Step {
37-
Implement the `perform` method to handle action selection.
38-
39-
This method is called when a user taps a quick action from the Home Screen. Use the action type to navigate to the appropriate screen or trigger the corresponding feature.
40-
41-
@Code(name: "MyQuickActions.swift", file: ConfigurationStep4)
42-
}
4335
}
4436
}
4537
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import QuickActionsKit
2+
3+
@MainActor
4+
class SceneDelegate: UIResponder, UIWindowSceneDelegate {}
5+
6+
extension SceneDelegate: QuickActionsHandler {
7+
func handle(_ action: MyQuickActionsType, userInfo: [String:any NSSecureCoding]?) async -> Bool {
8+
switch action {
9+
case .home:
10+
// …
11+
case .create:
12+
// …
13+
}
14+
15+
return true
16+
}
17+
}

0 commit comments

Comments
 (0)