What's New / Apple Intelligence, ML & Evaluation

What's new in SuggestedActions

+10 NewiOS · macOS

SuggestedActions is a SwiftUI framework for showing suggested next actions in a conversation message UI. You place a SuggestedActionsView, give it message context, and it generates action suggestions.

The 27 SDK adds 10 APIs and removes none. The new types are SuggestedActionsMessage, Participant, and SuggestedActionsView. SuggestedActionsMessage has init and previousMessagesLimit. SuggestedActionsView has body, the Body associated type, generate, and init.

New

10
struct

SuggestedActionsMessage

NewiOSmacOS
public struct SuggestedActionsMessage : Sendable

A representation of the message you use as context for suggested actions.

Create a SuggestedActionsMessage from your app's data model for a message, then pass it to init(message:previousMessages:) or generate(message:previousMessages:).

The id you pass to the create a SuggestedActionsMessage must be unique for each message and stable across app launches. Creating stable identifiers lets the framework match messages against previously cached suggested actions.

Note: To use the Suggested Actions framework, add the

<doc://com.apple.documentation/documentation/bundleresources/entitlements/com.apple.developer.suggested-actions> entitlement to your app target.

Declaration
public struct SuggestedActionsMessage : Sendable {

    /// Creates a representation of a message that the system uses to display suggested actions.
    ///
    /// - Parameters:
    ///   - id: A stable, unique identifier for the message. Common types for this identifier are
    ///     `String`, `UUID`, or a custom identifier type, but any `Hashable`
    ///     value works. The identifier must remain consistent across the lifetime of
    ///     the message and across app launches.
    ///   - date: The date when the sender sent the message or the date your app
    ///     received it.
    ///   - subject: The subject line of the message.
    ///   - body: The body content of the message.
    ///   - sender: The participant who sent the message.
    ///   - recipients: The participants who received the message.
    @available(macOS 27.0, iOS 27.0, *)
    @available(tvOS, unavailable)
    @available(watchOS, unavailable)
    public init(id: some Hashable, date: Date, subject: AttributedString?, body: AttributedString, sender: SuggestedActionsMessage.Participant, recipients: [SuggestedActionsMessage.Participant])
}
struct

SuggestedActionsView

NewiOSmacOS
public struct SuggestedActionsView : View

A view that displays suggested actions for a message.

The suggested actions view displays inline actions for a messaging app, next to a message, using context you provide. This view animates suggested actions as they become available. If no suggested actions are available, the view's size is zero and remains zero until they become available. At size zero, a SuggestedActionsView doesn't affect your surrounding layout. As a result, place the view for every message in a conversation. It doesn't introduce gaps between messages if a message doesn't have suggested actions.

Note: To display suggested actions, add the

<doc://com.apple.documentation/documentation/bundleresources/entitlements/com.apple.developer.suggested-actions> entitlement to your app target.

## Customize the appearance

To customize a SuggestedActionsView, apply standard SwiftUI view modifiers to change its appearance. Additionally, the view reads the following modifiers from its parent views:

  • <doc://com.apple.documentation/documentation/swiftui/view/tint(_:)>,
  • <doc://com.apple.documentation/documentation/swiftui/view/foregroundstyle(_:)>,
  • <doc://com.apple.documentation/documentation/swiftui/view/font(_:)>
  • <doc://com.apple.documentation/documentation/swiftui/view/buttonbordershape(_:)>

## Generate suggested actions for future use

To avoid showing a loading state when the view appears, call generate(message:previousMessages:) to let the Suggested Actions framework create suggested actions and cache them for future use. When you later initialize a SuggestedActionsView, the framework checks the id of cached suggested actions based on their messages' id property. If it finds an id that matches the id of a new SuggestedActionsMessage, the system uses the already generated suggested action.

The following example shows how an app might show a SuggestedActionsView with information about previous messages using a capsule border shape, blue tint, and the callout font style:

SuggestedActionsView(
    message: message.suggestedActionsMessage,
    previousMessages: message.previousMessages
        .suffix(SuggestedActionsMessage.previousMessagesLimit)
        .map(\.suggestedActionsMessage)
)
.buttonBorderShape(.capsule)
.tint(.blue)
.font(.callout)
Declaration
@MainActor public struct SuggestedActionsView : View {

