Structures
The following structures are available globally.
-
A
See morenull
state type for actions that do not require stateDeclaration
Swift
public struct NoInput : RouteParametersCodable, ActivityCodable, FlintLoggable
-
Represents the binding of an action to a specific unconditional
Feature
.These are use as the main entry point for performing actions, having been bound using the
action
function ofFeature
(provided by a protocol extension).
See moreclass DocumentManagementFeature: Feature { static let description = "Create documents" // This is where the binding is created static let createNew = action(DocumentCreateAction.self) static func prepare(actions: FeatureActionsBuilder) { actions.declare(createNew) } } ... later you can perform the action directly ... DocumentManagementFeature.createNew.perform( ... ) Note that you do not create these bindings explicitly, you must use the Flint `action` function for this.
Declaration
Swift
public struct StaticActionBinding<FeatureType, ActionType> : CustomDebugStringConvertible where FeatureType : FeatureDefinition, ActionType : Action
-
The input type for
See moreDismissUIAction
, which will automatically dismiss a presenter that is aUIViewController
on UIKit platforms.Declaration
Swift
public struct DismissUIInput : FlintLoggable
-
Action inputs that have per-instance metadata applicable to
See moreNSUserActivity
can conform toActivityMetadataRepresentable
and the metadata they return of this type will be automatically used by theActivities
feature to register the activity and an implicit Siri Shortcut if so desired.Declaration
Swift
public struct ActivityMetadata
-
A binding of feature and action for a conditional action that may not be available at runtime, depending on other factors e.g. feature flagging or IAPs.
You can call
request()
on such a binding to see if its available in order to perform it:public class TimelineFeature: ConditionalFeature { public static var availability: FeatureAvailability = .runtimeEvaluated public static var description: String = "Maintains an in-memory timeline of actions for debugging and reporting" public static var isAvailable: Bool? = true // ** This creates the conditional binding ** public static let loadData = action(LoadDataAction.self) public static func prepare(actions: FeatureActionsBuilder) { // Declare the action to Flint actions.declare(loadData) } } ... elsewhere when you need to perform the action ... if let request = TimelineFeature.loadData.request() { // Perform it in the main session. Use `ActionSession.perform` to use other sessions. request.perform(withInput: input, presenter: presenter) } else { fatalError("Should not have been able to chose this action, feature is disabled!") }
Note
This is a completely discrete type fromStaticActionBinding
so that you cannot callperform
with a conditional action, you must first request the conditional action using this binding, and then call perform with theVerifiedActionBinding
received from that.Declaration
Swift
public struct ConditionalActionBinding<FeatureType, ActionType> : CustomDebugStringConvertible where FeatureType : ConditionalFeature, ActionType : Action
-
A type used to prevent direct execution of actions on
ConditionalFeature
(s), such thatActionSession
only has functions to perform actions usingVerifiedActionBinding
and not aperform()
using aConditionalActionBinding
.This makes it impossible to directly perform an action of a conditional feature without first requesting access to it, as these request instances are only created by the framework and must be used to perform such actions.
The protocol extensions on
See moreConditionalFeature
only supportsrequest
and notperform
, forcing the caller to test if the feature is available first and at least explicitly ignore thefeature not available
path, but hopefully provide a code path for that.Declaration
Swift
public struct VerifiedActionBinding<FeatureType, ActionType> where FeatureType : ConditionalFeature, ActionType : Action
-
A container for the definition a single Feature’s constraints.
See moreDeclaration
Swift
public struct DeclaredFeatureConstraints
-
Values of this type represent a single constraint evaluation result, used to determine whether a constraint has been met or not.
You receive these values when the feature’s constraints have been evaluated by the
FeatureConstraintsEvaluator
, which returns aFeatureConstraintEvaluation
so that you can access the individual results.See
FeatureConstraintEvaluation
Declaration
Swift
public struct FeatureConstraintResult<T> : Hashable where T : FeatureConstraint
-
The container for constraint evaluation results.
Use this to examine all the constraints on the feature and whether they are active and/or fulfilled.
See moreDeclaration
Swift
public struct FeatureConstraintsEvaluation
-
A type that encapsulates information about the permission requirements of a feature, for easy access when determining what to do in your app when a Feature is not available.
Use
See morenotDetermined.count > 0
to detect when there are permissions that can be authorised.Declaration
Swift
public struct FeaturePermissionRequirements
-
The struct used to define a single platform and version constraint.
See moreDeclaration
Swift
public struct PlatformConstraint : Hashable, CustomStringConvertible
-
An encapsulation of a single Action Stack entry.
This is intentionally lightweight, so it does not retain objects from your app, using simplified representations instead.
This is explicitly immutable as entries cannot be changed after the fact.
See moreDeclaration
Swift
public struct ActionStackEntry : CustomDebugStringConvertible
-
An abstract
path
for log events.This is used to provide a simple hierarchical structure to log events to facilitate filtering and collapsing, mostly by Features but also arbitrary paths for non-Feature based subsystems.
See moreDeclaration
Swift
public struct TopicPath : Hashable, CustomStringConvertible, ExpressibleByArrayLiteral
-
Represents a topic path that you want to focus on for debugging.
This is an immutable wrapper used to allow the Focus feature to be used with either TopicPath or Feature.
See
FocusFeature
Declaration
Swift
public struct FocusArea : FlintLoggable, CustomStringConvertible, CustomDebugStringConvertible, Hashable
-
Provides access to the context specific loggers for a feature or action
See moreDeclaration
Swift
public struct ContextualLoggers
-
The context for a log event.
The same context should be used for multiple log events if the context remains the same, e.g. the topic is the same.
See moreDeclaration
Swift
public struct LogEventContext
-
This type provides access to the App’s loggers.
Logging in Flint is slightly different and solves several problems:
- Excessively noisy logs in non-development builds (a separate logger for debug logging, always silenced in production)
- The inability to tell what actual user activity a log entry relates to (see: topic paths, contextual logging)
- The typical reliance on a specific logging framework. Wire up whatever implementation you like here.
- Focusing on logs only related to specific application features, e.g. drill down into just your
Share
feature’s logging
Abstracting logging is one of the more laughable and tedious things in computing, after all how many ways do we need to log text? However nothing out there supports contextual logging and topic paths which are crucial for Flint. So here we are.
Flint’s logging is somewhat decoupled from the rest of Flint and works like this:
- Something in the App calls
Logging.development?.contextualLogger(...)
orLogging.production.contextualLogger(...)
to get a logger that has information about what the user is doing. - The resulting
ContextSpecificLogger
, if not nil is passed to subsystems that require logging. This is the biggest difference with other logging systems that assume the logger never changes. - The subsystems call one of the logging functions on the logger.
- The
ContextualLogger
delegates the actual logging to aContextualLoggerTarget
, which can filter events or log levels as desired - The
DefaultContextualLoggerTarget
filters events according to Focus rules, and sends output to aLoggerOutput
instance which is the final output of the log text.
The chain of execution is along these lines:
ContextualLogger
->ContextualLoggerTarget
->LoggerOutput
The
LoggerOutput
is the only think you need to implement for your logging framework, e.g. a layer that uses CocoaLumberjack or Apple’s log systems, or Fabric’sCLS_LOG
rolling log buffer.Production logging is always available, so that logger factory is not optional. Debug logging can be entirely disabled for production builds, resulting is close to zero overheads due to the optional dereferencing.
This solves the problem of polluting production logs with excessive internal debug info, without having to dial down log levels in production.
The implementation of
ContextualLoggerTarget
can peform filtering of events by topic path or other properties of thecontext
(seeDefaultLogger
) and thoseContextSpecificLogger
implementations then pass the logging info on to theLoggerOutput
implementation which writes to whatever output you desire.There is an
AggregatingLoggerOutput
provided so you can compose multiple log outputs easily and drive them from the same contextual loggers, e.g. to output to Console as well as an ASL log file.See
DefaultLoggerFactory.setup()
for the simple console logging used by default when usingFlint.quickSetup
.Declaration
Swift
public struct Logging
-
This type provides information about the purchases required for a single conditional feature.
You can use this at runtime to establish which purchases you need to show to the user to enable them to unlock a feature.
See moreDeclaration
Swift
public struct FeaturePurchaseRequirements
-
A wrapper that provides all the details of a successful url mapping lookup.
This is used to execution an action bound to a URL mapping, supplying the extra parameters parsed out of the URL itself.
See
`URLPatternDeclaration
Swift
public struct URLExecutionContext
-
Undocumented
Declaration
Swift
public struct URLMappingResult
-
A struct used to represent a route scope and path mapping to an action
See moreDeclaration
Swift
public struct URLMapping : Hashable, Equatable, CustomStringConvertible, CustomDebugStringConvertible