diff --git a/DemoSwiftApp/AppDelegate.swift b/DemoSwiftApp/AppDelegate.swift index ef90be51c..53d741c3c 100644 --- a/DemoSwiftApp/AppDelegate.swift +++ b/DemoSwiftApp/AppDelegate.swift @@ -49,7 +49,8 @@ class AppDelegate: UIResponder, UIApplicationDelegate { // - initialize immediately with the given JSON datafile or its cached copy // - no network delay, but the local copy is not guaranteed to be in sync with the server experiment settings - initializeOptimizelySDKWithCustomization() + //initializeOptimizelySDKWithCustomization() + initializeOptimizelySDKWithClientConfiguration() } // MARK: - Initialization Examples @@ -94,17 +95,47 @@ class AppDelegate: UIResponder, UIApplicationDelegate { func initializeOptimizelySDKWithCustomization() { // customization example (optional) - + let customLogger = CustomLogger() // 30 sec interval may be too frequent. This is for demo purpose. // This should be should be much larger (default = 10 mins). let customDownloadIntervalInSecs = 30 + + optimizely = OptimizelyClient(sdkKey: sdkKey, + logger: customLogger, + periodicDownloadInterval: customDownloadIntervalInSecs, + defaultLogLevel: logLevel) + + addListeners() + + // initialize SDK + optimizely!.start { result in + switch result { + case .failure(let error): + print("Optimizely SDK initiliazation failed: \(error)") + case .success: + print("Optimizely SDK initialized successfully!") + } + self.startWithRootViewController() + } + } + + func initializeOptimizelySDKWithClientConfiguration() { + + var clientConfig = OptimizelyClientConfig() + clientConfig.defaultLogLevel = .debug + clientConfig.periodicDownloadInterval = 10*60 + clientConfig.fetchDatafileResourceTimeout = 5*60 + clientConfig.fetchDatafileRequestTimeout = 60 + clientConfig.customEventEndPoint = "https://google.com" + clientConfig.eventBatchInterval = 0 // disable batching + clientConfig.eventBatchSize = 20 + clientConfig.eventQueueMaxSize = 1000 + clientConfig.optInForCertficatePinning = false optimizely = OptimizelyClient(sdkKey: sdkKey, - logger: customLogger, - periodicDownloadInterval: customDownloadIntervalInSecs, - defaultLogLevel: logLevel) - + clientConfig: clientConfig) + addListeners() // initialize SDK diff --git a/OptimizelySDK/Customization/DefaultEventDispatcher.swift b/OptimizelySDK/Customization/DefaultEventDispatcher.swift index 7e3d8cfa6..60b140f04 100644 --- a/OptimizelySDK/Customization/DefaultEventDispatcher.swift +++ b/OptimizelySDK/Customization/DefaultEventDispatcher.swift @@ -47,7 +47,10 @@ open class DefaultEventDispatcher: BackgroundingCallbacks, OPTEventDispatcher { // timer as a atomic property. var timer: AtomicProperty = AtomicProperty() - public init(batchSize: Int = 10, backingStore: DataStoreType = .file, dataStoreName: String = "OPTEventQueue", timerInterval: TimeInterval = 60*1 ) { + public init(batchSize: Int = 10, + backingStore: DataStoreType = .file, + dataStoreName: String = "OPTEventQueue", + timerInterval: TimeInterval = 60*1 ) { self.batchSize = batchSize > 0 ? batchSize : 1 self.backingStore = backingStore self.backingStoreName = dataStoreName diff --git a/OptimizelySDK/Data Model/DispatchEvents/EventForDispatch.swift b/OptimizelySDK/Data Model/DispatchEvents/EventForDispatch.swift index 332ac67f5..8ebc3138e 100644 --- a/OptimizelySDK/Data Model/DispatchEvents/EventForDispatch.swift +++ b/OptimizelySDK/Data Model/DispatchEvents/EventForDispatch.swift @@ -17,7 +17,7 @@ import Foundation @objcMembers public class EventForDispatch: NSObject, Codable { - static let eventEndpoint = "https://logx.optimizely.com/v1/events" + static var eventEndpoint = "https://logx.optimizely.com/v1/events" public let url: URL public let body: Data diff --git a/OptimizelySDK/Optimizely/OptimizelyClient.swift b/OptimizelySDK/Optimizely/OptimizelyClient.swift index 500996281..eb5042261 100644 --- a/OptimizelySDK/Optimizely/OptimizelyClient.swift +++ b/OptimizelySDK/Optimizely/OptimizelyClient.swift @@ -63,7 +63,6 @@ open class OptimizelyClient: NSObject { /// - logger: custom Logger /// - eventDispatcher: custom EventDispatcher (optional) /// - userProfileService: custom UserProfileService (optional) - /// - periodicDownloadInterval: custom interval for periodic background datafile download (optional. default = 10 * 60 secs) /// - defaultLogLevel: default log level (optional. default = .info) public init(sdkKey: String, logger: OPTLogger? = nil, @@ -89,6 +88,67 @@ open class OptimizelyClient: NSObject { logger.d("SDK Version: \(version)") } + /// Optimizely Manager + /// + /// - Parameters: + /// - sdkKey: sdk key + /// - logger: custom Logger + /// - eventDispatcher: custom EventDispatcher (optional) + /// - userProfileService: custom UserProfileService (optional) + /// - clientConfig: custom SDK configuration + public init(sdkKey: String, + logger: OPTLogger? = nil, + eventDispatcher: OPTEventDispatcher? = nil, + userProfileService: OPTUserProfileService? = nil, + clientConfig: OptimizelyClientConfig) { + + self.sdkKey = sdkKey + + super.init() + + // use default settings if no custom settings provided + + let clientConfig = clientConfig ?? OptimizelyClientConfig() + + // UserProfileService + + let userProfileService = userProfileService ?? DefaultUserProfileService() + + // Logger + + let logger = logger ?? DefaultLogger() + type(of: logger).logLevel = clientConfig.defaultLogLevel + logger.d("SDK Version: \(version)") + + // EventDispatcher + + let eventDispatcher = eventDispatcher ?? DefaultEventDispatcher(batchSize: clientConfig.eventBatchSize, + timerInterval: clientConfig.eventBatchInterval) + if let eventEndPoint = clientConfig.customEventEndPoint { + EventForDispatch.eventEndpoint = eventEndPoint + } + + // DatafileHandler + + let datafileHandler = DefaultDatafileHandler() + datafileHandler.setTimer(sdkKey: sdkKey, interval: Int(clientConfig.periodicDownloadInterval)) + + // DecisionService + + let decisionService = DefaultDecisionService(userProfileService: userProfileService) + + // NotificationCenter + + let notificationCenter = DefaultNotificationCenter() + + self.registerServices(sdkKey: sdkKey, + logger: logger, + eventDispatcher: eventDispatcher, + datafileHandler: datafileHandler, + decisionService: decisionService, + notificationCenter: notificationCenter) + } + /// Start Optimizely SDK (Asynchronous) /// /// If an updated datafile is available in the server, it's downloaded and the SDK is configured with diff --git a/OptimizelySDK/Optimizely/OptimizelyClientConfig.swift b/OptimizelySDK/Optimizely/OptimizelyClientConfig.swift new file mode 100644 index 000000000..32c27cc71 --- /dev/null +++ b/OptimizelySDK/Optimizely/OptimizelyClientConfig.swift @@ -0,0 +1,55 @@ +// +/**************************************************************************** +* Copyright 2019, Optimizely, Inc. and contributors * +* * +* Licensed under the Apache License, Version 2.0 (the "License"); * +* you may not use this file except in compliance with the License. * +* You may obtain a copy of the License at * +* * +* http://www.apache.org/licenses/LICENSE-2.0 * +* * +* Unless required by applicable law or agreed to in writing, software * +* distributed under the License is distributed on an "AS IS" BASIS, * +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * +* See the License for the specific language governing permissions and * +* limitations under the License. * +***************************************************************************/ + +import Foundation + +public struct OptimizelyClientConfig { + + /// Default logger level (.error, .warning, .info, .debug) + public var defaultLogLevel: OptimizelyLogLevel = .info + + /// Custom interval for periodic background datafile download (seconds) + /// If set to 0, background polling is disabled + public var periodicDownloadInterval: TimeInterval = 10*60 + /// Timeout for datafile download completion (seconds) + /// If not set, `URLSessionConfiguration.timeoutIntervalForResource` default value is used (7 days) + public var fetchDatafileResourceTimeout: TimeInterval? + /// Timout for datafile request (seconds) + /// If not set, `URLSessionConfiguration.timeoutIntervalForRequest` default value is used (60 secs) + public var fetchDatafileRequestTimeout: TimeInterval? + /// This is for debugging purposes when you don't want to download the datafile. + /// In practice, you should allow the background thread to update the cache copy + public var doFetchDatafileBackground: Bool = false + + /// URL endpoint for event dispatch + /// If not overriden, all events are sent to the default optimizely server url (https://logx.optimizely.com/v1/events). + public var customEventEndPoint: String? + /// Custom Interval for periodic dispatch of batched events (seconds) + /// If set to 0, events are dispatched immediately (no batching) + public var eventBatchInterval: TimeInterval = 1*60 + /// Maximum number of events to be batched into a single batch event + public var eventBatchSize: Int = 10 + /// Maximum number of events that can be queued + /// If overflowed, the oldest events are discarded + public var eventQueueMaxSize: Int = 30000 + + /// Enable certficate pinning for extra security + public var optInForCertficatePinning: Bool = false + + public init() {} + +} diff --git a/OptimizelySDK/OptimizelySwiftSDK.xcodeproj/project.pbxproj b/OptimizelySDK/OptimizelySwiftSDK.xcodeproj/project.pbxproj index c5e8f7d3a..cc14497d5 100644 --- a/OptimizelySDK/OptimizelySwiftSDK.xcodeproj/project.pbxproj +++ b/OptimizelySDK/OptimizelySwiftSDK.xcodeproj/project.pbxproj @@ -346,6 +346,16 @@ 6E4F0D992213A4EF00DD13A5 /* Project.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E4F0D962213A4EF00DD13A5 /* Project.swift */; }; 6E4F0D9A2213A4EF00DD13A5 /* Project.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6E4F0D962213A4EF00DD13A5 /* Project.swift */; }; 6E53A6692203872600EA3A61 /* Optimizely.h in Headers */ = {isa = PBXBuildFile; fileRef = 6EBAEB6E21E3FEF800D13AA9 /* Optimizely.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 6E55DD7122CC18F9009E3B7F /* OptimizelyClientConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6EF7E34322CAC5AD002145B5 /* OptimizelyClientConfig.swift */; }; + 6E55DD7222CC18FB009E3B7F /* OptimizelyClientConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6EF7E34322CAC5AD002145B5 /* OptimizelyClientConfig.swift */; }; + 6E55DD7322CC18FC009E3B7F /* OptimizelyClientConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6EF7E34322CAC5AD002145B5 /* OptimizelyClientConfig.swift */; }; + 6E55DD7422CC18FD009E3B7F /* OptimizelyClientConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6EF7E34322CAC5AD002145B5 /* OptimizelyClientConfig.swift */; }; + 6E55DD7522CC18FE009E3B7F /* OptimizelyClientConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6EF7E34322CAC5AD002145B5 /* OptimizelyClientConfig.swift */; }; + 6E55DD7622CC18FE009E3B7F /* OptimizelyClientConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6EF7E34322CAC5AD002145B5 /* OptimizelyClientConfig.swift */; }; + 6E55DD7722CC18FF009E3B7F /* OptimizelyClientConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6EF7E34322CAC5AD002145B5 /* OptimizelyClientConfig.swift */; }; + 6E55DD7822CC1900009E3B7F /* OptimizelyClientConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6EF7E34322CAC5AD002145B5 /* OptimizelyClientConfig.swift */; }; + 6E55DD7922CC1901009E3B7F /* OptimizelyClientConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6EF7E34322CAC5AD002145B5 /* OptimizelyClientConfig.swift */; }; + 6E55DD7A22CC1902009E3B7F /* OptimizelyClientConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6EF7E34322CAC5AD002145B5 /* OptimizelyClientConfig.swift */; }; 6E614DD621E3F38A005982A1 /* Optimizely.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6E614DCD21E3F389005982A1 /* Optimizely.framework */; }; 6E636B912236C91F00AF3CEF /* Optimizely.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6EBAEB6C21E3FEF800D13AA9 /* Optimizely.framework */; }; 6E636BA02236C96700AF3CEF /* Optimizely.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6EBAEB6C21E3FEF800D13AA9 /* Optimizely.framework */; }; @@ -1050,13 +1060,16 @@ 6EF4B4E422383632002DE8B6 /* AtomicProperty.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0BE644EC223821D3009A5D1D /* AtomicProperty.swift */; }; 6EF4B4E5223836C1002DE8B6 /* BackgroundingCallbacks.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0B77D05722370526005AA83F /* BackgroundingCallbacks.swift */; }; 6EF4B4E6223836C1002DE8B6 /* BackgroundingCallbacks.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0B77D05722370526005AA83F /* BackgroundingCallbacks.swift */; }; + 6EF7E34422CAC5AD002145B5 /* OptimizelyClientConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6EF7E34322CAC5AD002145B5 /* OptimizelyClientConfig.swift */; }; + 6EF7E34522CAC5AD002145B5 /* OptimizelyClientConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6EF7E34322CAC5AD002145B5 /* OptimizelyClientConfig.swift */; }; 6EFAB05022A57FB100800884 /* ProjectConfigTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6EFAB04F22A57FB100800884 /* ProjectConfigTests.swift */; }; 6EFAB05122A57FB100800884 /* ProjectConfigTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6EFAB04F22A57FB100800884 /* ProjectConfigTests.swift */; }; 6EFAB05522A58DCB00800884 /* EventForDispatchTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6EFAB05422A58DCB00800884 /* EventForDispatchTests.swift */; }; 6EFAB05622A58DCB00800884 /* EventForDispatchTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6EFAB05422A58DCB00800884 /* EventForDispatchTests.swift */; }; 6EFAB05A22A5D51100800884 /* OptimizelyClientTests_Others.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6EFAB05922A5D51100800884 /* OptimizelyClientTests_Others.swift */; }; 6EFAB06822A6E75000800884 /* OptimizelyErrorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6EFAB06722A6E75000800884 /* OptimizelyErrorTests.swift */; }; - 7D709BF221602C0F885D19AD /* Pods_OptimizelySwiftSDK_tvOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1B04909B698F3888941B202B /* Pods_OptimizelySwiftSDK_tvOS.framework */; }; + C72BD1BB22B12E63003A55E4 /* LoggerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C72BD1BA22B12E63003A55E4 /* LoggerTests.swift */; }; + C72BD1BC22B12E63003A55E4 /* LoggerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C72BD1BA22B12E63003A55E4 /* LoggerTests.swift */; }; C737D50022ABDA400081AFEB /* AttributeValue.swift in Sources */ = {isa = PBXBuildFile; fileRef = C737D4FE22ABDA400081AFEB /* AttributeValue.swift */; }; C737D50122ABDA400081AFEB /* AttributeValue.swift in Sources */ = {isa = PBXBuildFile; fileRef = C737D4FE22ABDA400081AFEB /* AttributeValue.swift */; }; C737D50222ABDA400081AFEB /* AttributeValue.swift in Sources */ = {isa = PBXBuildFile; fileRef = C737D4FE22ABDA400081AFEB /* AttributeValue.swift */; }; @@ -1081,8 +1094,6 @@ C737D51522ABDA400081AFEB /* ConditionLeaf.swift in Sources */ = {isa = PBXBuildFile; fileRef = C737D4FF22ABDA400081AFEB /* ConditionLeaf.swift */; }; C737D51622ABDA400081AFEB /* ConditionLeaf.swift in Sources */ = {isa = PBXBuildFile; fileRef = C737D4FF22ABDA400081AFEB /* ConditionLeaf.swift */; }; C737D51722ABDA400081AFEB /* ConditionLeaf.swift in Sources */ = {isa = PBXBuildFile; fileRef = C737D4FF22ABDA400081AFEB /* ConditionLeaf.swift */; }; - C72BD1BB22B12E63003A55E4 /* LoggerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C72BD1BA22B12E63003A55E4 /* LoggerTests.swift */; }; - C72BD1BC22B12E63003A55E4 /* LoggerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C72BD1BA22B12E63003A55E4 /* LoggerTests.swift */; }; C737D52622ABEFCA0081AFEB /* DecisionServiceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C737D52422ABEFCA0081AFEB /* DecisionServiceTests.swift */; }; C737D52722ABEFCA0081AFEB /* DecisionServiceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C737D52422ABEFCA0081AFEB /* DecisionServiceTests.swift */; }; C737D52822ABEFCA0081AFEB /* OptimizelyErrorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = C737D52522ABEFCA0081AFEB /* OptimizelyErrorTests.swift */; }; @@ -1340,6 +1351,7 @@ 6EDE919822273DD700840112 /* optimizely_6372300739_v4.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = optimizely_6372300739_v4.json; sourceTree = ""; }; 6EDE91A122273DD700840112 /* typed_audience_datafile.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = typed_audience_datafile.json; sourceTree = ""; }; 6EDE91A422273DD700840112 /* UnsupportedVersionDatafile.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = UnsupportedVersionDatafile.json; sourceTree = ""; }; + 6EF7E34322CAC5AD002145B5 /* OptimizelyClientConfig.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OptimizelyClientConfig.swift; sourceTree = ""; }; 6EFAB04F22A57FB100800884 /* ProjectConfigTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProjectConfigTests.swift; sourceTree = ""; }; 6EFAB05422A58DCB00800884 /* EventForDispatchTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EventForDispatchTests.swift; sourceTree = ""; }; 6EFAB05922A5D51100800884 /* OptimizelyClientTests_Others.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OptimizelyClientTests_Others.swift; sourceTree = ""; }; @@ -1350,9 +1362,9 @@ 8B522E5E2D6FEE76A247A4D1 /* Pods-OptimizelySwiftSDK-tvOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-OptimizelySwiftSDK-tvOS.release.xcconfig"; path = "Target Support Files/Pods-OptimizelySwiftSDK-tvOS/Pods-OptimizelySwiftSDK-tvOS.release.xcconfig"; sourceTree = ""; }; AED4B61B2F7C775E23D39EBB /* Pods-OptimizelyTests-Common-iOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-OptimizelyTests-Common-iOS.release.xcconfig"; path = "Target Support Files/Pods-OptimizelyTests-Common-iOS/Pods-OptimizelyTests-Common-iOS.release.xcconfig"; sourceTree = ""; }; B2925B8EB22C8B6628168A73 /* Pods-OptimizelySwiftSDK-tvOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-OptimizelySwiftSDK-tvOS.debug.xcconfig"; path = "Target Support Files/Pods-OptimizelySwiftSDK-tvOS/Pods-OptimizelySwiftSDK-tvOS.debug.xcconfig"; sourceTree = ""; }; + C72BD1BA22B12E63003A55E4 /* LoggerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoggerTests.swift; sourceTree = ""; }; C737D4FE22ABDA400081AFEB /* AttributeValue.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AttributeValue.swift; sourceTree = ""; }; C737D4FF22ABDA400081AFEB /* ConditionLeaf.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConditionLeaf.swift; sourceTree = ""; }; - C72BD1BA22B12E63003A55E4 /* LoggerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoggerTests.swift; sourceTree = ""; }; C737D52422ABEFCA0081AFEB /* DecisionServiceTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DecisionServiceTests.swift; sourceTree = ""; }; C737D52522ABEFCA0081AFEB /* OptimizelyErrorTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OptimizelyErrorTests.swift; sourceTree = ""; }; C79F9D852251F58F002B0BC9 /* DecisionListenerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DecisionListenerTests.swift; sourceTree = ""; }; @@ -1698,6 +1710,7 @@ 6E4DD8EE21E530A900B0C2C7 /* OptimizelyResult.swift */, 6E4DD8EF21E530A900B0C2C7 /* OptimizelyError.swift */, 6E7C0B7321F1372100ECFF34 /* OptimizelyLogLevel.swift */, + 6EF7E34322CAC5AD002145B5 /* OptimizelyClientConfig.swift */, ); path = Optimizely; sourceTree = ""; @@ -2670,6 +2683,7 @@ 0B4E11FD21EE90F600D5B370 /* DataStoreUserDefaults.swift in Sources */, 0B77D04122331E0D005AA83F /* OptimizelyClient+Extension.swift in Sources */, C737D50122ABDA400081AFEB /* AttributeValue.swift in Sources */, + 6EF7E34522CAC5AD002145B5 /* OptimizelyClientConfig.swift in Sources */, 0B7B9EC421F2ACB100056589 /* DataStoreFile.swift in Sources */, 0B77D05922370526005AA83F /* BackgroundingCallbacks.swift in Sources */, 0B4E11FA21EE8FF400D5B370 /* OPTDataStore.swift in Sources */, @@ -2725,7 +2739,6 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 6E4F0D7C22133C5A00DD13A5 /* AttributeValue.swift in Sources */, 6E4DD8D021E5261600B0C2C7 /* ProjectConfig.swift in Sources */, 0B7B188C2232DB8600A1F85D /* DataStoreMemory.swift in Sources */, 6EA4265422191EEC00B074B5 /* Array+Extension.swift in Sources */, @@ -2740,6 +2753,7 @@ 6E4DD8FC21E530A900B0C2C7 /* OptimizelyClient.swift in Sources */, 6EDBCE212272333B009DF724 /* OptimizelyClient+ObjC.swift in Sources */, 6E8D321B2266905F00478458 /* LogMessage.swift in Sources */, + 6E55DD7522CC18FE009E3B7F /* OptimizelyClientConfig.swift in Sources */, 6E4F0D9A2213A4EF00DD13A5 /* Project.swift in Sources */, 6E4DD8C821E5261600B0C2C7 /* TrafficAllocation.swift in Sources */, 6E4DD8B421E5260700B0C2C7 /* OPTLogger.swift in Sources */, @@ -2793,7 +2807,6 @@ buildActionMask = 2147483647; files = ( 6E636BB02236C98300AF3CEF /* DefaultUserProfileService.swift in Sources */, - 6E636BE22236C9B700AF3CEF /* ConditionLeaf.swift in Sources */, 0BAB9B0122567E34000DC388 /* (null) in Sources */, 6E636BA82236C97E00AF3CEF /* OptimizelyError.swift in Sources */, 6E636BC62236C99D00AF3CEF /* DefaultDecisionService.swift in Sources */, @@ -2817,6 +2830,7 @@ 6E636BAF2236C98300AF3CEF /* DefaultEventDispatcher.swift in Sources */, 6E8CB5C9224C461A00B8CB7A /* OptimizelyClientTests_Variables.swift in Sources */, 6E636BA92236C97E00AF3CEF /* OptimizelyLogLevel.swift in Sources */, + 6E55DD7922CC1901009E3B7F /* OptimizelyClientConfig.swift in Sources */, 6E636BE02236C9B700AF3CEF /* Audience.swift in Sources */, 6E636C192236CBE400AF3CEF /* OTUtils.swift in Sources */, 6E636C622237182000AF3CEF /* OptimizelyClientTests_Evaluation.swift in Sources */, @@ -2886,6 +2900,7 @@ 6E636BAB2236C97E00AF3CEF /* OptimizelyResult.swift in Sources */, 6E636BC82236C99E00AF3CEF /* DefaultBucketer.swift in Sources */, 6E636BBE2236C99400AF3CEF /* DataStoreUserDefaults.swift in Sources */, + 6E55DD7622CC18FE009E3B7F /* OptimizelyClientConfig.swift in Sources */, 6EDBCE202272333B009DF724 /* OptimizelyClient+ObjC.swift in Sources */, 6E8D321A2266905F00478458 /* LogMessage.swift in Sources */, 6E636BFC2236C9BD00AF3CEF /* Variation.swift in Sources */, @@ -3022,6 +3037,7 @@ 6EA425882218E69800B074B5 /* OptimizelySwiftSDKiOSTests.swift in Sources */, 6ED1B8FB2225AA6500C4C774 /* DefaultUserProfileServiceTests.swift in Sources */, 6EA425452218E4A300B074B5 /* Attribute.swift in Sources */, + 6E55DD7422CC18FD009E3B7F /* OptimizelyClientConfig.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -3066,6 +3082,7 @@ 6EA426212218E74F00B074B5 /* DataStoreFile.swift in Sources */, 6EA425AC2218E6AE00B074B5 /* AttributeTests.swift in Sources */, 6EA426342218E74F00B074B5 /* UserAttribute.swift in Sources */, + 6E55DD7322CC18FC009E3B7F /* OptimizelyClientConfig.swift in Sources */, 6EA426482218E74F00B074B5 /* HandlerRegistryService.swift in Sources */, 6EA425A12218E6AE00B074B5 /* AttributeValueTests.swift in Sources */, 6EA4259E2218E6AE00B074B5 /* ConditionHolderTests_Evaluate.swift in Sources */, @@ -3129,7 +3146,6 @@ 6EDBCE1C2272333B009DF724 /* OptimizelyClient+ObjC.swift in Sources */, 0B7B18892232DB8400A1F85D /* DataStoreMemory.swift in Sources */, 6E0AFBC52257C49800BC7665 /* BucketTests_BucketVariation.swift in Sources */, - 6EA425CD2218E74D00B074B5 /* AttributeValue.swift in Sources */, 0B104B01228E156200BE87A8 /* BatchEventBuilderTests_Events.swift in Sources */, 0BE644F0223821D3009A5D1D /* AtomicProperty.swift in Sources */, C72BD1BB22B12E63003A55E4 /* LoggerTests.swift in Sources */, @@ -3157,6 +3173,7 @@ 6EA425B82218E74D00B074B5 /* DataStoreQueueStackImpl.swift in Sources */, 6EA425C72218E74D00B074B5 /* EventForDispatch.swift in Sources */, 0BC47BD62242F7EF00E5C2CD /* DatafileHandlerTests.swift in Sources */, + 6E55DD7A22CC1902009E3B7F /* OptimizelyClientConfig.swift in Sources */, 6E0AFBC12257C49800BC7665 /* BucketTests_GroupToExp.swift in Sources */, 6E8CB5A2224BF4BE00B8CB7A /* DecisionServiceTests_Features.swift in Sources */, 6EA425D42218E74D00B074B5 /* Event.swift in Sources */, @@ -3248,6 +3265,7 @@ 6EA425ED2218E74E00B074B5 /* DataStoreFile.swift in Sources */, 6EA4259D2218E6AD00B074B5 /* AttributeTests.swift in Sources */, 6EA426002218E74E00B074B5 /* UserAttribute.swift in Sources */, + 6E55DD7822CC1900009E3B7F /* OptimizelyClientConfig.swift in Sources */, 6EA426142218E74E00B074B5 /* HandlerRegistryService.swift in Sources */, 6EA425922218E6AD00B074B5 /* AttributeValueTests.swift in Sources */, 6EA4258F2218E6AD00B074B5 /* ConditionHolderTests_Evaluate.swift in Sources */, @@ -3326,6 +3344,7 @@ 6EA426C2221925CD00B074B5 /* DefaultDatafileHandler.swift in Sources */, 6EA426BF221925CD00B074B5 /* DefaultBucketer.swift in Sources */, 6EA426782219259800B074B5 /* HandlerRegistryService.swift in Sources */, + 6E55DD7722CC18FF009E3B7F /* OptimizelyClientConfig.swift in Sources */, 6EA426CB221925DE00B074B5 /* OptimizelyClient.swift in Sources */, 6EA42694221925B100B074B5 /* FeatureFlag.swift in Sources */, 6EA4267F2219259E00B074B5 /* ArrayEventForDispatch+Extension.swift in Sources */, @@ -3394,6 +3413,7 @@ 6EA426C7221925CE00B074B5 /* DefaultBucketer.swift in Sources */, 6EA4267C2219259900B074B5 /* HandlerRegistryService.swift in Sources */, 6EA426D5221925DF00B074B5 /* OptimizelyClient.swift in Sources */, + 6E55DD7222CC18FB009E3B7F /* OptimizelyClientConfig.swift in Sources */, 6EA426A7221925B300B074B5 /* FeatureFlag.swift in Sources */, 6EA42683221925A000B074B5 /* ArrayEventForDispatch+Extension.swift in Sources */, 6EA426B4221925BC00B074B5 /* OPTDecisionService.swift in Sources */, @@ -3480,6 +3500,7 @@ 6E7C0B7421F1372100ECFF34 /* OptimizelyLogLevel.swift in Sources */, 0BC48EA522038491003AFD71 /* ArrayEventForDispatch+Extension.swift in Sources */, 6E4DD85221E5250200B0C2C7 /* OPTDatafileHandler.swift in Sources */, + 6EF7E34422CAC5AD002145B5 /* OptimizelyClientConfig.swift in Sources */, 6E4DD83B21E524EF00B0C2C7 /* DefaultEventDispatcher.swift in Sources */, 6E4DD86721E5251200B0C2C7 /* Audience.swift in Sources */, 6E4DD84921E524FB00B0C2C7 /* Constants.swift in Sources */, @@ -3514,6 +3535,7 @@ 0B77D04222331E0E005AA83F /* OptimizelyClient+Extension.swift in Sources */, 6E4DD8A921E5260600B0C2C7 /* OPTLogger.swift in Sources */, 6E4DD88D21E525FC00B0C2C7 /* DefaultLogger.swift in Sources */, + 6E55DD7122CC18F9009E3B7F /* OptimizelyClientConfig.swift in Sources */, 0B7B9EC521F51AF600056589 /* DataStoreFile.swift in Sources */, 6EDBCE1B2272333A009DF724 /* OptimizelyClient+ObjC.swift in Sources */, 6E4DD8C321E5261500B0C2C7 /* FeatureFlag.swift in Sources */,