A novel approach to feature toggles for Swift programmers.
Feature toggles, also known as “feature flags,” are a tool to keep a team of developers contributing to the mainline without revealing half-implemented features on their releases.
The FeatureToggles
package provides a mechanism for declaring toggles
in a decentralized manner. Those toggles can stay turned off in RELEASE
builds,
keeping the main branch deployable. However, you can turn them on in other
environments so developers and testers can access them.
Compared to other solutions for managing toggles, FeatureToggles
presents several advantages.
- It’s distributed. Different modules can provide new toggles to their clients. That’s great for modular projects.
- It’s ergonomic. Inspired by SwiftUI’s
environment
, it lets you access any toggle with a simple@FeatureToggle
-annotated property. - It’s versatile. Turn features on or off depending on whether it’s a
DEBUG
orRELEASE
build, or override the default via a specially-formatted URL. - It’s strongly typed. Leveraging the power of Swift’s type system, it reduces errors and enhances code readability and maintainability.
- It’s lightweight. Just a few lines of code, zero dependencies.
First, declare a FeatureToggleKey
. You can extend an existing data structure:
extension TeleportView: FeatureToggleKey, ReleaseDisabled, DebugEnabled {}
Or create a brand new entity:
enum TeleportFeatureToggle: FeatureToggleKey, ReleaseDisabled, DebugEnabled {}
Note
The ReleaseEnabled
, ReleaseDisabled
, DebugEnabled
, and DebugDisabled
indicate the default toggle behavior. Four combinations are possible:
ReleaseDisabled
,DebugDisabled
ReleaseDisabled
,DebugEnabled
ReleaseEnabled
,DebugDisabled
ReleaseEnabled
,DebugEnabled
Then, add a getter for your new key.
extension FeatureToggleValues {
var teleport: Bool { self[TeleportView.self] }
}
Finally, use the @FeatureToggle
property wrapper whenever
you wish to access the current state of the toggle.
struct ContentView: View {
@FeatureToggle(\.teleport) var isTeleportButtonEnabled
var body: some View {
VStack {
Text("Welcome to our app")
.font(.title)
if isTeleportButtonEnabled {
TeleportView()
}
}
}
}
Your app can override compile-time defaults with a specially-formatted URL.
First, add a featureToggleIdentifier
to your key:
extension TeleportView: FeatureToggleKey, ReleaseDisabled, DebugEnabled {
static let featureToggleIdentifier = "teleport"
}
Then, call FeatureToggleValues.override(withValuesFrom:)
when the app delegate opens a URL.
In an iOS application, it would look something like this:
public func application(
_: UIApplication,
open url: URL,
options _: [UIApplication.OpenURLOptionsKey: Any] = [:]
) -> Bool {
FeatureToggleValues.override(withValuesFrom: url)
}
If your app’s custom URL is myapp
, this link would enable the feature
even in RELEASE
builds with a disabled compile-time toggle:
myapp://toggle?id=teleport&value=true
This library is released under the MIT license. See LICENSE for details.