Skip to content

Commit dd17c28

Browse files
feat: add apiProxyURL to DevCycleOptions (#176)
* feat: add apiProxyURL to DevCycleOptions * fix: add docs to DevCycleOptions methods
1 parent af6164e commit dd17c28

File tree

6 files changed

+83
-9
lines changed

6 files changed

+83
-9
lines changed

DevCycle/DevCycleClient.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ public class DevCycleClient {
6767

6868
self.config = DVCConfig(sdkKey: sdkKey, user: user)
6969

70-
let service = DevCycleService(config: self.config!, cacheService: self.cacheService)
70+
let service = DevCycleService(config: self.config!, cacheService: self.cacheService, options: self.options)
7171

7272
self.initialize(service: service, callback: callback)
7373
}

DevCycle/Models/DevCycleOptions.swift

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
//
2-
// DVCOptions.swift
2+
// DevCycleOptions.swift
33
// DevCycle
44
//
5-
//
65

76
import Foundation
87

@@ -16,6 +15,7 @@ public class DevCycleOptions {
1615
var disableRealtimeUpdates: Bool = false
1716
var disableAutomaticEventLogging: Bool = false
1817
var disableCustomEventLogging: Bool = false
18+
var apiProxyURL: String?
1919

2020
public class OptionsBuilder {
2121
var options: DevCycleOptions
@@ -24,6 +24,7 @@ public class DevCycleOptions {
2424
self.options = DevCycleOptions()
2525
}
2626

27+
// Controls the interval between flushing events to the DevCycle servers in milliseconds, defaults to 10 seconds.
2728
public func flushEventsIntervalMs(_ interval: Int? = 10000) -> OptionsBuilder {
2829
self.options.flushEventsIntervalMs = interval
2930
return self
@@ -35,41 +36,54 @@ public class DevCycleOptions {
3536
return self
3637
}
3738

39+
// Disables logging of SDK generated events (e.g. variableEvaluated, variableDefaulted) to DevCycle.
3840
public func disableAutomaticEventLogging(_ disable: Bool) -> OptionsBuilder{
3941
self.options.disableAutomaticEventLogging = disable
4042
return self
4143
}
4244

45+
// Disables logging of custom events generated by calling .track() method to DevCycle.
4346
public func disableCustomEventLogging(_ disable: Bool) -> OptionsBuilder{
4447
self.options.disableCustomEventLogging = disable
4548
return self
4649
}
4750

51+
// Controls the log level of the SDK, defaults to `error`
4852
public func logLevel(_ level: LogLevel) -> OptionsBuilder {
4953
self.options.logLevel = level
5054
return self
5155
}
5256

57+
// Enables the usage of EdgeDB for DevCycle that syncs User Data to DevCycle.
5358
public func enableEdgeDB(_ enable: Bool) -> OptionsBuilder {
5459
self.options.enableEdgeDB = enable
5560
return self
5661
}
5762

63+
// Disable the use of cached configs
5864
public func disableConfigCache(_ disable: Bool) -> OptionsBuilder {
5965
self.options.disableConfigCache = disable
6066
return self
6167
}
6268

69+
// The maximum allowed age of a cached config in milliseconds, defaults to 7 days
6370
public func configCacheTTL(_ ttl: Int = 604800000) -> OptionsBuilder {
6471
self.options.configCacheTTL = ttl
6572
return self
6673
}
6774

75+
// Disable Realtime Update and their SSE connection.
6876
public func disableRealtimeUpdates(_ disable: Bool) -> OptionsBuilder {
6977
self.options.disableRealtimeUpdates = disable
7078
return self
7179
}
7280

81+
// Allows the SDK to communicate with a proxy of DevCycle APIs.
82+
public func apiProxyURL(_ proxyURL: String) -> OptionsBuilder {
83+
self.options.apiProxyURL = proxyURL
84+
return self
85+
}
86+
7387
public func build() -> DevCycleOptions {
7488
let result = self.options
7589
self.options = DevCycleOptions()

DevCycle/Networking/DevCycleService.swift

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,16 +71,18 @@ protocol DevCycleServiceProtocol {
7171
class DevCycleService: DevCycleServiceProtocol {
7272
var session: URLSession
7373
var config: DVCConfig
74+
var options: DevCycleOptions?
7475

7576
var cacheService: CacheServiceProtocol
7677
var requestConsolidator: RequestConsolidator!
7778

7879
private var newUser: DevCycleUser?
7980

80-
init(config: DVCConfig, cacheService: CacheServiceProtocol) {
81+
init(config: DVCConfig, cacheService: CacheServiceProtocol, options: DevCycleOptions? = nil) {
8182
let sessionConfig = URLSessionConfiguration.default
8283
self.session = URLSession(configuration: sessionConfig)
8384
self.config = config
85+
self.options = options
8486
self.cacheService = cacheService
8587
self.requestConsolidator = RequestConsolidator(service: self, cacheService: cacheService)
8688
}
@@ -243,18 +245,30 @@ class DevCycleService: DevCycleServiceProtocol {
243245

244246
switch(type) {
245247
case "event":
246-
url = NetworkingConstants.eventsUrl + NetworkingConstants.hostUrl
248+
if let proxyUrl = self.options?.apiProxyURL {
249+
url = proxyUrl
250+
} else {
251+
url = NetworkingConstants.eventsUrl + NetworkingConstants.hostUrl
252+
}
247253
url.append("\(NetworkingConstants.Version.v1)")
248254
url.append("\(NetworkingConstants.UrlPaths.events)")
249255
case "edgeDB":
250-
url = NetworkingConstants.sdkUrl + NetworkingConstants.hostUrl
256+
if let proxyUrl = self.options?.apiProxyURL {
257+
url = proxyUrl
258+
} else {
259+
url = NetworkingConstants.sdkUrl + NetworkingConstants.hostUrl
260+
}
251261
url.append("\(NetworkingConstants.Version.v1)")
252262
url.append("\(NetworkingConstants.UrlPaths.edgeDB)")
253263
if let userId = config.user.userId {
254264
url.append("/\(userId)")
255265
}
256266
default:
257-
url = NetworkingConstants.sdkUrl + NetworkingConstants.hostUrl
267+
if let proxyUrl = self.options?.apiProxyURL {
268+
url = proxyUrl
269+
} else {
270+
url = NetworkingConstants.sdkUrl + NetworkingConstants.hostUrl
271+
}
258272
url.append("\(NetworkingConstants.Version.v1)")
259273
url.append("\(NetworkingConstants.UrlPaths.config)")
260274
querySpecificItems.append(URLQueryItem(name: "sdkKey", value: config.sdkKey))

DevCycle/ObjC/ObjCDevCycleOptions.swift

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ public class ObjCDevCycleOptions: NSObject {
2121
@objc public var disableConfigCache: NSNumber?
2222
@objc public var configCacheTTL: NSNumber?
2323
@objc public var disableRealtimeUpdates: NSNumber?
24+
@objc public var disableAutomaticEventLogging: NSNumber?
25+
@objc public var disableCustomEventLogging: NSNumber?
26+
@objc public var apiProxyURL: NSString?
2427

2528
func buildDevCycleOptions() -> DevCycleOptions {
2629
var optionsBuilder = DevCycleOptions.builder()
@@ -54,6 +57,21 @@ public class ObjCDevCycleOptions: NSObject {
5457
optionsBuilder = optionsBuilder.disableRealtimeUpdates(disable)
5558
}
5659

60+
if let disableAutomaticEventLogging = self.disableAutomaticEventLogging,
61+
let disable = disableAutomaticEventLogging as? Bool {
62+
optionsBuilder = optionsBuilder.disableAutomaticEventLogging(disable)
63+
}
64+
65+
if let disableCustomEventLogging = self.disableCustomEventLogging,
66+
let disable = disableCustomEventLogging as? Bool {
67+
optionsBuilder = optionsBuilder.disableCustomEventLogging(disable)
68+
}
69+
70+
if let apiProxyURL = self.apiProxyURL,
71+
let proxyURL = apiProxyURL as? String {
72+
optionsBuilder = optionsBuilder.apiProxyURL(proxyURL)
73+
}
74+
5775
if let logLevel = self.logLevel,
5876
let level = logLevel as? Int {
5977
var setLogLevel = LogLevel.error

DevCycleTests/Models/DevCycleOptionsTest.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ class DevCycleOptionsTest: XCTestCase {
2121
.configCacheTTL(172800000)
2222
.disableConfigCache(true)
2323
.disableRealtimeUpdates(true)
24+
.disableCustomEventLogging(true)
25+
.disableAutomaticEventLogging(true)
26+
.apiProxyURL("localhost:4000")
2427
.build()
2528
XCTAssertNotNil(options)
2629
XCTAssert(options.flushEventsIntervalMs == 1000)
@@ -29,6 +32,9 @@ class DevCycleOptionsTest: XCTestCase {
2932
XCTAssert(options.configCacheTTL == 172800000)
3033
XCTAssert(options.disableConfigCache)
3134
XCTAssert(options.disableRealtimeUpdates)
35+
XCTAssert(options.disableCustomEventLogging)
36+
XCTAssert(options.disableAutomaticEventLogging)
37+
XCTAssert(options.apiProxyURL == "localhost:4000")
3238
}
3339

3440
func testBuilderReturnsOptionsAndSomeAreNil() {

DevCycleTests/Networking/DevCycleServiceTests.swift

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,14 @@ class DevCycleServiceTests: XCTestCase {
1515
XCTAssert(url!.contains("user_id=my_user"))
1616
}
1717

18+
func testProxyConfigURL() throws {
19+
let options = DevCycleOptions.builder().apiProxyURL("localhost:4000").build()
20+
let url = getService(options).createConfigRequest(user: getTestUser(), enableEdgeDB: false).url?.absoluteString
21+
XCTAssert(url!.contains("localhost:4000/v1/mobileSDKConfig"))
22+
XCTAssert(url!.contains("sdkKey=my_sdk_key"))
23+
XCTAssert(url!.contains("user_id=my_user"))
24+
}
25+
1826
func testCreateConfigURLRequestWithEdgeDB() throws {
1927
let url = getService().createConfigRequest(user: getTestUser(), enableEdgeDB: true).url?.absoluteString
2028
XCTAssert(url!.contains("https://sdk-api.devcycle.com/v1/mobileSDKConfig"))
@@ -29,12 +37,26 @@ class DevCycleServiceTests: XCTestCase {
2937
XCTAssertFalse(url!.contains("user_id=my_user"))
3038
}
3139

40+
func testProxyEventUrl() throws {
41+
let options = DevCycleOptions.builder().apiProxyURL("localhost:4000").build()
42+
let url = getService(options).createEventsRequest().url?.absoluteString
43+
XCTAssert(url!.contains("localhost:4000/v1/events"))
44+
XCTAssertFalse(url!.contains("user_id=my_user"))
45+
}
46+
3247
func testCreateSaveEntityRequest() throws {
3348
let url = getService().createSaveEntityRequest().url?.absoluteString
3449
XCTAssert(url!.contains("https://sdk-api.devcycle.com/v1/edgedb"))
3550
XCTAssert(url!.contains("my_user"))
3651
}
3752

53+
func testProxyEntityUrl() throws {
54+
let options = DevCycleOptions.builder().apiProxyURL("localhost:4000").build()
55+
let url = getService(options).createSaveEntityRequest().url?.absoluteString
56+
XCTAssert(url!.contains("localhost:4000/v1/edgedb"))
57+
XCTAssert(url!.contains("my_user"))
58+
}
59+
3860
func testProcessConfigReturnsNilIfMissingProperties() throws {
3961
let data = "{\"config\":\"key\"}".data(using: .utf8)
4062
let config = processConfig(data)
@@ -81,10 +103,10 @@ extension DevCycleServiceTests {
81103
}
82104
}
83105

84-
func getService() -> DevCycleService {
106+
func getService(_ options: DevCycleOptions? = nil) -> DevCycleService {
85107
let user = getTestUser()
86108
let config = DVCConfig(sdkKey: "my_sdk_key", user: user)
87-
return DevCycleService(config: config, cacheService: MockCacheService())
109+
return DevCycleService(config: config, cacheService: MockCacheService(), options: options)
88110
}
89111

90112
func getTestUser() -> DevCycleUser {

0 commit comments

Comments
 (0)