    /// The content and behavior of the view.
    ///
    /// When you implement a custom view, you must implement a computed
    /// `body` property to provide the content for your view. Return a view
    /// that's composed of built-in views that SwiftUI provides, plus other
    /// composite views that you've already defined:
    ///
    ///     struct MyView: View {
    ///         var body: some View {
    ///             Text("Hello, World!")
    ///         }
    ///     }
    ///
    /// For more information about composing views and a view hierarchy,
    /// see <doc:Declaring-a-Custom-View>.
    @available(macOS 27.0, iOS 27.0, *)
    @available(tvOS, unavailable)
    @available(watchOS, unavailable)
    @MainActor @preconcurrency public var body: some View { get }

    /// The type of view representing the body of this view.
    ///
    /// When you create a custom view, Swift infers this type from your
    /// implementation of the required ``View/body-swift.property`` property.
    @available(macOS 27.0, iOS 27.0, *)
    @available(tvOS, unavailable)
    @available(watchOS, unavailable)
    public typealias Body = some View
}
extension

SuggestedActionsView

NewiOSmacOS
extension SuggestedActionsView : Sendable
Declaration
extension SuggestedActionsView : Sendable {
}
init

SuggestedActionsMessage.init

NewiOSmacOS
public init(id: some Hashable, date: Date, subject: AttributedString?, body: AttributedString, sender: SuggestedActionsMessage.Participant, recipients: [SuggestedActionsMessage.Participant])

Creates a representation of a message that the system uses to display suggested actions.

Parameters

id
A stable, unique identifier for the message. Common types for this identifier are String, UUID, or a custom identifier type, but any Hashable value works. The identifier must remain consistent across the lifetime of the message and across app launches.
date
The date when the sender sent the message or the date your app received it.
subject
The subject line of the message.
body
The body content of the message.
sender
The participant who sent the message.
recipients
The participants who received the message.
struct

SuggestedActionsMessage.Participant

NewiOSmacOS
public struct Participant : Sendable

A sender or recipient of a message in a conversation.

Create a Participant by providing a display name, a handle that uniquely identifies the participant, and a Boolean value that indicates whether the participant is the user of this device. Common handles are phone numbers or email addresses, but you can use any string that uniquely identifies a participant within your app's user identity system.

To enable the Suggested Actions to tailor the suggested actions to the person who uses a device, make sure the isUser parameter of init(name:handle:isUser:) is true for the participant that uses the device. Set isUser to false for other participants. The following code snippet shows how an app can initialize a Participant who uses the current device and a second participant who sends a message from their own device to the first participant's device:

// The participant who uses this device.
let user = SuggestedActionsMessage.Participant(
    name: "Anne Johnson",
    handle: "annejohnson1@icloud.com",
    isUser: true
)

// A second participant, usually contact in the conversation.
let contact = SuggestedActionsMessage.Participant(
    name: "Juan Chavez",
    handle: "chavez4@icloud.com",
    isUser: false
)
Declaration
public struct Participant : Sendable {

    /// Creates a participant in a conversation.
    ///
    /// - Parameters:
    ///   - name: The participant's display name, for example, Juan Chavez.
    ///   - handle: A unique identifier for the participant, like an
    ///     email address or phone number.
    ///   - isUser: A Boolean value that indicates whether the participant
    ///     is the user of this device. Set `isUser` to `true` for the
    ///     participant whose identity matches the user signed in to your
    ///     app on this device, and `false` for every other participant.
    public init(name: String, handle: String, isUser: Bool)
}
var

SuggestedActionsMessage.previousMessagesLimit

NewiOSmacOS
public static var previousMessagesLimit: Int { get }

The maximum number of previous messages that contribute to generating suggested actions.

When you pass an array of SuggestedActionsMessage values to the previousMessages parameter of init(message:previousMessages:) or generate(message:previousMessages:), the framework only considers a limited number of provided previous messages. previousMessagesLimit represents this limit. The framework ignores any older messages that exceed it.

The value of previousMessagesLimit may change between OS releases. Read it at runtime rather than hardcoding a limit to avoid constructing SuggestedActionsMessage instances that the framework doesn't use, as shown in the following example:

