Skip to content

Commit 6a47839

Browse files
Prepare release 3.10.3 (#528)
* Upload task body issue fixed (#521) (cherry picked from commit a375e2b) * [FSSDK-9776] handle duplicate experiment key (#523) Logged for Duplicate keys (cherry picked from commit c2af8fe) * [FSSDK-9709] feat: App privacy manifest file added (#522) * Update CHANGELOG.md * Update README.md * Update swift.yml * Update run_unit_tests.sh
1 parent 5dafc99 commit 6a47839

File tree

10 files changed

+138
-12
lines changed

10 files changed

+138
-12
lines changed

.github/workflows/swift.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ on:
1717
description: release
1818

1919
env:
20-
VERSION: 3.10.2
20+
VERSION: 3.10.3
2121

2222
jobs:
2323

CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,15 @@
11
# Optimizely Swift SDK Changelog
22

3+
## 3.10.3
4+
December 5, 2023
5+
6+
### Bug Fixes
7+
* Remove redundant post request body in upload task. ([#521](https://github.com/optimizely/swift-sdk/pull/521/)).
8+
9+
### Enhancement
10+
* Add privacy manifest file ([#522](https://github.com/optimizely/swift-sdk/pull/522/)).
11+
* Handle duplicate keys in experiment ([#523](https://github.com/optimizely/swift-sdk/pull/523/)).
12+
313
## 3.10.2
414
March 14, 2023
515

OptimizelySwiftSDK.xcodeproj/project.pbxproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2457,6 +2457,7 @@
24572457
children = (
24582458
6E75167A22C520D400B2B157 /* Optimizely.h */,
24592459
6E75167B22C520D400B2B157 /* Info.plist */,
2460+
987F11D92AF3F56F0083D3F9 /* PrivacyInfo.xcprivacy */,
24602461
);
24612462
path = "Supporting Files";
24622463
sourceTree = "<group>";

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,15 +37,15 @@ Add the dependency on the Optimizely Swift SDK with Swift Package Manager in `Xc
3737
#### CocoaPods
3838
1. Add the following lines to the _Podfile_:<pre>
3939
```use_frameworks!```
40-
```pod 'OptimizelySwiftSDK', '~> 3.10.2'```
40+
```pod 'OptimizelySwiftSDK', '~> 3.10.3'```
4141
</pre>
4242

4343
2. Run the following command: <pre>``` pod install ```</pre>
4444

4545
Further installation instructions for Cocoapods: https://guides.cocoapods.org/using/getting-started.html
4646

4747
#### Carthage
48-
1. Add the following lines to the _Cartfile_:<pre>```github "optimizely/swift-sdk" ~> 3.10.2```</pre>
48+
1. Add the following lines to the _Cartfile_:<pre>```github "optimizely/swift-sdk" ~> 3.10.3```</pre>
4949

5050
2. Run the following command:<pre>```carthage update```</pre>
5151

Scripts/run_unit_tests.sh

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
#
88

99
# unit tests for PR only
10-
if [[ "$BRANCH" == "master" ]]
11-
then
10+
# if [[ "$BRANCH" == "master" ]]
11+
# then
1212
xcodebuild test -derivedDataPath $COVERAGE_DIR -workspace OptimizelySwiftSDK.xcworkspace -scheme $SCHEME -configuration Release CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO -sdk $TEST_SDK -destination "platform=$PLATFORM,OS=$OS,name=$NAME" ONLY_ACTIVE_ARCH=YES | tee buildoutput | xcpretty && test ${PIPESTATUS[0]} -eq 0
13-
fi
13+
# fi

Sources/Customization/DefaultEventDispatcher.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,6 @@ open class DefaultEventDispatcher: BackgroundingCallbacks, OPTEventDispatcher {
183183

184184
var request = URLRequest(url: event.url)
185185
request.httpMethod = "POST"
186-
request.httpBody = event.body
187186
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
188187

189188
// send notification BEFORE sending event to the server

Sources/Optimizely/OptimizelyClient.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -745,7 +745,7 @@ open class OptimizelyClient: NSObject {
745745
public func getOptimizelyConfig() throws -> OptimizelyConfig {
746746
guard let config = self.config else { throw OptimizelyError.sdkNotReady }
747747

748-
return OptimizelyConfigImp(projectConfig: config)
748+
return OptimizelyConfigImp(projectConfig: config, logger: logger)
749749
}
750750
}
751751

Sources/Optimizely/OptimizelyConfig.swift

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,8 @@ struct OptimizelyConfigImp: OptimizelyConfig {
9595
var attributes: [OptimizelyAttribute] = []
9696
var audiences: [OptimizelyAudience] = []
9797
var events: [OptimizelyEvent] = []
98-
99-
init(projectConfig: ProjectConfig) {
98+
99+
init(projectConfig: ProjectConfig, logger: OPTLogger = DefaultLogger()) {
100100
guard let project = projectConfig.project else { return }
101101

102102
self.environmentKey = project.environmentKey ?? ""
@@ -139,7 +139,7 @@ struct OptimizelyConfigImp: OptimizelyConfig {
139139
return updatedRollout
140140
}
141141

142-
self.experimentsMap = makeExperimentsMap(project: project, experiments: updatedExperiments)
142+
self.experimentsMap = makeExperimentsMap(project: project, experiments: updatedExperiments, logger: logger)
143143
self.featuresMap = makeFeaturesMap(project: project, experiments: updatedExperiments, rollouts: updatedRollouts)
144144
}
145145
}
@@ -148,9 +148,12 @@ struct OptimizelyConfigImp: OptimizelyConfig {
148148

149149
extension OptimizelyConfigImp {
150150

151-
func makeExperimentsMap(project: Project, experiments: [Experiment]) -> [String: Experiment] {
151+
func makeExperimentsMap(project: Project, experiments: [Experiment], logger: OPTLogger) -> [String: Experiment] {
152152
var map = [String: Experiment]()
153153
experiments.forEach {
154+
if map.keys.contains($0.key) {
155+
logger.w("Duplicate experiment keys found in datafile: \($0.key)")
156+
}
154157
map[$0.key] = $0
155158
}
156159
return map
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3+
<plist version="1.0">
4+
<dict>
5+
<key>NSPrivacyAccessedAPITypes</key>
6+
<array>
7+
<dict>
8+
<key>NSPrivacyAccessedAPITypeReasons</key>
9+
<array>
10+
<string>To store configuration and event data temporarily</string>
11+
</array>
12+
<key>NSPrivacyAccessedAPIType</key>
13+
<string>NSPrivacyAccessedAPICategoryUserDefaults</string>
14+
</dict>
15+
</array>
16+
</dict>
17+
</plist>

Tests/OptimizelyTests-APIs/OptimizelyClientTests_OptimizelyConfig.swift

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,64 @@ class OptimizelyClientTests_OptimizelyConfig: XCTestCase {
263263
let result = try? self.optimizely.getOptimizelyConfig()
264264
XCTAssertNil(result)
265265
}
266+
267+
func testOptimizelyConfigWithDuplicateKeys() {
268+
let exp0: [String : Any] = [
269+
"id": "10001",
270+
"key": "duplicate_key",
271+
"status": "Running",
272+
"layerId": "22222",
273+
"variations": [],
274+
"trafficAllocation": [],
275+
"audienceIds": ["33333"],
276+
"audienceConditions": [],
277+
"forcedVariations": ["12345": "1234567890"]
278+
]
279+
280+
let exp1: [String : Any] = [
281+
"id": "10005",
282+
"key": "duplicate_key",
283+
"status": "Running",
284+
"layerId": "22222",
285+
"variations": [],
286+
"trafficAllocation": [],
287+
"audienceIds": ["33333"],
288+
"audienceConditions": [],
289+
"forcedVariations": ["12345": "1234567890"]
290+
]
291+
292+
var projectData: [String: Any] = [
293+
"version": "4",
294+
"projectId": "11111",
295+
"experiments": [],
296+
"audiences": [],
297+
"groups": [],
298+
"attributes": [],
299+
"accountId": "1234567890",
300+
"events": [],
301+
"revision": "5",
302+
"anonymizeIP": true,
303+
"rollouts": [],
304+
"typedAudiences": [],
305+
"integrations": [],
306+
"featureFlags": [],
307+
"botFiltering": false,
308+
"sendFlagDecisions": true
309+
]
310+
311+
projectData["experiments"] = [exp0, exp1]
312+
let model: Project = try! OTUtils.model(from: projectData)
313+
let projectConfig = ProjectConfig()
314+
projectConfig.project = model
315+
316+
let logger = TestLogger()
317+
let optiConfigImpl = OptimizelyConfigImp(projectConfig: projectConfig, logger: logger)
318+
let optimizelyExpMap: [String: OptimizelyExperiment] = optiConfigImpl.experimentsMap
319+
XCTAssertEqual(logger.getMessages(.warning), ["Duplicate experiment keys found in datafile: duplicate_key"])
320+
321+
XCTAssertEqual(optimizelyExpMap.count, 1)
322+
XCTAssertEqual(optimizelyExpMap["duplicate_key"]?.id, "10005")
323+
}
266324

267325
}
268326

@@ -371,3 +429,41 @@ extension OptimizelyEvent {
371429
}
372430
}
373431

432+
// MARK: - Mock Loggers
433+
434+
fileprivate class TestLogger: OPTLogger {
435+
private static var _logLevel: OptimizelyLogLevel?
436+
public static var logLevel: OptimizelyLogLevel {
437+
get {
438+
return _logLevel ?? .info
439+
}
440+
set (newLevel) {
441+
_logLevel = newLevel
442+
}
443+
}
444+
445+
required public init() {
446+
clearMessages()
447+
}
448+
449+
func log(level: OptimizelyLogLevel, message: String) {
450+
logMessages[level.rawValue].append(message)
451+
}
452+
453+
// Utils
454+
455+
var logMessages = [[String]]()
456+
457+
var logCount: Int {
458+
return logMessages.reduce(0) { $0 + $1.count }
459+
}
460+
461+
func getMessages(_ level: OptimizelyLogLevel) -> [String] {
462+
return logMessages[level.rawValue]
463+
}
464+
465+
func clearMessages() {
466+
logMessages = [[String]](repeating: [], count: OptimizelyLogLevel.debug.rawValue + 1)
467+
}
468+
469+
}

0 commit comments

Comments
 (0)