Skip to content

Reversi ⚫️⚪️ is an A/B testing framework for iOS written in Swift.

License

Notifications You must be signed in to change notification settings

popei69/reversi

Repository files navigation

Reversi ⚫️⚪️

Platform Language CI Status Version Swift Package Manager compatible Carthage compatible License

Reversi ⚫️⚪️ is an A/B testing framework written in Swift.

Read more about the motivation on my blog.

Content

Why Reversi?

  • Feature flags and A/B testing tools are designed for Product Marketers and Managers and forgot to be developer friendly. Adding A/B testing or feature flag should be as easy as setting up any properties.
  • Choose your service, keep your data. Reversi doesn't handle data, it should be designed to work with bundled file as well as remote services. You'll only inject your configuration at launch, Reversi will handle when to run UI variations.

Apptimize

Apptimize before Reversi

if (Apptimize.isFeatureFlagOn("new_feature_flag_variable")) {
   // ON
   myObject.customVariant()
} else {
   // OFF
   myObject.defaultVariant()
}

Apptimize with Reversi

myObject.defaultVariant()
myObject.addFeatureFlag("new_feature_flag_variable") { object in
    object.customVariant()
}

Read more about how to implement Reversi for Apptimze

Firebase

Firebase before Reversi

var welcomeMessage = remoteConfig[welcomeMessageConfigKey].stringValue

Firebase with Reversi

var welcomeMessage = "Welcome"
welcomeMessage.addVariation(welcomeMessageConfigKey, for: String.self) { welcomeMessage, newText in
    welcomeMessage = newText
}

Read more about how to implement Reversi for Firebase

Optimizely

Optimizely before Reversi

// Activate an A/B test
let variation = client?.activate("app_redesign", userId:"12122")
if (variation?.variationKey == "control") {
    // Execute code for "control" variation
    myObject.variantControl()
} else if (variation?.variationKey == "treatment") {
    // Execute code for "treatment" variation
    myObject.variantTreatment()
} else {
    // Execute code for users who don't qualify for the experiment
    myObject.defaultVariant()
}

Optimizely with Reversi

// Activate an A/B test
myObject.defaultVariant()
myObject
    .addVariation("app_redesign", for: Void.self, options: ["variable_key": "control"]) { myObject, _ in
        myObject.variantControl()
    }
    .addVariation("app_redesign", for: Void.self, options: ["variable_key": "treatment"]) { myObject, _ in
        myObject.variantControl()
    }

Read more about how to implement Reversi for Optimizely

How does it work?

Reversi includes variations and will execute only the one included in the running experiments. The key designed the unique identifier to that experiment.

// feed your configuration to the service from local json or remote service
ReversiService.shared.configure(with: configuration)

label.text = "Hello World"
label.font = UIFont.boldSystemFont(ofSize: 15)
label.textColor = .darkGray

// block will be executed only if "text_variation" experiment is up and running
label.addVariation("text_variation", for: String.self) { label, value in
    label.text = value // "Hello Variation World"
}

Usage

There is no limit to the number of variations and their access

label.addVariation("text_variation", for: String.self) { label, value in
    label.text = variationText
}
.addFeatureFlag("font_variation") { label in
    label.font = UIFont.boldSystemFont(ofSize: 14)
}

// button color
button.addFeatureFlag("button_variation") { button in
    button.backgroundColor = .orange
}

// combined elements
self.addFeatureFlag("combined_variation") { viewController in
    viewController.label.textColor = .lightGray
    viewController.button.setTitleColor(.lightGray, for: .normal)
}

Since each experiment directly affects UI elements, variations are only executed on main thread.

Installation

Swift Package Manager

let package = Package(
    ...
    dependencies: [
        .package(url: "https://github.com/popei69/reversi.git", from: "1.1.0")
    ],
    ...
)

CocoaPods

Reversi is available through CocoaPods. To install it, simply add the following line to your Podfile:

pod 'Reversi'

Carthage

Reversi is also available through Carthage.

github 'popei69/Reversi' ~> 1.0

Example

To run the example project, clone the repo, and run pod install from the Example directory first.

State of the project

  • Create a configuration file for bundled experiments
  • Ability to support variation in value: Void, Bool, Int, String.
  • Ability to support remote configuration: Apptimize, Firebase, Optimizely.
  • Unit tests for stability.
  • Ability to support amount of users affected per experiment

Author

Contact me on Twitter

Contributing

This project is still exploratory. I'm happy for anybody to create an issue for suggestions and improvements.

License

Reversi is available under the MIT license. See the LICENSE file for more info.

About

Reversi ⚫️⚪️ is an A/B testing framework for iOS written in Swift.

Resources

License

Stars

Watchers

Forks

Packages

No packages published