Skip to content

Commit f887777

Browse files
Merge branch 'master' into muzahid/update-license-year
2 parents d84c5cd + e5a0f8e commit f887777

18 files changed

+219
-92
lines changed

.github/workflows/integration_tests.yml

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,6 @@ on:
55
secrets:
66
CI_USER_TOKEN:
77
required: true
8-
TRAVIS_COM_TOKEN:
9-
required: true
10-
118
jobs:
129
integration_tests:
1310
runs-on: ubuntu-latest
@@ -16,8 +13,8 @@ jobs:
1613
with:
1714
# You should create a personal access token and store it in your repository
1815
token: ${{ secrets.CI_USER_TOKEN }}
19-
repository: 'optimizely/travisci-tools'
20-
path: 'home/runner/travisci-tools'
16+
repository: 'optimizely/ci-helper-tools'
17+
path: 'home/runner/ci-helper-tools'
2118
ref: 'master'
2219
- name: set SDK Branch if PR
2320
env:
@@ -31,7 +28,6 @@ jobs:
3128
if: ${{ github.event_name != 'pull_request' }}
3229
run: |
3330
echo "SDK_BRANCH=$REF_NAME" >> $GITHUB_ENV
34-
echo "TRAVIS_BRANCH=$REF_NAME" >> $GITHUB_ENV
3531
- name: Trigger build
3632
env:
3733
SDK: swift
@@ -41,14 +37,12 @@ jobs:
4137
GITHUB_TOKEN: ${{ secrets.CI_USER_TOKEN }}
4238
EVENT_TYPE: ${{ github.event_name }}
4339
GITHUB_CONTEXT: ${{ toJson(github) }}
44-
#REPO_SLUG: ${{ github.repository }}
4540
PULL_REQUEST_SLUG: ${{ github.repository }}
4641
UPSTREAM_REPO: ${{ github.repository }}
4742
PULL_REQUEST_SHA: ${{ github.event.pull_request.head.sha }}
4843
PULL_REQUEST_NUMBER: ${{ github.event.pull_request.number }}
4944
UPSTREAM_SHA: ${{ github.sha }}
50-
TOKEN: ${{ secrets.TRAVIS_COM_TOKEN }}
5145
EVENT_MESSAGE: ${{ github.event.message }}
5246
HOME: 'home/runner'
5347
run: |
54-
home/runner/travisci-tools/trigger-script-with-status-update.sh
48+
home/runner/ci-helper-tools/trigger-script-with-status-update.sh

.github/workflows/source_clear_cron.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ on:
99

1010
jobs:
1111
source_clear:
12-
runs-on: macos-12
12+
runs-on: macos-13
1313
steps:
1414
- uses: actions/checkout@v3
1515
- name: Source clear scan

.github/workflows/swift.yml

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ on:
1717
description: release
1818

1919
env:
20-
VERSION: 4.1.0
20+
VERSION: 5.1.0
2121

2222
jobs:
2323

@@ -29,10 +29,9 @@ jobs:
2929
uses: optimizely/swift-sdk/.github/workflows/integration_tests.yml@master
3030
secrets:
3131
CI_USER_TOKEN: ${{ secrets.CI_USER_TOKEN }}
32-
TRAVIS_COM_TOKEN: ${{ secrets.TRAVIS_COM_TOKEN }}
3332

