Protocol
Presentable
The base protocol for all presenters.
@MainActor protocol Presentable : AnyObject
Mentioned In
Overview
Presentable is @MainActor-isolated so views — UIKit UIViewControllers or SwiftUI Views — can read presenter state synchronously, without hopping isolation domains.
Overview
Feature-specific Presentable protocols extend this protocol to declare the methods that the interactor calls on the presenter. Those methods are typically async: the interactor is an actor, the presenter is @MainActor, and crossing isolation domains requires await.
Because the annotation lives on this base protocol, every feature Presentable — and any var listener requirement it declares — is @MainActor-isolated by inheritance. A @MainActor view controller therefore satisfies the conformance with requirement and witness in the same isolation domain, so the Swift 6 diagnostic “Main actor-isolated property ‘listener’ cannot be used to satisfy nonisolated protocol requirement” cannot arise for this seam. See Cross-Isolation Patterns for the full reasoning.
You have two options for who conforms to a feature-specific Presentable:
A dedicated Presenter subclass (recommended when there is non-trivial view-state to hold). The view controller holds the presenter and SwiftUI reads its stored properties directly (@Bindable locally in body for two-way bindings), or UIKit observes them via Observations { ... }; either way the view controller stays a thin renderer.
The view controller itself, when there is no separate state to hold and the presenter would just delegate every method to the view controller anyway.
Both styles compose with PresentableInteractable — only the conforming type changes.
Usage
protocol HomePresentable: Presentable {
func presentUser(_ user: User) async
func presentLogoutFailure(_ message: String) async
}
See Also
Presenter
See Also
PresentableInteractable
See Also
ViewControllable
Relationships
Conforming Types