Latest 1.0
License MIT
Platforms ios 9.0




pod "ABTestKit"


Copy ABTestKit.swift file to your project.


Copy ABTestKit+.swift found in the Example project and define your tests inside the extension to ABTestKit.Test struct.
An A/B Test is initialized with a name and variants using an enum with the following options:

  • ab: control and test variant with 50% weight each
  • split: n number of variants where weight for each equals 1÷n
  • weighted: custom defined weights

Optionally add a convenience initializer to add defaults values, formatting, etc.

extension ABTestKit.Test {
    static let featureNumberOne = ABTestKit.Test(name: "feature_1", date: "010101") // 50-50 split
    static let featureNumberTwo = ABTestKit.Test(name: "feature_2", date: "030202", variants: .split([.control, .test, "test2", "test3"])) // even 25% each
    static let featureNumberThree = ABTestKit.Test(name: "feature_3", date: "030303", variants: .weighted([(.control, 0.9), (.test, 0.1)])) // 90-10 split

    // Convenience initializer
    init(name: String, date: String, variants: ABTestKit.Variants = .ab) {
        let formattedName = "(date)_(name)"
        self.init(name: formattedName, variants: variants)

Use the shared singleton property to setup the framework:

  • Enable all the active tests

  • React to bucketing events (optional)

  • Migrate the buckets in UserDefaults to the key defined in the Configuration object (optional)
extension ABTestKit {
    static let shared: ABTestKit = {
        let testKit = ABTestKit(tests:
            .featureNumberOne, .featureNumberTwo, .featureNumberThree
        testKit.migrate(from: "PreviousABTestValues")

        testKit.variantAllocated = { variant, test in
            // Make API call to update the server, report an event, print log, etc.
        return testKit

Optional: Expose the tests to Objective-C by returning their name, since Obj-C can’t see the Test struct.

extension ABTestKit {
    static var featureNumberOne: TestName { return }
    static var featureNumberTwo: TestName { return }
    static var featureNumberThree: TestName { return }


Perform logic based on buckets

try! ABTestKit.shared.runTest(.featureNumberOne
    , control: {
        performSegue(withIdentifier: "control", sender: self)
    , test: {
        performSegue(withIdentifier: "test", sender: self)

// Trailing closure will default to `test`
try! ABTestKit.shared.runTest(.featureNumberOne) {
        performSegue(withIdentifier: "test", sender: self)

Multiple test buckets

try! ABTestKit.shared.runTest(.featureNumberTwo, handlers: {
    // control
    view.backgroundColor = .white
}, {
    // test
    view.backgroundColor = .red
}, {
    // test2
    view.backgroundColor = .green
}, {
    // test3
    view.backgroundColor = .blue

Hide (or show) views

button.isHidden = try! ABTestKit.shared.isTestVariant(for: .featureNumberThree)

Control flow

guard try! ABTestKit.shared.isTestVariant(for: .featureNumberThree) else { return }

Exclude control bucket

if try! ABTestKit.shared.isTestVariant(for: .featureNumberTwo) {
    // Any test bucket
    print("Not control bucket")


Initialize with custom configuration

let configuration = ABTestKit.Configuration(tests: .featureNumberOne, .featureNumberTwo, .featureNumberThree,
                                            userDefaultsKey: "com.acme.ABTests")
let testKit = ABTestKit(configuration: configuration)

Override buckets

try! ABTestKit.shared.setVariant(.control, for: .featureNumberOne)

Reset all buckets


Access all active tests

print(ABTestKit.shared.allTests) // ["feature_1", "feature_2", "feature_3"]

Access the selected buckets for tests

print(ABTestKit.shared.variantsByTestName) // [["feature_1: "control"], ["feature_2": "test2"], ["feature_3: "test"]]


Yariv Nissim | yar1vn

Latest podspec

    "name": "ABTestKit",
    "version": "1.0",
    "summary": "AB Tests framework in Swift  3.",
    "description": "Use ABTestKit to randomly bukcet users, and run code based on these buckets quickly and easily with closures.nThis framework supports Obj-C but is designed with Swift in mind.",
    "homepage": "",
    "license": {
        "type": "MIT",
        "file": "LICENSE"
    "authors": {
        "Yariv Nissim": "[email protected]"
    "source": {
        "git": "",
        "tag": "1.0"
    "social_media_url": "",
    "platforms": {
        "ios": "9.0"
    "source_files": "ABTestKit/Classes/**/*",
    "pushed_with_swift_version": "3.0"

Pin It on Pinterest

Share This