3433
lint:
35-
runs-on: macos-12
34+
runs-on: macos-13
3635
steps:
3736
- uses: actions/checkout@v3
3837
- uses: maxim-lobanov/setup-xcode@v1
@@ -41,16 +40,15 @@ jobs:
4140
- env:
4241
SRCCLR_API_TOKEN: ${{ secrets.SRCCLR_API_TOKEN }}
4342
run: |
44-
gem install cocoapods -v '1.9.3'
43+
gem install cocoapods -v '1.15.2'
4544
pod spec lint --quick
4645
curl -sSL https://download.sourceclear.com/ci.sh | bash
4746
4847
unittests:
4948
if: "${{ github.event.inputs.PREP == '' && github.event.inputs.RELEASE == '' }}"
5049
uses: optimizely/swift-sdk/.github/workflows/unit_tests.yml@master
51-
5250
prepare_for_release:
53-
runs-on: macos-12
51+
runs-on: macos-13
5452
if: "${{ github.event.inputs.PREP == 'true' && github.event_name == 'workflow_dispatch' }}"
5553
steps:
5654
- uses: actions/checkout@v3
@@ -69,7 +67,7 @@ jobs:
6967
BRANCH: ${{ github.ref_name }}
7068
GITHUB_USER: optibot
7169
GITHUB_TOKEN: ${{ secrets.CI_USER_TOKEN }}
72-
COCOAPODS_VERSION: '1.12.1'
70+
COCOAPODS_VERSION: '1.15.2'
7371
run: |
7472
gem install cocoapods -v $COCOAPODS_VERSION
7573
Scripts/run_prep.sh
@@ -79,7 +77,7 @@ jobs:
7977

8078
release:
8179
if: "${{github.event.inputs.RELEASE == 'true' && github.event_name == 'workflow_dispatch' }}"
82-
runs-on: macos-12
80+
runs-on: macos-13
8381
steps:
8482
- uses: actions/checkout@v3
8583
- uses: maxim-lobanov/setup-xcode@v1
@@ -96,7 +94,7 @@ jobs:
9694
BRANCH: ${{ github.ref_name }}
9795
GITHUB_TOKEN: ${{ secrets.CI_USER_TOKEN }}
9896
COCOAPODS_TRUNK_TOKEN: ${{ secrets.COCOAPODS_TRUNK_TOKEN }}
99-
COCOAPODS_VERSION: '1.12.1'
97+
COCOAPODS_VERSION: '1.15.2'
10098
run: |
10199
gem install cocoapods -v $COCOAPODS_VERSION
102100
Scripts/run_release.sh

.github/workflows/unit_tests.yml

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ env:
77

88
jobs:
99
unittests:
10-
runs-on: macos-12
10+
runs-on: macos-13
1111
strategy:
1212
fail-fast: false
1313
matrix:
@@ -19,27 +19,27 @@ jobs:
1919
# - see "https://github.com/actions/runner-images/blob/main/images/macos/macos-11-Readme.md" for installed macOS, xcode and simulator versions.
2020
include:
2121
- os: 16.1
22-
device: "iPhone 12"
22+
device: "iPhone 14"
2323
scheme: "OptimizelySwiftSDK-iOS"
2424
test_sdk: "iphonesimulator"
2525
platform: "iOS Simulator"
2626
os_type: "iOS"
2727
simulator_xcode_version: 14.1
28-
- os: 15.5
29-
device: "iPhone 12"
28+
- os: 16.2
29+
device: "iPhone 14"
3030
scheme: "OptimizelySwiftSDK-iOS"
3131
test_sdk: "iphonesimulator"
3232
platform: "iOS Simulator"
3333
os_type: "iOS"
34-
simulator_xcode_version: 13.4.1
35-
- os: 15.5
34+
simulator_xcode_version: 14.2
35+
- os: 16.4
3636
# good to have tests with older OS versions, but it looks like this is min OS+xcode versions supported by github actions
37-
device: "iPad Air (4th generation)"
37+
device: "iPad Air (5th generation)"
3838
scheme: "OptimizelySwiftSDK-iOS"
3939
test_sdk: "iphonesimulator"
4040
platform: "iOS Simulator"
4141
os_type: "iOS"
42-
simulator_xcode_version: 13.4.1
42+
simulator_xcode_version: 14.3.1
4343
- os: 16.1
4444
device: "Apple TV"
4545
scheme: "OptimizelySwiftSDK-tvOS"
@@ -76,7 +76,7 @@ jobs:
7676
NAME: ${{ matrix.device }}
7777
run: |
7878
gem install coveralls-lcov
79-
gem install cocoapods -v '1.11.3'
79+
gem install cocoapods -v '1.15.2'
8080
pod repo update
8181
pod install
8282
HOMEBREW_NO_INSTALL_CLEANUP=true brew update && brew install jq
@@ -85,7 +85,7 @@ jobs:
8585
# - to find pre-installed xcode version, run this:
8686
##ls /Applications/
8787
# - to find supported simulator os versions, run this (and find simulator with non-error "datapath")
88-
##xcrun simctl list --json devices
88+
# xcrun simctl list --json devices
8989
9090
# switch to the target xcode version
9191
sudo xcode-select -switch /Applications/Xcode_$SIMULATOR_XCODE_VERSION.app

