Wellspent is a Screen Time SDK that allows you to lock distracting apps until your users complete a specific action in your app. It's plug-and-play and comes with pre-built UI screens you can customize to your IU. Most apps get their native screen time feature live within 2-3 days with the SDK.
Here's how
- Configure Wellspent SDK, Wellspent's Screen Time SDK within your app.
- Wellspent SDK locks distracting apps until your users complete an action in your app, based on your SDK settings.
-
Event-based App Blocking: Full screen take-over that reminds your users to use your app when they open distracting apps during their self-set schedule. Distracting apps are unlocked after a specific event in your app is fired (e.g. session started, session completed).
-
Custom UI Control: You can customize our pre-built UI to have full control over the visual style of the screen time feature in your app (onboarding screens, full-screen nudges, settings screen).
-
Analytics: Analyze adoption and nudging rates in real-time, either in your analytics provider or with our dashboards.
- iOS 16.0+
- Swift 5.9+
- Xcode 16.0+
public class Wellspent {
static let shared: Wellspent
func configure(properties: WellspentSDKProperties, theme: WellspentTheme? = nil, trackingHandler: WellspentTrackingService? = nil) async -> Bool
func start(onComplete: (() -> Void)? = nil, onDismiss: (() -> Void)? = nil)
func showNudgeSettings(onFinish: (() -> Void)? = nil)
func completeHabit()
func isHabitCompleted() -> Bool?
}
To initialize the SDK with your app properties, you can use the configuration structure. Reach out to us at https://www.wellspent.so/demo for an API Key.
struct WellspentSDKProperties {
init(
apiKey: String,
name: String,
bundleId: String,
appGroupIdentifier: String,
activity: String? = nil,
successCriteria: String? = nil
)
}
WellspentSDK requires you to add 3 separate app extension targets to your project namely the DeviceActivityMonitorExtension
, ShieldActionExtension
and the ShieldConfigurationExtension
.
- To Create a New Target
- Open Xcode.
- Go to
File
>New
>Target
. - Search for extension.
- Select it and click
Next
. - Set a suitable name.
- Click
Finish
.
Add an app group with to all extension targets and your main app.
-
Enable App Group
- Select the newly created extensions targets.
- Go to
Signing & Capabilities
. - Click
+ Capability
and addApp Groups
. - Add
$(YOUR_APP_GROUP_NAME)
. - Repeat for all app extension targets and your main app
- Add the AppGroup to Info.plist for all extension targets
<dict> <key>AppGroup</key> <string>YOUR_APPGROUP_NAME</string> ..... </dict>
Caution
The Wellspent SDK will not work without the app extensions and their respective app groups
capability being set up. The app group name must be added to the Info.plist
for every extension target.
With the app extensions created, request for the Family Controls Entitlement (Distribution) from Apple. This is neccessary to go live in the App Store but not a requirement for local development. It's preferable to request the entitlement soon after creating the app extensions.
Follow our guide to request the Family Controls (Distribution) Entitlement.
Ensure the SDK is added to your project via Swift Package Manager.
dependencies: [
.package(url: "https://github.com/nlbb/Wellspent-iOS-SDK-Binaries.git", branch: "main")
]
- Add the
Extension_DeviceActivityMonitor
framework to theDeviceActivityMonitor
extension target - Add the
Extension_ShieldAction
framework to theShieldActionExtension
target - Add the
Extension_ShieldConfiguration
framework to theShieldConfigurationExtension
target - Add the
Wellspent
framework to the main app target
- Open
DeviceActivityMonitorExtension.swift
and replace all existing code with snippet below
import Extension_DeviceActivityMonitor
class YourDeviceMonitorExtension: Extension_DeviceActivityMonitor.ActivityMonitorExtension {}
- Open
ShieldActionExtension.swift
and replace all existing code with snippet below
import Extension_ShieldAction
class ShieldActionExtension: Extension_ShieldAction.ShieldActionExtension {}
- Open
ShieldConfigurationExtension.swift
and replace all existing code with snippet below.
import Extension_ShieldConfiguration
class ShieldConfigurationExtension: Extension_ShieldConfiguration.ShieldConfigurationExtension {}
Initialize it in your application's entry point with the provided API key and further properties, using the initialize method.
Doing this as early as possible ensures the SDK is ready for use. This method will fail synchronously if and only if the passed arguments are invalid. This method does depend on network connectivity.
import WellspentSDK
Task {
let result = await Wellspent.shared.configure(
properties: WellspentSDKProperties(
apiKey: "INSERT-YOUR-API-KEY",
name: "APP_NAME",
bundleId: "APP_BUNDLE_ID",
appGroupIdentifier: "YOUR_APP_GROUP",
activity: "APP_ACTIVITY e.g learning",
successCriteria: "SUCCESS_CRITERIA e.g lesson"
),
theme: CustomTheme(), // this is optional
trackingHandler: AnalyticsManager() // this is optional
)
}
To track user interactions and screen view (e.g. toggling nudge settings),
implement the WellspentTrackingService
protocol and pass an instance to configure
.
This allows you to forward analytics events to your provider (e.g., Firebase, Mixpanel).
Create a class that conforms to WellspentTrackingService
to receive analytics events.
class AnalyticsManager: WellspentTrackingService {
func trackScreenView(screenName: String, properties: [String: Any]?) {
// Forward screen view to your analytics provider
}
func trackEvent(eventName: String, properties: [String: Any]?) {
// Forward event to your analytics provider
}
}
You can kick-off user onboarding by invoking the start
method
Usually this call should be initiated in response some user action, such as tapping a "Connect" button.
Wellspent.shared.start(
onComplete: {
// Handle scenario when user completed onboarding flow
},
onDismiss: {
// Handle scenario when user cancels the onboarding flow
}
)
Users can customize their nudge schedules and manage distracting apps directly through the SDK. This can be achieved by invoking the showNudgeSettings
method, which presents a user interface for modifying these preferences.
import WellspentSDK
Wellspent.shared.showNudgeSettings(onFinish: {
// Handle scenario when user finishes editing nudge settings
})
This method allows users to adjust their nudge schedules to better align with their goals and specify which apps they find distracting. By enabling this feature, you empower users to take control of their app usage patterns, fostering a more intentional and productive experience.
When users complete their daily habit, developers should call the completeDailyHabit
method to unlock the apps.
This action notifies the Wellspent that the user's daily goal has been achieved, triggering updates to ensure the intervention mechanism reflects the completion status.
By doing so, users regain access to their apps, reinforcing positive behavior and habit formation.
import WellspentSDK
WellspentSDK.shared.completeDailyHabit()
To customise the colors and typography of the SDK screens, you need to create a class that conforms to WellspentTheme
protocol. This protocol exposes the cutomisable UI elements on the SDK.
You can initialize the Color values in various ways, including using hex values, named colors, RGB values etc.
struct CustomTheme: WellspentTheme {
// Background colors
var backgroundPrimary: Color { Color("BackgroundPrimary") }
var backgroundSecondary: Color { Color("BackgroundSecondary") }
var backgroundTertiary: Color { Color("BackgroundTertiary") }
var backgroundShield: Color { Color("BackgroundShield") }
// Label colors
var labelPrimary: Color { Color("LabelPrimary") }
var labelSecondary: Color { Color("LabelSecondary") }
var labelTertiary: Color { Color("LabelTertiary") }
// Button colors
var backgroundButton: Color { Color("BackgroundButton") }
var backgroundButtonDisabled: Color { Color("BackgroundButtonDisabled") }
var buttonLabel: Color { Color("ButtonLabel") }
var buttonLabelDisabled: Color { Color("ButtonLabelDisabled") }
// Other colors
var fills: Color { Color("Fills") }
}
For automatic support of both light and dark mode, define your colors in an Asset Catalog:
- Open your Asset Catalog (Assets.xcassets)
- Create a new Color Set for each theme color (e.g., "BackgroundPrimary")
- Select the Color Set and enable "Any, Dark" appearance in the Attributes Inspector
- Set different colors for light and dark appearances
During SDK configuration:
let result = await Wellspent.shared.configure(
properties: WellspentSDKProperties(
// Your configuration properties
),
theme: CustomTheme(),
trackingHandler: trackingHandler
)
After configuration, using the apply method:
Wellspent.shared.apply(theme: CustomTheme())