Skip to content

Commit 1677db5

Browse files
fix: nested event tag support added
1 parent b3651f6 commit 1677db5

File tree

2 files changed

+61
-1
lines changed

2 files changed

+61
-1
lines changed

Sources/Data Model/Audience/AttributeValue.swift

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ enum AttributeValue: Codable, Equatable, CustomStringConvertible {
2121
case int(Int64) // supported value range [-2^53, 2^53]
2222
case double(Double)
2323
case bool(Bool)
24-
// not defined in datafile schema, but required for forward compatiblity (see Nikhil's doc)
24+
case custom([String : AttributeValue])
2525
case others
2626

2727
var description: String {
@@ -34,6 +34,8 @@ enum AttributeValue: Codable, Equatable, CustomStringConvertible {
3434
return "int(\(value))"
3535
case .bool(let value):
3636
return "bool(\(value))"
37+
case .custom(let value):
38+
return "custom(\(value))"
3739
case .others:
3840
return "others"
3941
}
@@ -63,6 +65,12 @@ enum AttributeValue: Codable, Equatable, CustomStringConvertible {
6365
self = .bool(boolValue)
6466
return
6567
}
68+
69+
if let custom = value as? [String : Any] {
70+
let attr = custom.compactMapValues { AttributeValue(value: $0) }
71+
self = .custom(attr)
72+
return
73+
}
6674

6775
return nil
6876
}
@@ -87,6 +95,12 @@ enum AttributeValue: Codable, Equatable, CustomStringConvertible {
8795
return
8896
}
8997

98+
if let value = try? container.decode([String: AttributeValue].self) {
99+
self = .custom(value)
100+
return
101+
}
102+
103+
90104
// accept all other types (null, {}, []) for forward compatibility support
91105
self = .others
92106
}
@@ -103,6 +117,8 @@ enum AttributeValue: Codable, Equatable, CustomStringConvertible {
103117
try container.encode(value)
104118
case .bool(let value):
105119
try container.encode(value)
120+
case .custom(let value):
121+
try container.encode(value.mapValues { $0 })
106122
case .others:
107123
return
108124
}
@@ -135,6 +151,10 @@ extension AttributeValue {
135151
return true
136152
}
137153

154+
if case .custom(let selfDict) = self, case .custom(let targetDict) = targetValue {
155+
return selfDict == targetDict
156+
}
157+
138158
return false
139159
}
140160

@@ -227,6 +247,8 @@ extension AttributeValue {
227247
return String(value)
228248
case .bool(let value):
229249
return String(value)
250+
case .custom(let value):
251+
return String(describing: value)
230252
case .others:
231253
return "UNKNOWN"
232254
}
@@ -240,6 +262,7 @@ extension AttributeValue {
240262
case (.double, .int): return true
241263
case (.double, .double): return true
242264
case (.bool, .bool): return true
265+
case (.custom, .custom): return true
243266
default: return false
244267
}
245268
}

Tests/OptimizelyTests-Common/BatchEventBuilderTests_EventTags.swift

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,43 @@ extension BatchEventBuilderTests_EventTags {
316316
XCTAssertEqual(de["value"] as! Double, 32, "value must be valid for value")
317317
}
318318

319+
320+
func testNestedTag() {
321+
let properties: [String: Any] = [
322+
"category": "shoes",
323+
"Text": "value",
324+
"nested": [
325+
"foot": "value",
326+
"mouch": "valuefalsdf"
327+
]
328+
]
329+
let eventKey = "event_single_targeted_exp"
330+
let eventTags: [String: Any] = ["browser": "chrome",
331+
"v1": Int8(10),
332+
"v2": Int16(20),
333+
"v3": Int32(30),
334+
"revenue": Int64(40),
335+
"value": Float(32),
336+
"$opt_event_properties": properties]
337+
338+
try! optimizely.track(eventKey: eventKey, userId: userId, attributes: nil, eventTags: eventTags)
339+
340+
let de = getDispatchEvent(dispatcher: eventDispatcher)!
341+
let tags = de["tags"] as! [String: Any]
342+
343+
XCTAssertEqual(tags["browser"] as! String, "chrome")
344+
XCTAssertEqual(tags["v1"] as! Int, 10)
345+
XCTAssertEqual(tags["v2"] as! Int, 20)
346+
XCTAssertEqual(tags["v3"] as! Int, 30)
347+
XCTAssertEqual(tags["revenue"] as! Int, 40)
348+
XCTAssertEqual(tags["value"] as! Double, 32)
349+
XCTAssertEqual(de["revenue"] as! Int, 40, "value must be valid for revenue")
350+
XCTAssertEqual(de["value"] as! Double, 32, "value must be valid for value")
351+
352+
353+
}
354+
355+
319356
func testEventTagsWithRevenueAndValue_toJSON() {
320357

321358
// valid revenue/value types

0 commit comments

Comments
 (0)