CHANGELOG.md

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

3+
## 5.1.0
4+
February 4th, 2025
5+
6+
### Functionality Enhancement
7+
* Add support for nested event tags ([#570](https://github.com/optimizely/swift-sdk/pull/570)).
8+
9+
## 5.0.0
10+
November 25th, 2024
11+
12+
### Breaking Changes
13+
* VUID configuration is now independent of ODP ([#456](https://github.com/optimizely/swift-sdk/pull/556))
14+
* When VUID is disabled:
15+
* `vuid` is not generated or saved.
16+
* `client-initialized` event will not auto fired on SDK init.
17+
* `vuid` is not included in the odp events as a default attribute.
18+
* `createUserContext()` will be rejected if `userId` is not provided.
19+
320
## 4.1.0
421
November 8, 2024
522

OptimizelySwiftSDK.podspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
Pod::Spec.new do |s|
22
s.name = "OptimizelySwiftSDK"
33
s.module_name = "Optimizely"
4-
s.version = "4.1.0"
4+
s.version = "5.1.0"
55
s.summary = "Optimizely experiment framework for iOS/tvOS/watchOS"
66
s.homepage = "https://docs.developers.optimizely.com/experimentation/v4.0.0-full-stack/docs"
77
s.license = { :type => "Apache License, Version 2.0", :file => "LICENSE" }

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ If you have a name conflict with other swift packages when you add the Optimizel
3939
#### CocoaPods
4040
1. Add the following lines to the _Podfile_:<pre>
4141
```use_frameworks!```
42-
```pod 'OptimizelySwiftSDK', '~> 4.1.0'```
42+
```pod 'OptimizelySwiftSDK', '~> 5.1.0'```
4343
</pre>
4444

4545
2. Run the following command: <pre>``` pod install ```</pre>
@@ -129,4 +129,4 @@ Used to enforce Swift style and conventions.
129129

130130
- React - https://github.com/optimizely/react-sdk
131131

132-
- Ruby - https://github.com/optimizely/ruby-sdk
132+
- Ruby - https://github.com/optimizely/ruby-sdk

Sources/Data Model/Audience/AttributeValue.swift

Lines changed: 53 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,15 @@
1717
import Foundation
1818

1919
enum AttributeValue: Codable, Equatable, CustomStringConvertible {
20+
typealias AttrArray = Array<AttributeValue>
21+
typealias AttrDictionary = [String : AttributeValue]
22+
2023
case string(String)
2124
case int(Int64) // supported value range [-2^53, 2^53]
2225
case double(Double)
2326
case bool(Bool)
24-
// not defined in datafile schema, but required for forward compatiblity (see Nikhil's doc)
27+
case array(AttrArray)
28+
case dictionary(AttrDictionary)
2529
case others
2630

2731
var description: String {
@@ -34,6 +38,10 @@ enum AttributeValue: Codable, Equatable, CustomStringConvertible {
3438
return "int(\(value))"
3539
case .bool(let value):
3640
return "bool(\(value))"
41+
case .array(let value):
42+
return "array(\(value))"
43+
case .dictionary(let value):
44+
return "dictionary(\(value))"
3745
case .others:
3846
return "others"
3947
}
@@ -63,6 +71,18 @@ enum AttributeValue: Codable, Equatable, CustomStringConvertible {
6371
self = .bool(boolValue)
6472
return
6573
}
74+
75+
if let arrValue = value as? [Any] {
76+
let attr = arrValue.compactMap { AttributeValue(value: $0) }
77+
self = .array(attr)
78+
return
79+
}
80+
81+
if let dicValue = value as? [String : Any] {
82+
let attr = dicValue.compactMapValues { AttributeValue(value: $0) }
83+
self = .dictionary(attr)
84+
return
85+
}
6686

6787
return nil
6888
}
@@ -87,7 +107,18 @@ enum AttributeValue: Codable, Equatable, CustomStringConvertible {
87107
return
88108
}
89109

90-
// accept all other types (null, {}, []) for forward compatibility support
110+
if let value = try? container.decode(AttrArray.self) {
111+
self = .array(value)
112+
return
113+
}
114+
115+
if let value = try? container.decode(AttrDictionary.self) {
116+
self = .dictionary(value)
117+
return
118+
}
119+
120+
121+
// accept all other types (null) for forward compatibility support
91122
self = .others
92123
}
93124

@@ -103,6 +134,10 @@ enum AttributeValue: Codable, Equatable, CustomStringConvertible {
103134
try container.encode(value)
104135
case .bool(let value):
105136
try container.encode(value)
137+
case .array(let value):
138+
try container.encode(value)
139+
case .dictionary(let value):
140+
try container.encode(value.mapValues { $0 })
106141
case .others:
107142
return
108143
}
@@ -135,6 +170,14 @@ extension AttributeValue {
135170
return true
136171
}
137172

173+
if case .array(let selfArr) = self, case .array(let targetArr) = targetValue {
174+
return selfArr == targetArr
175+
}
176+
177+
if case .dictionary(let selfDict) = self, case .dictionary(let targetDict) = targetValue {
178+
return selfDict == targetDict
179+
}
180+
138181
return false
139182
}
140183

@@ -227,6 +270,10 @@ extension AttributeValue {
227270
return String(value)
228271
case .bool(let value):
229272
return String(value)
273+
case .array(let value):
274+
return String(describing: value)
275+
case .dictionary(let value):
276+
return String(describing: value)
230277
case .others:
231278
return "UNKNOWN"
232279
}
@@ -240,6 +287,8 @@ extension AttributeValue {
240287
case (.double, .int): return true
241288
case (.double, .double): return true
242289
case (.bool, .bool): return true
290+
case (.array, .array): return true
291+
case (.dictionary, .dictionary): return true
243292
default: return false
244293
}
245294
}
@@ -271,6 +320,8 @@ extension AttributeValue {
271320
case (.int): return true
272321
case (.double): return true
273322
case (.bool): return true
323+
case (.array): return true
324+
case (.dictionary): return true
274325
default: return false
275326
}
276327
}

Sources/ODP/OdpManager.swift

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,8 @@ public class OdpManager {
5757
cacheTimeoutInSecs: cacheTimeoutInSecs,
5858
resourceTimeoutInSecs: timeoutForSegmentFetchInSecs)
5959
self.eventManager = eventManager ?? OdpEventManager(sdkKey: sdkKey,
60-
resourceTimeoutInSecs: timeoutForEventDispatchInSecs)
60+
resourceTimeoutInSecs: timeoutForEventDispatchInSecs)
61+
6162
self.odpConfig = OdpConfig()
6263
self.segmentManager.odpConfig = odpConfig
6364
self.eventManager.odpConfig = odpConfig
@@ -80,6 +81,12 @@ public class OdpManager {
8081
completionHandler: completionHandler)
8182
}
8283

84+
func sendInitializedEvent(vuid: String) throws {
85+
guard enabled else { throw OptimizelyError.odpNotEnabled }
86+
guard odpConfig.eventQueueingAllowed else { throw OptimizelyError.odpNotIntegrated }
87+
eventManager.sendInitializedEvent(vuid: vuid)
88+
}
89+
8390
func identifyUser(userId: String) {
8491
guard enabled else {
8592
logger.d("ODP identify event is not dispatched (ODP disabled).")

Sources/Optimizely+Decide/OptimizelyClient+Decide.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ extension OptimizelyClient {
3636
/// - Parameter attributes: A map of attribute names to current user attribute values.
3737
/// - Returns: An OptimizelyUserContext associated with this OptimizelyClient
3838
public func createUserContext(attributes: [String: Any]? = nil) -> OptimizelyUserContext? {
39-
guard enableVuid, let vuid = self.vuid else {
39+
guard let vuid = self.vuid else {
4040
logger.e("Vuid is not enabled or invalid VUID. User context not created.")
4141
return nil
4242
}

0 commit comments

Comments
 (0)