Message Center message view

Show a single Message Center message with MessageCenterMessageView, add a navigation bar, customize the message view style, or render only the message body.

View as Markdown

The message view shows a single Message Center message. Use it alongside your own list view, or to deep link directly to a message.

  • MessageCenterMessageView shows the message with no navigation bar.
  • MessageCenterMessageViewWithNavigation adds a navigation bar with a title and delete button.
  • MessageCenterMessageContentView renders only the message body, so you provide all surrounding UI.

MessageCenterMessageView

Show a message by its ID. Provide a dismissAction to handle closing the view.

Show a message

import SwiftUI
import AirshipMessageCenter

struct MyMessageScreen: View {
    let messageID: String

    var body: some View {
        MessageCenterMessageView(messageID: messageID) {
            // Handle dismiss
        }
    }
}

MessageCenterMessageViewWithNavigation

MessageCenterMessageViewWithNavigation wraps the message in a navigation bar with a title and a delete button. It’s the destination used by MessageCenterContent when a message is selected.

public init(
    messageID: String,
    title: String? = nil,
    showBackButton: Bool? = nil,
    dismissAction: (@MainActor () -> Void)? = nil
)
  • title: The title shown until the message loads. The final title comes from the message.
  • showBackButton: Whether to show a back button. When unset, the back button appears only when the view is presented modally.
  • dismissAction: Called when the view is dismissed.

The delete button is hidden when hideDeleteButton is set in the theme.

Custom message view style

To customize the message presentation, implement MessageViewStyle and return your own view from makeBody(configuration:). The configuration provides the message view model and the dismiss action.

Custom message view style

struct CustomMessageViewStyle: MessageViewStyle {
    func makeBody(configuration: Configuration) -> some View {
        NavigationStack {
            MessageCenterMessageView(
                viewModel: configuration.viewModel,
                dismissAction: configuration.dismissAction
            )
            .navigationTitle("Message")
        }
    }
}

Apply the style with the .messageCenterMessageViewStyle(_:) modifier:

MessageCenterView()
    .messageCenterMessageViewStyle(CustomMessageViewStyle())

MessageCenterMessageContentView

MessageCenterMessageContentView renders only the message body (either a web body or a native (SceneA mobile app or web experience of one or more screens displayed with fully native UI components in real time, providing immediate, contextual responses to user behaviors. Scenes can be presented in full-screen, modal, or embedded format using the default swipe/click mode or as a story. Scene content can also be displayed in a Message Center message and contain survey questions.) layout). It has no loading indicator, error UI, retry, or mark-as-read behavior. Instead, it reports its state through a phase binding so you can provide your own chrome. Use it when you need complete control over everything around the message content.

public init(
    viewModel: MessageCenterMessageViewModel,
    phase: Binding<MessageCenterMessageContentPhase>,
    dismissAction: (@MainActor @Sendable () -> Void)? = nil
)

Set the phase to .loading to load the content. The view updates the binding to .loaded or .error(_:) as it loads:

Render message content

import SwiftUI
import AirshipMessageCenter

struct MyMessageContentScreen: View {
    @StateObject
    private var viewModel: MessageCenterMessageViewModel

    @State
    private var phase: MessageCenterMessageContentPhase = .loading

    init(messageID: String) {
        _viewModel = .init(wrappedValue: MessageCenterMessageViewModel(messageID: messageID))
    }

    var body: some View {
        ZStack {
            MessageCenterMessageContentView(viewModel: viewModel, phase: $phase)

            switch phase {
            case .loading:
                ProgressView()
            case .error:
                Text("Unable to load message")
            case .loaded:
                EmptyView()
            }
        }
    }
}