-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathExampleSwitchboard.swift
More file actions
127 lines (95 loc) · 4.64 KB
/
ExampleSwitchboard.swift
File metadata and controls
127 lines (95 loc) · 4.64 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
//
// ExampleSwitchboard.swift
// SwitchboardExample
//
// Created by Rob Phillips on 10/3/17.
// Copyright © 2017 Keepsafe Software Inc. All rights reserved.
//
import Switchboard
final class ExampleSwitchboard: Switchboard {
// MARK: - Constants
static let serverUrlString = "https://someServerUrlStringGoesHere.com"
// MARK: - Instantiation
static let shared = ExampleSwitchboard()
// MARK: - Properties
let analytics = ExampleSwitchboardAnalytics()
// MARK: - Activating
override func activate(serverUrlString: String, completion: SwitchboardClientCompletion?) {
// You should save the serverUrlString locally and use it in the download config method
let uuid = "uid456"
downloadConfiguration(for: uuid, completion: completion)
}
override func downloadConfiguration(for uuid: String, userData: [String : Any]? = nil, completion: SwitchboardClientCompletion?) {
// If we're debugging, just let it use the debugging cache
guard isDebugging == false else {
completion?(nil)
return
}
// Otherwise, fetch from the server
// If you need to join the default parameters with the user data, just use something like
// var parameters = SwitchboardProperties.defaults(withUuid: uuid)
// if let userData = userData {
// for (key, value) in userData {
// parameters[key] = value
// }
// }
// For this example, we'll just set the active & inactive features ourselves, but
// this is a similar order for what to do in your network success callback
if let json = ExampleSwitchboard.defaultExperimentsAndFeatures() {
// Active
experiments = SwitchboardExperimentFactory.from(json: json, analytics: analytics)
features = SwitchboardFeatureFactory.from(json: json, analytics: analytics)
// Inactive
inactiveExperiments = SwitchboardExperimentFactory.from(json: json, analytics: analytics, active: false)
inactiveFeatures = SwitchboardFeatureFactory.from(json: json, analytics: analytics, active: false)
// Cache these for any network outages or lags the next time they launch
SwitchboardCache.cache(experiments: experiments, features: features)
// Log any entitled experiments and features
let entitledExperiments = experiments.filter({ $0.isEntitled })
analytics.entitled(experiments: Set(entitledExperiments), features: features)
} else {
// Example of catching a JSON parsing error and returning it
let error = NSError(domain: "com.keepsafe.switchboard.errors", code: 1, userInfo: [NSLocalizedDescriptionKey: "Error turning the response into a JSON dictionary."])
completion?(error)
return
}
completion?(nil)
}
// MARK: - Private Instantiation
fileprivate override init() {
super.init()
restoreFromCache()
addPreventionLogic()
}
}
// MARK: - Private API
fileprivate extension ExampleSwitchboard {
// MARK: - Cache
func restoreFromCache() {
// Check if we should use debug cache
guard self.isDebugging == false else {
SwitchboardDebugController.restoreDebugCache(switchboard: self, analytics: self.analytics)
return
}
// Otherwise, use the non-debug cache and pass in the Switchboard and analytics provider where needed
let (experiments, features) = SwitchboardCache.restoreFromCache()
if let experiments = experiments {
self.experiments = Set(experiments.compactMap({ SwitchboardExperiment(name: $0.name, values: $0.values, switchboard: self, analytics: self.analytics) }))
}
if let features = features {
self.features = Set(features.compactMap({ SwitchboardFeature(name: $0.name, values: $0.values, analytics: self.analytics) }))
}
}
// MARK: - Prevention Logic
/// You can optionally add conditional logic for preventing experiments from starting or features from enabling
/// Sometimes you'll want to do this if you're using other A/B testing frameworks so you don't
/// run Switchboard experiments at the same time as other framework's experiments
func addPreventionLogic() {
preventExperimentFromStarting = { experimentName in
return experimentName == "somePreventedExperimentNameHere" // or other conditional logic
}
preventFeatureFromEnabling = { featureName in
return featureName == "somePreventedFeatureNameHere" // or other conditional logic
}
}
}