diff --git a/Sources/OnboardingKit/Documentation.docc/Extensions/OnboardingConditions.md b/Sources/OnboardingKit/Documentation.docc/Extensions/OnboardingConditions.md index f3caf15..acb4619 100644 --- a/Sources/OnboardingKit/Documentation.docc/Extensions/OnboardingConditions.md +++ b/Sources/OnboardingKit/Documentation.docc/Extensions/OnboardingConditions.md @@ -6,6 +6,8 @@ - ``ColdLaunch`` - ``ManualCounter`` +- ``Once`` - ``TimeSinceFirstLaunch`` - ``AfterDate`` +- ``Conjunction`` - ``Disjunction`` diff --git a/Sources/OnboardingKit/Documentation.docc/OnboardingKit.md b/Sources/OnboardingKit/Documentation.docc/OnboardingKit.md index 69ddc1c..ebae09f 100644 --- a/Sources/OnboardingKit/Documentation.docc/OnboardingKit.md +++ b/Sources/OnboardingKit/Documentation.docc/OnboardingKit.md @@ -10,7 +10,7 @@ The top-level component of OnboardingKit is ``OnboardingManager``. Typically, yo An ``OnboardingManager`` instance contains a collection of onboarding events, which are represented as instances of the ``OnboardingEvent`` class. Each ``OnboardingEvent`` instance represents a particular event that might occur as the user uses your app. When an onboarding event occurs, OnboardingKit can notify your app in one of two ways: it can set a property on a ”flags” object (*i.e.*, an instance of a class that conforms to the ``OnboardingFlags`` protocol) that you specify, or it can just call a handler function that you provide. -Each onboarding event contains a collection of onboarding conditions, which are structures that conform to the ``OnboardingCondition`` protocol. An event is triggered when **all** of its conditions are satisfied. All of the built-in conditions are contained in the ``OnboardingConditions`` namespace. To enable more dynamic onboarding flows, OnboardingKit provides a special ``OnboardingConditions/Disjunction`` condition that’s satisfied when **any** of its child conditions are satified. +Each onboarding event contains a collection of onboarding conditions, which are structures that conform to the ``OnboardingCondition`` protocol. An event is triggered when **all** of its conditions are satisfied. All of the built-in conditions are contained in the ``OnboardingConditions`` namespace. To enable more dynamic onboarding flows, OnboardingKit provides a special ``OnboardingConditions/Disjunction`` condition that’s satisfied when **any** of its child conditions are satified as well as an ``OnboardingConditions/Conjunction`` condition that’s satisfied when **all** of its child conditions are satisfied, which is useful for nesting inside of a disjunction condition. Events must be intentionally checked to see if they have been triggered; OnboardingKit won’t update your UI unless some event is checked and determined to have occured. Currently, OnboardingKit provides two ways to check events: it can check them automatically every time your app launches, and it can check them when you manually call ``OnboardingManager/checkManually()``. Each event automatically determines the manner in which it’s checked, so it’s a good idea to call ``OnboardingManager/checkManually()`` whenever you think that an onboarding event could possibly have occured. More automated ways to check events may be added in the future. diff --git a/Sources/OnboardingKit/OnboardingCondition.swift b/Sources/OnboardingKit/OnboardingCondition.swift index 9d8b572..b47f286 100644 --- a/Sources/OnboardingKit/OnboardingCondition.swift +++ b/Sources/OnboardingKit/OnboardingCondition.swift @@ -163,6 +163,33 @@ public enum OnboardingConditions { } + /// A condition that’s satisfied on the first cold launch and never again. + public struct Once: OnboardingCondition { + + public static var triggers: Set = [.launch] + + public var isSatisfied: Bool { + get { + if UserDefaults.standard.bool(forKey: self.defaultsKey) { + return false + } else { + UserDefaults.standard.set(true, forKey: self.defaultsKey) + return true + } + } + } + + /// The key that’s used to store the Boolean flag for this condition with `UserDefaults`. + public let defaultsKey: String + + /// Creates a “once” condition. + /// - Parameter defaultsKey: The key that’s used to store the Boolean flag for this condition with `UserDefaults`. + public init(defaultsKey: String) { + self.defaultsKey = defaultsKey + } + + } + /// A condition that checks how much time has passed since the first launch. @available(iOS 15, macOS 12, watchOS 8, tvOS 15, *) public struct TimeSinceFirstLaunch: RegistrableOnboardingCondition {