let previousMessages = allPreviousMessages
    .suffix(SuggestedActionsMessage.previousMessagesLimit)
    .map(\.suggestedActionsMessage)

SuggestedActionsView(
    message: message.suggestedActionsMessage,
    previousMessages: previousMessages
)
var

SuggestedActionsView.body

NewiOSmacOS
public var body: some View { get }

The content and behavior of the view.

When you implement a custom view, you must implement a computed body property to provide the content for your view. Return a view that's composed of built-in views that SwiftUI provides, plus other composite views that you've already defined:

struct MyView: View {
    var body: some View {
        Text("Hello, World!")
    }
}

For more information about composing views and a view hierarchy, see <doc:Declaring-a-Custom-View>.

typealias

SuggestedActionsView.Body

NewiOSmacOS
public typealias Body = some View

The type of view representing the body of this view.

When you create a custom view, Swift infers this type from your implementation of the required body-swift.property property.

func

SuggestedActionsView.generate

NewiOSmacOS
nonisolated public static func generate(message: SuggestedActionsMessage, previousMessages: [SuggestedActionsMessage] = []) async

Fetches and caches suggested actions for the provided message.

Call this method ahead of presenting a SuggestedActionsView to generate and cache suggested actions for future use. When you later initialize the view with a SuggestedActionsMessage that has a matching id, the view uses the cached result and renders immediately without displaying a loading indicator.

Generate suggested actions for future use when you know that a person is likely to see them soon, for example, when someone opens a conversation.

You can call this method multiple times with different messages. Within a single conversation, the framework deduplicates suggestions: If a suggested action appears for an earlier message, it doesn't appear again for later messages.

The following example shows how an app might use a ChatManager class that processes an incoming message and creates a suggested actions view:

@Observable
class ChatManager {
    private(set) var messages: [ChatMessage] = []

    // Process a new incoming message and generate suggested
    // actions to let the Suggested Actions framework cache them for future use.
    func handleIncomingMessage(_ newMessage: ChatMessage) async {
        await SuggestedActionsView.generate(
            message: newMessage.suggestedActionsMessage,
            previousMessages: newMessage.previousMessages
                .suffix(SuggestedActionsMessage.previousMessagesLimit)
                .map(\.suggestedActionsMessage)
        )
        messages.append(newMessage)
    }
}

Parameters

message
The message that you want to generate suggested actions for.
previousMessages
An array of messages that precede the provided message. The Suggested Actions framework uses them as context to generate suggested actions for the message. The system limits the number of previous messages it considers to the value of previousMessagesLimit. This parameter defaults to an empty array if you don't include previous messages.
init

SuggestedActionsView.init

NewiOSmacOS
public init(message: SuggestedActionsMessage, previousMessages: [SuggestedActionsMessage] = [])

Creates a view that shows suggested actions for the specified message.

Use this initializer to present suggested actions that the framework generates for a provided message. The Suggested Actions framework analyzes the message, and previous messages you provide as additional context, then shows relevant actions that a person can take.

If you call generate(message:previousMessages:) to generate suggested actions for future use, and later pass a SuggestedActionsMessage, the Suggested Actions framework checks for suggested actions it already generated and cached. If it finds a message with a matching id, the SuggestedActionsView uses the cached result and renders the suggested actions immediately.

The following example shows how an app might show a SuggestedActionsView with information from previous messages:

struct ChatView: View {
    @Binding
    var messages: [ChatMessage]

    var body: some View {
        ForEach(messages) { message in
            ChatBubble(message)

            SuggestedActionsView(
                message: message.suggestedActionsMessage,
                previousMessages: message.previousMessages
                    .suffix(SuggestedActionsMessage.previousMessagesLimit)
                    .map(\.suggestedActionsMessage)
            )
        }
    }
}

Parameters

message
The message that you want to generate suggested actions for.
previousMessages
An array of messages that precede the provided message. The Suggested Actions framework uses them as context to generate suggested actions for the message. The system limits the number of previous messages it considers to the value of previousMessagesLimit. This parameter defaults to an empty array if you don't include previous messages.

No APIs match your filter.

← More in Apple Intelligence, ML & Evaluation