From fa9a2dfc277d7d38f66f6f2396e70f6753d8ed3d Mon Sep 17 00:00:00 2001 From: muzahidul-opti Date: Wed, 3 Dec 2025 16:41:11 +0600 Subject: [PATCH] feat: add CMAB Example and CMAB Custom Config functions and update datafile JSON structure --- DemoSwiftApp/Samples/SamplesForAPI.swift | 93 +++++++++++++++++++ .../Resources/demoTestDatafile.json | 46 +++++++++ 2 files changed, 139 insertions(+) diff --git a/DemoSwiftApp/Samples/SamplesForAPI.swift b/DemoSwiftApp/Samples/SamplesForAPI.swift index 7ec817e66..2ecb50c13 100644 --- a/DemoSwiftApp/Samples/SamplesForAPI.swift +++ b/DemoSwiftApp/Samples/SamplesForAPI.swift @@ -427,4 +427,97 @@ class SamplesForAPI { } + // MARK:- CMAB Example + + static func CMAB_Basic() { + let SDK_KEY = "Q9LjjQmUn5pDCjKMc1jFC" + let FLAG_KEY = "cmab-flag" + let client = OptimizelyClient( + sdkKey: SDK_KEY + ) + + if #available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) { + Task { + try await client.start() + let user = OptimizelyUserContext( + optimizely: client, + userId: "USER_123", + attributes: ["country": "us"] + ) + let options: [OptimizelyDecideOption] = [.ignoreCmabCache, .ignoreUserProfileService] + let decision = await user.decideAsync(key: FLAG_KEY, options: options) + print("CMAB decision: \(decision)") + } + } else { + guard let localDatafileUrl = Bundle.main.url(forResource: "demoTestDatafile", withExtension: "json"), + let localDatafile = try? Data(contentsOf: localDatafileUrl) + else { + fatalError("Local datafile cannot be found") + } + + try? client.start(datafile: localDatafile) + + let user = OptimizelyUserContext( + optimizely: client, + userId: "USER_123", + attributes: ["country": "us"] + ) + let options: [OptimizelyDecideOption] = [.ignoreCmabCache, .ignoreUserProfileService] + user.decideAsync(key: FLAG_KEY, options: options, completion: { decision in + print("CMAB decision: \(decision)") + }) + } + + } + + static func CMAB_Custom_Config() { + let SDK_KEY = "Q9LjjQmUn5pDCjKMc1jFC" + let FLAG_KEY = "cmab-flag" + + var cmabConfig = CmabConfig( + cacheSize: 10, + cacheTimeoutInSecs: 120, + predictionEndpoint: "https://prediction.cmab.optimizely.com/predict/%@" + ) + + // Initialize client with custom cmab config + let client = OptimizelyClient( + sdkKey: SDK_KEY, + cmabConfig: cmabConfig + ) + + if #available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) { + Task { + try await client.start() + let user = OptimizelyUserContext( + optimizely: client, + userId: "USER_123", + attributes: ["country": "us"] + ) + let options: [OptimizelyDecideOption] = [.ignoreCmabCache, .ignoreUserProfileService] + let decision = await user.decideAsync(key: FLAG_KEY, options: options) + print("CMAB decision: \(decision)") + } + } else { + guard let localDatafileUrl = Bundle.main.url(forResource: "demoTestDatafile", withExtension: "json"), + let localDatafile = try? Data(contentsOf: localDatafileUrl) + else { + fatalError("Local datafile cannot be found") + } + + try? client.start(datafile: localDatafile) + + let user = OptimizelyUserContext( + optimizely: client, + userId: "USER_123", + attributes: ["country": "us"] + ) + let options: [OptimizelyDecideOption] = [.ignoreCmabCache, .ignoreUserProfileService] + user.decideAsync(key: FLAG_KEY, options: options, completion: { decision in + print("CMAB decision: \(decision)") + }) + } + + } + } diff --git a/DemoSwiftApp/SharedResources/Resources/demoTestDatafile.json b/DemoSwiftApp/SharedResources/Resources/demoTestDatafile.json index dc01079ec..ced718dbf 100644 --- a/DemoSwiftApp/SharedResources/Resources/demoTestDatafile.json +++ b/DemoSwiftApp/SharedResources/Resources/demoTestDatafile.json @@ -150,6 +150,43 @@ }, "id": "12331371850" + }, + { + "id": "9300002796873", + "key": "cmab-rule-1", + "status": "Running", + "layerId": "9300002051159", + "variations": [ + { + "id": "1532445", + "key": "on", + "featureEnabled": true, + "variables": [] + }, + { + "id": "1532444", + "key": "off", + "featureEnabled": false, + "variables": [] + } + ], + "trafficAllocation": [], + "forcedVariations": { + + }, + "audienceIds": [ + "5716609898119168" + ], + "audienceConditions": [ + "or", + "5716609898119168" + ], + "cmab": { + "attributeIds": [ + "6381652968996864" + ], + "trafficAllocation": 10000 + } } ], "audiences": [ @@ -157,6 +194,11 @@ "id": "12208130097", "conditions": "[\"and\", [\"or\", [\"or\", {\"name\": \"browser_type\", \"type\": \"custom_attribute\", \"value\": \"safari\"}, {\"name\": \"browser_type\", \"type\": \"custom_attribute\", \"value\": \"chrome\"}]]]", "name": "safari" + }, + { + "id": "5716609898119168", + "conditions": "[\"and\", [\"or\", [\"or\", {\"match\": \"exact\", \"name\": \"country\", \"type\": \"custom_attribute\", \"value\": \"us\"}], [\"or\", {\"match\": \"exact\", \"name\": \"country\", \"type\": \"custom_attribute\", \"value\": \"ru\"}]]]", + "name": "cmab-audience" } ], "groups": [ @@ -174,6 +216,10 @@ { "id": "12126623630", "key": "geo" + }, + { + "id": "6381652968996864", + "key": "country" } ], "botFiltering": false,