Skip to content

Commit

Permalink
Favor anonymous over transient (#216)
Browse files Browse the repository at this point in the history
After much discussion and debate about how backwards compatibility
concerns would be addressed, we have decided that we are going to keep
the name anonymous and abandon transient.
  • Loading branch information
keelerm84 committed Jul 1, 2022
1 parent 5a6748b commit a8bc65f
Show file tree
Hide file tree
Showing 7 changed files with 32 additions and 35 deletions.
4 changes: 2 additions & 2 deletions ContractTests/Source/Controllers/SdkController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -225,8 +225,8 @@ final class SdkController: RouteCollection {
contextBuilder.name(name)
}

if let transient = params.transient {
contextBuilder.transient(transient)
if let anonymous = params.anonymous {
contextBuilder.anonymous(anonymous)
}

if let secondary = params.secondary {
Expand Down
4 changes: 2 additions & 2 deletions ContractTests/Source/Models/command.swift
Original file line number Diff line number Diff line change
Expand Up @@ -82,13 +82,13 @@ struct SingleContextParameters: Content, Decodable {
var kind: String?
var key: String
var name: String?
var transient: Bool?
var anonymous: Bool?
var secondary: String?
var privateAttribute: [String]?
var custom: [String:LDValue]?

private enum CodingKeys: String, CodingKey {
case kind, key, name, transient, secondary, privateAttribute = "private", custom
case kind, key, name, anonymous, secondary, privateAttribute = "private", custom
}
}

Expand Down
39 changes: 18 additions & 21 deletions LaunchDarkly/LaunchDarkly/Models/Context/LDContext.swift
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public struct LDContext: Encodable, Equatable {

// Meta attributes
fileprivate var name: String?
fileprivate var transient: Bool = false
fileprivate var anonymous: Bool = false
fileprivate var secondary: String?
internal var privateAttributes: [Reference] = []

Expand Down Expand Up @@ -131,8 +131,8 @@ public struct LDContext: Encodable, Equatable {
try container.encodeIfPresent(meta, forKey: DynamicCodingKeys(string: "_meta"))
}

if context.transient {
try container.encodeIfPresent(context.transient, forKey: DynamicCodingKeys(string: "transient"))
if context.anonymous {
try container.encodeIfPresent(context.anonymous, forKey: DynamicCodingKeys(string: "anonymous"))
}
}

Expand Down Expand Up @@ -412,8 +412,8 @@ public struct LDContext: Encodable, Equatable {
return self.key.map { .string($0) }
case "name":
return self.name.map { .string($0) }
case "transient":
return .bool(self.transient)
case "anonymous":
return .bool(self.anonymous)
default:
return self.attributes[name]
}
Expand Down Expand Up @@ -487,7 +487,7 @@ extension LDContext: Decodable {
custom.forEach { contextBuilder.trySetValue($0.key, $0.value) }

let isAnonymous = try values.decodeIfPresent(Bool.self, forKey: .isAnonymous) ?? false
contextBuilder.transient(isAnonymous)
contextBuilder.anonymous(isAnonymous)

let privateAttributeNames = try values.decodeIfPresent([String].self, forKey: .privateAttributeNames) ?? []
privateAttributeNames.forEach { contextBuilder.addPrivateAttribute(Reference($0)) }
Expand Down Expand Up @@ -589,7 +589,7 @@ extension LDContext: TypeIdentifying {}
///
/// You may use these methods to set additional attributes and/or change the kind before calling
/// `LDContextBuilder.build()`. If you do not change any values, the defaults for the `LDContext` are that its
/// kind is "user", its key is set to whatever value you passed to `LDContextBuilder.init(key:)`, its transient attribute
/// kind is "user", its key is set to whatever value you passed to `LDContextBuilder.init(key:)`, its anonymous attribute
/// is false, and it has no values for any other attributes.
///
/// To define a multi-kind LDContext, see `LDMultiContextBuilder`.
Expand All @@ -598,7 +598,7 @@ public struct LDContextBuilder {

// Meta attributes
private var name: String?
private var transient: Bool = false
private var anonymous: Bool = false
private var secondary: String?
private var privateAttributes: [Reference] = []

Expand Down Expand Up @@ -668,7 +668,7 @@ public struct LDContextBuilder {
///
/// - "name": Must be a string or null. See `LDContextBuilder.name(_:)`.
///
/// - "transient": Must be a boolean. See `LDContextBuilder.transient(_:)`.
/// - "anonymous": Must be a boolean. See `LDContextBuilder.anonymous(_:)`.
///
/// Values that are JSON arrays or objects have special behavior when referenced in
/// flag/segment rules.
Expand Down Expand Up @@ -699,9 +699,9 @@ public struct LDContextBuilder {
self.name(val)
case ("name", _):
return false
case ("transient", .bool(let val)):
self.transient(val)
case ("transient", _):
case ("anonymous", .bool(let val)):
self.anonymous(val)
case ("anonymous", _):
return false
case ("secondary", .string(let val)):
self.secondary(val)
Expand All @@ -710,9 +710,6 @@ public struct LDContextBuilder {
case ("privateAttributeNames", _):
Log.debug(typeName(and: #function) + ": The privateAttributeNames property has been replaced with privateAttributes. Refusing to set a property named privateAttributeNames.")
return false
case ("anonymous", _):
Log.debug(typeName(and: #function) + ": The anonymous property has been replaced with transient. Refusing to set a property named anonymous.")
return false
case (_, .null):
self.attributes.removeValue(forKey: name)
return false
Expand Down Expand Up @@ -744,15 +741,15 @@ public struct LDContextBuilder {
/// The default value is false. False means that this LDContext represents an entity such as a
/// user that you want to be able to see on the LaunchDarkly dashboard.
///
/// Setting transient to true excludes this LDContext from the database that is used by the
/// Setting anonymous to true excludes this LDContext from the database that is used by the
/// dashboard. It does not exclude it from analytics event data, so it is not the same as
/// making attributes private; all non-private attributes will still be included in events and
/// data export.
///
/// This value is also addressable in evaluations as the attribute name "transient". It is
/// This value is also addressable in evaluations as the attribute name "anonymous". It is
/// always treated as a boolean true or false in evaluations.
public mutating func transient(_ transient: Bool) {
self.transient = transient
public mutating func anonymous(_ anonymous: Bool) {
self.anonymous = anonymous
}

/// Provide a reference to designate any number of LDContext attributes as private: that is,
Expand All @@ -766,7 +763,7 @@ public struct LDContextBuilder {
/// This action only affects analytics events that involve this particular LDContext. To mark some (or all)
/// LDContext attributes as private for all uses, use the overall event configuration for the SDK.
///
/// The attributes "kind" and "key", and the metadata properties set by secondary and transient,
/// The attributes "kind" and "key", and the metadata properties set by secondary and anonymous,
/// cannot be made private.
public mutating func addPrivateAttribute(_ reference: Reference) {
self.privateAttributes.append(reference)
Expand Down Expand Up @@ -802,7 +799,7 @@ public struct LDContextBuilder {
context.kind = kind
context.contexts = []
context.name = self.name
context.transient = self.transient
context.anonymous = self.anonymous
context.secondary = self.secondary
context.privateAttributes = self.privateAttributes
context.key = self.key
Expand Down
2 changes: 1 addition & 1 deletion LaunchDarkly/LaunchDarkly/ObjectiveC/ObjcLDContext.swift
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public final class ObjcLDContextBuilder: NSObject {
@objc public func key(key: String) { builder.key(key) }
@objc public func name(name: String) { builder.name(name) }
@objc public func secondary(secondary: String) { builder.secondary(secondary) }
@objc public func transient(transient: Bool) { builder.transient(transient) }
@objc public func anonymous(anonymous: Bool) { builder.anonymous(anonymous) }
@objc public func addPrivateAttribute(reference: ObjcLDReference) { builder.addPrivateAttribute(reference.reference) }
@objc public func removePrivateAttribute(reference: ObjcLDReference) { builder.removePrivateAttribute(reference.reference) }

Expand Down
2 changes: 1 addition & 1 deletion LaunchDarkly/LaunchDarklyTests/Mocks/LDContextStub.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ extension LDContext {

builder.name(StubConstants.name)
builder.secondary(StubConstants.secondary)
builder.transient(StubConstants.isAnonymous)
builder.anonymous(StubConstants.isAnonymous)

builder.trySetValue("firstName", StubConstants.firstName)
builder.trySetValue("lastName", StubConstants.lastName)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ final class LDContextCodableSpec: XCTestCase {
("{\"key\": \"foo\"}", "{\"key\": \"foo\", \"kind\": \"user\"}"),
("{\"key\" : \"foo\", \"name\" : \"bar\"}", "{\"kind\" : \"user\", \"key\" : \"foo\", \"name\" : \"bar\"}"),
("{\"key\" : \"foo\", \"custom\" : {\"a\" : \"b\"}}", "{\"kind\" : \"user\", \"key\" : \"foo\", \"a\" : \"b\"}"),
("{\"key\" : \"foo\", \"anonymous\" : true}", "{\"kind\" : \"user\", \"key\" : \"foo\", \"transient\" : true}"),
("{\"key\" : \"foo\", \"anonymous\" : true}", "{\"kind\" : \"user\", \"key\" : \"foo\", \"anonymous\" : true}"),
("{\"key\" : \"foo\", \"secondary\" : \"bar\"}", "{\"kind\" : \"user\", \"key\" : \"foo\", \"_meta\" : {\"secondary\" : \"bar\"}}"),
("{\"key\" : \"foo\", \"ip\" : \"1\", \"privateAttributeNames\" : [\"ip\"]}", "{\"kind\" : \"user\", \"key\" : \"foo\", \"ip\" : \"1\", \"_meta\" : { \"privateAttributes\" : [\"ip\"]} }")
]
Expand All @@ -26,7 +26,7 @@ final class LDContextCodableSpec: XCTestCase {
let testCases = [
"{\"kind\":\"org\",\"key\":\"foo\"}",
"{\"kind\":\"user\",\"key\":\"foo\"}",
"{\"kind\":\"foo\",\"key\":\"bar\",\"transient\":true}",
"{\"kind\":\"foo\",\"key\":\"bar\",\"anonymous\":true}",
"{\"kind\":\"foo\",\"key\":\"bar\",\"name\":\"Foo\",\"_meta\":{\"privateAttributes\":[\"a\"],\"secondary\":\"baz\"}}",
"{\"kind\":\"foo\",\"key\":\"bar\",\"object\":{\"a\":\"b\"}}"
]
Expand Down Expand Up @@ -111,7 +111,7 @@ final class LDContextCodableSpec: XCTestCase {
},
"baz": {
"key": "baz-key",
"transient": true
"anonymous": true
}
}
"""
Expand All @@ -123,7 +123,7 @@ final class LDContextCodableSpec: XCTestCase {

var bazBuilder = LDContextBuilder(key: "baz-key")
bazBuilder.kind("baz")
bazBuilder.transient(true)
bazBuilder.anonymous(true)

var multiBuilder = LDMultiContextBuilder()
multiBuilder.addContext(try userBuilder.build().get())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ final class LDContextSpec: XCTestCase {
("kind", .string("org")),
("key", .string("my-key")),
("name", .string("my-name")),
("transient", .bool(true)),
("anonymous", .bool(true)),
("attr", .string("my-attr")),
("/starts-with-slash", .string("love that prefix")),
("/crazy~0name", .string("still works")),
Expand All @@ -207,7 +207,7 @@ final class LDContextSpec: XCTestCase {
var builder = LDContextBuilder(key: "my-key")
builder.kind("org")
builder.name("my-name")
builder.transient(true)
builder.anonymous(true)
builder.secondary("my-secondary")
builder.trySetValue("attr", .string("my-attr"))
builder.trySetValue("starts-with-slash", .string("love that prefix"))
Expand All @@ -231,7 +231,7 @@ final class LDContextSpec: XCTestCase {
builder.key("org")
builder.kind("org")
builder.name("my-name")
builder.transient(true)
builder.anonymous(true)
builder.trySetValue("attr", .string("my-attr"))

multibuilder.addContext(try builder.build().get())
Expand All @@ -242,7 +242,7 @@ final class LDContextSpec: XCTestCase {
("kind", LDValue.string("multi")),
("key", nil),
("name", nil),
("transient", nil),
("anonymous", nil),
("attr", nil)
]

Expand Down

0 comments on commit a8bc65f

Please sign in to comment.