From d7566517c40fe8a12b2e5f14596c552a44e2e64a Mon Sep 17 00:00:00 2001 From: Weihao Ding <158090588+weihao-statsig@users.noreply.github.com> Date: Wed, 26 Jun 2024 13:11:56 -0700 Subject: [PATCH] feat: add option to opt out non sdk metadata (#283) context: https://statsigcommunity.slack.com/archives/C01RAKM10TD/p1718750620298129?thread_ts=1718606236.716329&cid=C01RAKM10TD test: add UT --- Sources/Statsig/DeviceEnvironment.swift | 16 ++++++++++++++++ Sources/Statsig/StatsigUser.swift | 21 +++++++++++++++++++-- Tests/StatsigTests/StatsigUserSpec.swift | 11 +++++++++++ 3 files changed, 46 insertions(+), 2 deletions(-) diff --git a/Sources/Statsig/DeviceEnvironment.swift b/Sources/Statsig/DeviceEnvironment.swift index 26486b9..395b420 100644 --- a/Sources/Statsig/DeviceEnvironment.swift +++ b/Sources/Statsig/DeviceEnvironment.swift @@ -52,12 +52,28 @@ struct DeviceEnvironment { static func get(_ overrideStableID: String? = nil) -> [String: String?] { return instance.get(overrideStableID) } + + static func getSDKMetadata(_ overrideStableID: String? = nil) -> [String: String?] { + return instance.getSDKMetadata(overrideStableID) + } static func explicitGet(_ overrideStableID: String? = nil) -> [String: String] { return instance.get(overrideStableID).mapValues { val in return val ?? "" } } + + private func getSDKMetadata(_ overrideStableID: String? = nil) -> [String: String?] { + lock.lock() + defer { lock.unlock() } + + return [ + "sdkType": DeviceEnvironment.sdkType, + "sdkVersion": DeviceEnvironment.sdkVersion, + "sessionID": sessionID, + "stableID": getStableID(overrideStableID) + ] + } private func get(_ overrideStableID: String? = nil) -> [String: String?] { lock.lock() diff --git a/Sources/Statsig/StatsigUser.swift b/Sources/Statsig/StatsigUser.swift index c88084c..455f05b 100644 --- a/Sources/Statsig/StatsigUser.swift +++ b/Sources/Statsig/StatsigUser.swift @@ -43,6 +43,12 @@ public struct StatsigUser { Any value you wish to use in evaluation, but not have logged with events can be stored in this field. */ public let privateAttributes: [String: StatsigUserCustomTypeConvertible]? + + /** + Controls whether non-SDK-type SDK version metadata should be excluded or included. + Setting this option to `true` will exclude metadata related to non-SDK-type SDK versions. By default, this option is set to `false`, meaning all metadata is included. + */ + public var optOutNonSdkMetadata: Bool? /** Any Custom IDs to associated with the user. @@ -62,6 +68,7 @@ public struct StatsigUser { appVersion: String? = nil, custom: [String: StatsigUserCustomTypeConvertible]? = nil, privateAttributes: [String: StatsigUserCustomTypeConvertible]? = nil, + optOutNonSdkMetadata: Bool? = false, customIDs: [String: String]? = nil) { self.userID = userID @@ -71,6 +78,7 @@ public struct StatsigUser { self.locale = locale self.appVersion = appVersion self.customIDs = customIDs + self.optOutNonSdkMetadata = optOutNonSdkMetadata if let custom = custom, JSONSerialization.isValidJSONObject(custom) { self.custom = custom @@ -89,11 +97,20 @@ public struct StatsigUser { } self.privateAttributes = nil } - self.deviceEnvironment = DeviceEnvironment.get() + + if (self.optOutNonSdkMetadata ?? false) { + self.deviceEnvironment = DeviceEnvironment.getSDKMetadata() + } else { + self.deviceEnvironment = DeviceEnvironment.get() + } } mutating func setStableID(_ overrideStableID: String) { - self.deviceEnvironment = DeviceEnvironment.get(overrideStableID) + if (self.optOutNonSdkMetadata ?? false) { + self.deviceEnvironment = DeviceEnvironment.getSDKMetadata(overrideStableID) + } else { + self.deviceEnvironment = DeviceEnvironment.get(overrideStableID) + } } func toDictionary(forLogging: Bool) -> [String: Any?] { diff --git a/Tests/StatsigTests/StatsigUserSpec.swift b/Tests/StatsigTests/StatsigUserSpec.swift index ec03b9d..e6912bb 100644 --- a/Tests/StatsigTests/StatsigUserSpec.swift +++ b/Tests/StatsigTests/StatsigUserSpec.swift @@ -24,6 +24,17 @@ class StatsigUserSpec: BaseSpec { expect(validEmptyUser.deviceEnvironment).toNot(beNil()) expect(validEmptyUser.customIDs).to(beNil()) } + + it("only return sdk related medatada if opt out non sdk metadata") { + let validUserOptOutNonSdkMetadata = StatsigUser(optOutNonSdkMetadata: true) + + let deviceEnvironment = validUserOptOutNonSdkMetadata.deviceEnvironment + expect(deviceEnvironment["sdkVersion"]) == "1.44.0" + expect(deviceEnvironment["sdkType"]) == "ios-client" + expect(deviceEnvironment["sessionID"]).toNot(beNil()) + expect(deviceEnvironment["stableID"]).toNot(beNil()) + expect(deviceEnvironment.count) == 4 + } it("is a valid user with ID provided") { let validUserWithID = StatsigUser(userID: "12345")