ActionSession
public class ActionSession : CustomDebugStringConvertible
An ActionSession is used to group a bunch of Action invocations, ensure they are invoked on the expected queue, and track the Action Stacks that result from performing actions.
The session used for an action invocation is recorded in Flint timelines and logs to aid in debugging.
The default ActionSession.main
session provided is what your UI will use most of the time. However if
your application supports multiple concurrent windows or documents you may wish to create more so that
you can see timeline and log events broken down per window or document, e.g. with the session name equal to the
document name or a symbolic equivalent of it for privacy. This way you can see what the user is doing in a multi-context environment.
Furthermore, if your application performs background tasks you should consider creation a session for these.
The lifetime of an ActionStack can be tracked in logging and analytics and tied to a specific activity session,
and is demarcated by the first use of an action from a feature, and the action that indicates termination of the current feature
.
Threading
A session can be accessed from any queue or thread. The ActionSession.perform
method can be called directly or
via the StaticActionBinding
/VerifiedActionBinding
convenience perform
methods without knowing whether
the queue is correct for the action.
Actions can select which queue they will be called to perform
on, via their queue
property. This is always
the queue they will execute on, and may be entirely different from the session’s queue.
This mechanism guarantees that code calling into an ActionSession
does not need to care about the queue an Action expects,
and Actions do not need to care about the queue they are called on, thus eliminating excessive thread hops (AKA mmm, just DispatchQueue.async it
).
This reduces slushiness
and lag in UIs, and makes it easier to reason about the code.
The dispatcher will ensure that the Actions are called synchronously on their desired queue, even if that is the same as the current queue.
It will also make sure that they call their completion handler on the completion requirement’s callerQueue
, without excessive queue hops
so that if the caller is already on the correct thread, there is no async dispatch required.
!!! TODO: Extract protocol for easier testing
-
The default
ActionSession
used for user interactions with the app. This is similar to, but not identical to the idea ofDispatchQueue.main
. The action session is a higher level idea about what the user’s current activity is in the app. The features in use at any one time are inferred by the actions being performed in the action session.As such it is not possible to be using the same
Feature
more than once concurrently in the same action session. In the example of a multi-window or multi-tabbed application, you would create a new explicit action session per window or tab, and perform actions in those sessions to correctly track the activeFeature
(s).Declaration
Swift
public static let main: ActionSession
-
The name of the session, for debug, analytics and logging purposes
Declaration
Swift
public let name: String
-
Whether or not this session is for user-initiated actions rather than internal actions.
Declaration
Swift
public let userInitiatedActions: Bool
-
The dispatcher to use
Declaration
Swift
public let dispatcher: ActionDispatcher
-
The ActionStackTracker
Declaration
Swift
public let actionStackTracker: ActionStackTracker
-
The currently active action request. If this is non-nil, an action is currently being performed and awaiting completion
Declaration
Swift
public var currentActionStackEntry: ActionStackEntry?
-
Initialise a session
- param name: The name of the session, e.g.
main
orbgtasks
ordocument-3
- param userInitiatedActions: Set to
true
if by default the actions for this session are always initiated by the user. - param dispatch: The dispatcher to use, defaults to the global Flint dispatcher
- param actionStackTracker: The action stack tracker that will be used, defaults to the shared tracker instance
Declaration
Swift
public init(named name: String, userInitiatedActions: Bool, dispatcher: ActionDispatcher = Flint.dispatcher, actionStackTracker: ActionStackTracker = .instance)
- param name: The name of the session, e.g.
-
Call to set up the standard action start/stop logging
Declaration
Swift
public static func quickSetupMainSession()
-
Perform the action associated with a conditional request obtained from
ConditionalFeature.request
.This is how you execute actions that are not always available.
The completion handler is called on
callerQueue
of thisActionSession
- param conditionalRequest: The conditional request for the action to perform
- param presenter: The object presenting the outcome of the action
- param input: The value to pass as the input of the action
- param completion: The completion handler to call.
- param completionQueue: The queue to use when calling the completion handler.
Declaration
Swift
public func perform<FeatureType, ActionType>(_ conditionalRequest: VerifiedActionBinding<FeatureType, ActionType>, input: ActionType.InputType, presenter: ActionType.PresenterType, completion: ((ActionOutcome) -> ())? = nil, completionQueue: DispatchQueue? = nil)
-
Perform the action associated with a conditional request obtained from
ConditionalFeature.request
.This is how you execute actions that are not always available.
The completion handler is called on
callerQueue
of thisActionSession
- param conditionalRequest: The conditional request for the action to perform
- param input: The value to pass as the input of the action
- param completion: The completion handler to call.
- param completionQueue: The queue to use when calling the completion handler.
Declaration
Swift
public func perform<FeatureType, ActionType>(_ conditionalRequest: VerifiedActionBinding<FeatureType, ActionType>, input: ActionType.InputType, completion: ((ActionOutcome) -> ())? = nil, completionQueue: DispatchQueue? = nil) where ActionType.PresenterType == NoPresenter
-
Perform the action associated with a conditional request obtained from
ConditionalFeature.request
.This is how you execute actions that are not always available.
The completion handler is called on
callerQueue
of thisActionSession
- param conditionalRequest: The conditional request for the action to perform
- param presenter: The object presenting the outcome of the action
- param completion: The completion handler to call.
- param completionQueue: The queue to use when calling the completion handler.
Declaration
Swift
public func perform<FeatureType, ActionType>(_ conditionalRequest: VerifiedActionBinding<FeatureType, ActionType>, presenter: ActionType.PresenterType, completion: ((ActionOutcome) -> ())? = nil, completionQueue: DispatchQueue? = nil) where ActionType.InputType == NoInput
-
Perform the action associated with a conditional request obtained from
ConditionalFeature.request
.This is how you execute actions that are not always available.
The completion handler is called on
callerQueue
of thisActionSession
- param conditionalRequest: The conditional request for the action to perform
- param completion: The completion handler to call.
- param completionQueue: The queue to use when calling the completion handler.
Declaration
Swift
public func perform<FeatureType, ActionType>(_ conditionalRequest: VerifiedActionBinding<FeatureType, ActionType>, completion: ((ActionOutcome) -> ())? = nil, completionQueue: DispatchQueue? = nil) where ActionType.InputType == NoInput, ActionType.PresenterType == NoPresenter
-
Perform the action associated with a conditional request obtained from
ConditionalFeature.request
.This is how you execute actions that are not always available.
The completion handler is called on
callerQueue
of thisActionSession
- param presenter: The object presenting the outcome of the action
- param input: The value to pass as the input of the action
- param userInitiated: Set to
true
if the user explicitly chose to perform this action,false
if not - param source: Indicates where the request came from
- param completion: The completion handler to call.
- param completionQueue: The queue to use when calling the completion handler.
Declaration
Swift
public func perform<FeatureType, ActionType>(_ conditionalRequest: VerifiedActionBinding<FeatureType, ActionType>, input: ActionType.InputType, presenter: ActionType.PresenterType, userInitiated: Bool, source: ActionSource, completion: ((ActionOutcome) -> ())? = nil, completionQueue: DispatchQueue? = nil)
-
Perform the action associated with a conditional request obtained from
ConditionalFeature.request
.This is how you execute actions that are not always available.
The completion handler is called on
callerQueue
of thisActionSession
- param presenter: The object presenting the outcome of the action
- param input: The value to pass as the input of the action
- param userInitiated: Set to
true
if the user explicitly chose to perform this action,false
if not - param source: Indicates where the request came from
- param completionRequirement: The completion object to use.
- return: The completion status, indicating whether it was synchronously completed or not, and the result if so.
Declaration
Swift
public func perform<FeatureType, ActionType>(_ conditionalRequest: VerifiedActionBinding<FeatureType, ActionType>, input: ActionType.InputType, presenter: ActionType.PresenterType, userInitiated: Bool, source: ActionSource, completionRequirement: Action.Completion) -> Action.Completion.Status
-
Perform an action associated with an unconditional
Feature
.This is how you execute actions that are always available.
The completion handler is called on
callerQueue
of thisActionSession
- param actionBinding: The binding of the action to perform
- param presenter: The object presenting the outcome of the action
- param input: The value to pass as the input of the action
- param completion: The completion handler to call.
- param completionQueue: The queue to use when calling the completion handler.
Declaration
Swift
public func perform<FeatureType, ActionType>(_ actionBinding: StaticActionBinding<FeatureType, ActionType>, input: ActionType.InputType, presenter: ActionType.PresenterType, completion: ((ActionOutcome) -> ())? = nil, completionQueue: DispatchQueue? = nil)
-
Perform an action associated with an unconditional
Feature
.This is how you execute actions that are always available, when they have no presenter (
NoPresenter
) requirement.The completion handler is called on
callerQueue
of thisActionSession
- param actionBinding: The binding of the action to perform
- param completionQueue: The queue to use when calling the completion handler.
- param input: The value to pass as the input of the action
- param completion: The completion handler to call.
- param completionQueue: The queue to use when calling the completion handler.
Declaration
Swift
public func perform<FeatureType, ActionType>(_ actionBinding: StaticActionBinding<FeatureType, ActionType>, input: ActionType.InputType, completion: ((ActionOutcome) -> ())? = nil, completionQueue: DispatchQueue? = nil) where ActionType.PresenterType == NoPresenter
-
Perform an action associated with an unconditional
Feature
.This is how you execute actions that are always available, when they have no input (
NoInput
) requirement.The completion handler is called on
callerQueue
of thisActionSession
- param actionBinding: The binding of the action to perform
- param presenter: The presenter to pass to the action
- param completion: The completion handler to call.
- param completionQueue: The queue to use when calling the completion handler.
Declaration
Swift
public func perform<FeatureType, ActionType>(_ actionBinding: StaticActionBinding<FeatureType, ActionType>, presenter: ActionType.PresenterType, completion: ((ActionOutcome) -> ())? = nil, completionQueue: DispatchQueue? = nil) where ActionType.InputType == NoInput
-
Perform an action associated with an unconditional
Feature
.This is how you execute actions that are always available, when they have no input (
NoInput
) requirement and no presenter (NoPresenter
) requirement.The completion handler is called on
callerQueue
of thisActionSession
- param actionBinding: The binding of the action to perform
- param completion: The completion handler to call.
- param completionQueue: The queue to use when calling the completion handler.
Declaration
Swift
public func perform<FeatureType, ActionType>(_ actionBinding: StaticActionBinding<FeatureType, ActionType>, completion: ((ActionOutcome) -> ())? = nil, completionQueue: DispatchQueue? = nil) where ActionType.InputType == NoInput, ActionType.PresenterType == NoPresenter
-
Perform an action associated with an unconditional
Feature
.This is how you execute actions that are always available.
The completion handler is called on
callerQueue
of thisActionSession
- param actionBinding: The binding of the action to perform
- param presenter: The object presenting the outcome of the action
- param input: The value to pass as the input of the action
- param userInitiated: Set to
true
if the user explicitly chose to perform this action,false
if not - param source: Indicates where the request came from
- param completion: The completion handler to call.
- param completionQueue: The queue to use when calling the completion handler.
Declaration
Swift
public func perform<FeatureType, ActionType>(_ actionBinding: StaticActionBinding<FeatureType, ActionType>, input: ActionType.InputType, presenter: ActionType.PresenterType, userInitiated: Bool, source: ActionSource, completion: ((ActionOutcome) -> ())? = nil, completionQueue: DispatchQueue? = nil)
-
Perform an action associated with an unconditional
Feature
, returning completion status.This is how you execute actions that are always available.
The completion handler is called on
callerQueue
of thisActionSession
- param actionBinding: The binding of the action to perform
- param presenter: The object presenting the outcome of the action
- param input: The value to pass as the input of the action
- param userInitiated: Set to
true
if the user explicitly chose to perform this action,false
if not - param source: Indicates where the request came from
- param completionRequirement: The completion requirement to use.
- return: The completion status, indicating whether or not completion is being called synchronously, and including completion results.
Declaration
Swift
public func perform<FeatureType, ActionType>(_ actionBinding: StaticActionBinding<FeatureType, ActionType>, input: ActionType.InputType, presenter: ActionType.PresenterType, userInitiated: Bool, source: ActionSource, completionRequirement: Action.Completion) -> Action.Completion.Status
-
Declaration
Swift
public var debugDescription: String { get }