From 0232e6bc36e7568245b4b2544076e5d39fbf7e95 Mon Sep 17 00:00:00 2001 From: Swarna Saraf Date: Fri, 26 Jan 2024 13:03:39 -0800 Subject: [PATCH] Target SDK should attach response tokens in the retrieveLocationContent data callback (#155) (#156) (#157) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Target SDK should attach response tokens in the retrieveLocationContent data callback * Minor fixes * • reverted dependency updates • updated test constants * revert podfile.lock * Fixed tests after migration from UserDefaults to file system. * minor cleanup * Additional test + doc update Co-authored-by: Steve Benedick --- AEPTarget.podspec | 2 +- AEPTarget.xcodeproj/project.pbxproj | 8 +++- AEPTarget/Sources/Target.swift | 8 ++-- AEPTarget/Sources/TargetConstants.swift | 2 +- .../TargetFunctionalTests.swift | 16 ++++---- .../TargetFunctionalTestsBase.swift | 2 + .../TargetMigrationFunctionalTests.swift | 7 +++- .../TargetIntegrationTests.swift | 27 ++++++++----- .../NamedCollectionDataStore+clear.swift | 38 +++++++++++++++++++ .../TestHelpers/TargetTestConstants.swift | 2 +- .../TestHelpers/UserDefaults+clear.swift | 18 +++++++-- .../Tests/UnitTests/TargetStateTests.swift | 2 +- AEPTarget/Tests/UnitTests/TargetTests.swift | 26 ------------- .../UnitTests/TargetV4MigratorTests.swift | 17 +++------ .../UnitTests/TargetV5MigratorTests.swift | 17 +++------ AEPTargetDemoApp/ContentView.swift | 4 +- Documentation/AEPTarget.md | 2 +- Podfile.lock | 34 ++++++++--------- 18 files changed, 129 insertions(+), 103 deletions(-) create mode 100644 AEPTarget/Tests/TestHelpers/NamedCollectionDataStore+clear.swift diff --git a/AEPTarget.podspec b/AEPTarget.podspec index de3e7da..6f2933e 100644 --- a/AEPTarget.podspec +++ b/AEPTarget.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "AEPTarget" - s.version = "4.0.2" + s.version = "4.0.3" s.summary = "Experience Platform Target extension for Adobe Experience Platform Mobile SDK. Written and maintained by Adobe." s.description = <<-DESC The Experience Platform Target extension provides APIs that allow use of the Target product in the Adobe Experience Platform SDK. diff --git a/AEPTarget.xcodeproj/project.pbxproj b/AEPTarget.xcodeproj/project.pbxproj index 613cc0e..c6ca22e 100644 --- a/AEPTarget.xcodeproj/project.pbxproj +++ b/AEPTarget.xcodeproj/project.pbxproj @@ -25,6 +25,7 @@ 091AB3E2288636F400E43F23 /* TargetTntIdFunctionalTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 091AB3E1288636F400E43F23 /* TargetTntIdFunctionalTests.swift */; }; 0932CAF228DC5D3800BE99E2 /* Dictionary+Target.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0932CAF128DC5D3800BE99E2 /* Dictionary+Target.swift */; }; 0932CAF428DD0D2200BE99E2 /* TargetRawRequestsFunctionalTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0932CAF328DD0D2200BE99E2 /* TargetRawRequestsFunctionalTests.swift */; }; + 09F5D94B2B60912F00117437 /* NamedCollectionDataStore+clear.swift in Sources */ = {isa = PBXBuildFile; fileRef = 09F5D9492B6090F900117437 /* NamedCollectionDataStore+clear.swift */; }; 21BB6EAE22D5AC72C15DB97C /* Pods_AEPTargetTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 639B326C68E1444919C98676 /* Pods_AEPTargetTests.framework */; }; 54A53C0BFA0D61EF50B9E5C5 /* Pods_AEPTargetDemoApp.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 45A74BEED420E4145D1D72CC /* Pods_AEPTargetDemoApp.framework */; }; 780DF565258924B70033F107 /* URL+Target.swift in Sources */ = {isa = PBXBuildFile; fileRef = 780DF564258924B70033F107 /* URL+Target.swift */; }; @@ -168,6 +169,7 @@ 091AB3E1288636F400E43F23 /* TargetTntIdFunctionalTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TargetTntIdFunctionalTests.swift; sourceTree = ""; }; 0932CAF128DC5D3800BE99E2 /* Dictionary+Target.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Dictionary+Target.swift"; sourceTree = ""; }; 0932CAF328DD0D2200BE99E2 /* TargetRawRequestsFunctionalTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TargetRawRequestsFunctionalTests.swift; sourceTree = ""; }; + 09F5D9492B6090F900117437 /* NamedCollectionDataStore+clear.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NamedCollectionDataStore+clear.swift"; sourceTree = ""; }; 1F937F0708662CB013507FEA /* Pods-AEPTarget.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AEPTarget.debug.xcconfig"; path = "Target Support Files/Pods-AEPTarget/Pods-AEPTarget.debug.xcconfig"; sourceTree = ""; }; 22CDBB0E77B419D5D7E526F3 /* Pods-AEPTarget.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AEPTarget.release.xcconfig"; path = "Target Support Files/Pods-AEPTarget/Pods-AEPTarget.release.xcconfig"; sourceTree = ""; }; 2781B11116AD0207B40F67F0 /* Pods_AEPTargetDemoObjCApp.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_AEPTargetDemoObjCApp.framework; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -507,6 +509,7 @@ BB8FF11C2602A72C006C80D9 /* UserDefaults+clear.swift */, BBC428DA26166360006E4A3F /* MockNetworkService.swift */, 786C00E225C35EEB00F26D34 /* TargetTestConstants.swift */, + 09F5D9492B6090F900117437 /* NamedCollectionDataStore+clear.swift */, ); path = TestHelpers; sourceTree = ""; @@ -913,6 +916,7 @@ 924102A1260C01CA00DA88D2 /* MockPreviewManagerUIDelegate.swift in Sources */, BB1DBE9025D22C3D00DDBA15 /* Target+PublicAPITests.swift in Sources */, BB9C86EF255C9C90007AEF8B /* Event+TargetTests.swift in Sources */, + 09F5D94B2B60912F00117437 /* NamedCollectionDataStore+clear.swift in Sources */, BB861104261B663B00A39187 /* TargetFunctionalTests.swift in Sources */, BB8FF1262602A72C006C80D9 /* MockUIService.swift in Sources */, BB8FF1252602A72C006C80D9 /* UserDefaults+clear.swift in Sources */, @@ -1174,7 +1178,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MARKETING_VERSION = 4.0.2; + MARKETING_VERSION = 4.0.3; PRODUCT_BUNDLE_IDENTIFIER = com.adobe.aep.target; PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -1205,7 +1209,7 @@ "@executable_path/Frameworks", "@loader_path/Frameworks", ); - MARKETING_VERSION = 4.0.2; + MARKETING_VERSION = 4.0.3; PRODUCT_BUNDLE_IDENTIFIER = com.adobe.aep.target; PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; PROVISIONING_PROFILE_SPECIFIER = ""; diff --git a/AEPTarget/Sources/Target.swift b/AEPTarget/Sources/Target.swift index fe4c015..0567359 100644 --- a/AEPTarget/Sources/Target.swift +++ b/AEPTarget/Sources/Target.swift @@ -1074,17 +1074,17 @@ public class Target: NSObject, Extension { /// - Parameters: /// - mboxJson: `[String: Any]` target response dictionary /// - Returns: tuple containg `String` mbox content and `Dictionary` containing response tokens, if any. - private func extractMboxContentAndResponseTokens(mboxJson: [String: Any]) -> (content: String?, responseTokens: [String: String]?) { + private func extractMboxContentAndResponseTokens(mboxJson: [String: Any]) -> (content: String?, responseTokens: [String: Any]?) { guard let optionsArray = mboxJson[TargetConstants.TargetJson.OPTIONS] as? [[String: Any?]?] else { Log.debug(label: Target.LOG_TAG, "extractMboxContent - unable to extract mbox contents, options array is nil") return (nil, nil) } var contentBuilder = "" - var responseTokens: [String: String]? + var responseTokens: [String: Any]? for option in optionsArray { - responseTokens = option?[TargetConstants.TargetJson.Option.RESPONSE_TOKENS] as? [String: String] + responseTokens = option?[TargetConstants.TargetJson.Option.RESPONSE_TOKENS] as? [String: Any] guard let content = option?[TargetConstants.TargetJson.Option.CONTENT] else { continue @@ -1190,7 +1190,7 @@ public class Target: NSObject, Extension { /// - analyticsPayload: dictionary containing analytics for target (a4t) payload. /// - metricsAnalyticsPayload: dictionary containing a4t payload for click metric. /// - Returns: `Dictionary` containing Target payload or nil. - private func packageMboxResponsePayload(responseTokens: [String: String]?, + private func packageMboxResponsePayload(responseTokens: [String: Any]?, analyticsPayload: [String: String]?, metricsAnalyticsPayload: [String: String]?) -> [String: Any]? { diff --git a/AEPTarget/Sources/TargetConstants.swift b/AEPTarget/Sources/TargetConstants.swift index ae41e3e..ff75584 100644 --- a/AEPTarget/Sources/TargetConstants.swift +++ b/AEPTarget/Sources/TargetConstants.swift @@ -15,7 +15,7 @@ import Foundation enum TargetConstants { static let EXTENSION_NAME = "com.adobe.module.target" static let FRIENDLY_NAME = "Target" - static let EXTENSION_VERSION = "4.0.2" + static let EXTENSION_VERSION = "4.0.3" static let DATASTORE_NAME = EXTENSION_NAME static let DEFAULT_SESSION_TIMEOUT: Int = 30 * 60 // 30 mins static let DELIVERY_API_URL_BASE = "https://%@/rest/v1/delivery/?client=%@&sessionId=%@" diff --git a/AEPTarget/Tests/FunctionalTests/TargetFunctionalTests.swift b/AEPTarget/Tests/FunctionalTests/TargetFunctionalTests.swift index ba412ac..4bd1dc2 100644 --- a/AEPTarget/Tests/FunctionalTests/TargetFunctionalTests.swift +++ b/AEPTarget/Tests/FunctionalTests/TargetFunctionalTests.swift @@ -254,10 +254,10 @@ class TargetFunctionalTests: TargetFunctionalTestsBase { // MARK: - Session testing func testIfSessionTimeOut_useNewSessionIdAndDefaultEdgeHostInTargetReqeust() { - cleanUserDefaults() - getUserDefaults().setValue(1_617_825_969, forKey: "Adobe.com.adobe.module.target.session.timestamp") - getUserDefaults().setValue("935CDD24-8FD7-4B30-8508-4BE40C3FC263", forKey: "Adobe.com.adobe.module.target.session.id") - getUserDefaults().setValue("mboxedge35.tt.omtrdc.net", forKey: "Adobe.com.adobe.module.target.edge.host") + NamedCollectionDataStore.clear() + getTargetDataStore().set(key: "session.timestamp", value: 1_617_825_969) + getTargetDataStore().set(key: "session.id", value: "935CDD24-8FD7-4B30-8508-4BE40C3FC263") + getTargetDataStore().set(key: "edge.host", value: "mboxedge35.tt.omtrdc.net") mockRuntime = TestableExtensionRuntime() target = Target(runtime: mockRuntime) target.onRegistered() @@ -297,8 +297,8 @@ class TargetFunctionalTests: TargetFunctionalTestsBase { } func testIfNotSessionTimeOut_useSameSessionIdAndNewEdgeHostInTargetReqeust() { - cleanUserDefaults() - getUserDefaults().setValue(Date().getUnixTimeInSeconds(), forKey: "Adobe.com.adobe.module.target.session.timestamp") + NamedCollectionDataStore.clear() + getTargetDataStore().set(key: "session.timestamp", value: Date().getUnixTimeInSeconds()) mockRuntime = TestableExtensionRuntime() target = Target(runtime: mockRuntime) target.onRegistered() @@ -399,9 +399,9 @@ class TargetFunctionalTests: TargetFunctionalTestsBase { } func testSessionTimestampIsNotUpdatedWhenSendingRequestFails() { - cleanUserDefaults() + NamedCollectionDataStore.clear() let sessionTimestamp = Date().getUnixTimeInSeconds() - getUserDefaults().setValue(sessionTimestamp, forKey: "Adobe.com.adobe.module.target.session.timestamp") + getTargetDataStore().set(key: "session.timestamp", value: sessionTimestamp) mockRuntime = TestableExtensionRuntime() target = Target(runtime: mockRuntime) target.onRegistered() diff --git a/AEPTarget/Tests/FunctionalTests/TargetFunctionalTestsBase.swift b/AEPTarget/Tests/FunctionalTests/TargetFunctionalTestsBase.swift index 5e468ed..586680b 100644 --- a/AEPTarget/Tests/FunctionalTests/TargetFunctionalTestsBase.swift +++ b/AEPTarget/Tests/FunctionalTests/TargetFunctionalTestsBase.swift @@ -57,6 +57,8 @@ class TargetFunctionalTestsBase: XCTestCase { ] cleanUserDefaults() + NamedCollectionDataStore.clear() + mockRuntime = TestableExtensionRuntime() target = Target(runtime: mockRuntime) target.previewManager = mockPreviewManager diff --git a/AEPTarget/Tests/FunctionalTests/TargetMigrationFunctionalTests.swift b/AEPTarget/Tests/FunctionalTests/TargetMigrationFunctionalTests.swift index 071e70b..04487fc 100644 --- a/AEPTarget/Tests/FunctionalTests/TargetMigrationFunctionalTests.swift +++ b/AEPTarget/Tests/FunctionalTests/TargetMigrationFunctionalTests.swift @@ -23,8 +23,9 @@ class TargetMigrationFunctionalTests: TargetFunctionalTestsBase { } func testTargetInitWithDataMigrationFromV5() { - let userDefaultsV5 = getUserDefaults() cleanUserDefaults() + NamedCollectionDataStore.clear() + let userDefaultsV5 = getUserDefaults() let timestamp = Date().getUnixTimeInSeconds() userDefaultsV5.set("edge.host.com", forKey: "Adobe.ADOBEMOBILE_TARGET.EDGE_HOST") @@ -42,9 +43,11 @@ class TargetMigrationFunctionalTests: TargetFunctionalTestsBase { } func testTargetInitWithDataMigrationFromV4() { + cleanUserDefaults() + NamedCollectionDataStore.clear() + let userDefaultsV4 = getUserDefaults() let targetDataStore = getTargetDataStore() - cleanUserDefaults() userDefaultsV4.set("id_1", forKey: "ADBMOBILE_TARGET_TNT_ID") userDefaultsV4.set("id_2", forKey: "ADBMOBILE_TARGET_3RD_PARTY_ID") diff --git a/AEPTarget/Tests/IntegrationTests/TargetIntegrationTests.swift b/AEPTarget/Tests/IntegrationTests/TargetIntegrationTests.swift index 9b1f240..de84ff7 100644 --- a/AEPTarget/Tests/IntegrationTests/TargetIntegrationTests.swift +++ b/AEPTarget/Tests/IntegrationTests/TargetIntegrationTests.swift @@ -24,7 +24,7 @@ class TargetIntegrationTests: XCTestCase { private let dispatchQueue = DispatchQueue(label: "com.adobe.target.test") override func setUp() { FileManager.default.clear() - UserDefaults.clear() + NamedCollectionDataStore.clear() ServiceProvider.shared.reset() EventHub.reset() } @@ -715,7 +715,9 @@ class TargetIntegrationTests: XCTestCase { "content": "someContent", "type": "html", "responseTokens":{ - "activity.name":"My test activity" + "activity.name":"My test activity", + "profile.categoryAffinities":["shoes"], + "someKey":["someValue", true, 42] } } ], @@ -766,9 +768,14 @@ class TargetIntegrationTests: XCTestCase { XCTAssertEqual("tnt", analyticsPayload?["pe"]) XCTAssertEqual("331289:0:0|2|1,331289:0:0|32767|1", analyticsPayload?["tnta"]) - let responseTokens = data["responseTokens"] as? [String: String] - XCTAssertEqual(1, responseTokens?.count) - XCTAssertEqual("My test activity", responseTokens?["activity.name"]) + let responseTokens = data["responseTokens"] as? [String: Any] + XCTAssertEqual(3, responseTokens?.count) + XCTAssertEqual("My test activity", responseTokens?["activity.name"] as? String) + XCTAssertEqual(["shoes"], responseTokens?["profile.categoryAffinities"] as? [String]) + let someArr = responseTokens?["someKey"] as? [Any] + XCTAssertEqual("someValue", someArr?[0] as? String) + XCTAssertEqual(true, someArr?[1] as? Bool) + XCTAssertEqual(42, someArr?[2] as? Int) targetRequestExpectation.fulfill() } @@ -797,7 +804,8 @@ class TargetIntegrationTests: XCTestCase { "content": "someContent", "type": "html", "responseTokens":{ - "activity.name":"My test activity" + "activity.name":"My test activity", + "profile.categoryAffinities":["shoes"] }, "eventToken": "uR0kIAPO+tZtIPW92S0NnWqipfsIHvVzTQxHolz2IpSCnQ9Y9OaLL2gsdrWQTvE54PwSz67rmXWmSnkXpSSS2Q==" } @@ -862,9 +870,10 @@ class TargetIntegrationTests: XCTestCase { XCTAssertEqual("tnt", analyticsPayload?["pe"]) XCTAssertEqual("331289:0:0|2|1,331289:0:0|32767|1", analyticsPayload?["tnta"]) - let responseTokens = data["responseTokens"] as? [String: String] - XCTAssertEqual(1, responseTokens?.count) - XCTAssertEqual("My test activity", responseTokens?["activity.name"]) + let responseTokens = data["responseTokens"] as? [String: Any] + XCTAssertEqual(2, responseTokens?.count) + XCTAssertEqual("My test activity", responseTokens?["activity.name"] as? String) + XCTAssertEqual(["shoes"], responseTokens?["profile.categoryAffinities"] as? [String]) targetRequestExpectation.fulfill() } Target.retrieveLocationContent([retrieveRequest]) diff --git a/AEPTarget/Tests/TestHelpers/NamedCollectionDataStore+clear.swift b/AEPTarget/Tests/TestHelpers/NamedCollectionDataStore+clear.swift new file mode 100644 index 0000000..ed62e71 --- /dev/null +++ b/AEPTarget/Tests/TestHelpers/NamedCollectionDataStore+clear.swift @@ -0,0 +1,38 @@ +/* + Copyright 2024 Adobe. All rights reserved. + This file is licensed to you under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. You may obtain a copy + of the License at http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software distributed under + the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS + OF ANY KIND, either express or implied. See the License for the specific language + governing permissions and limitations under the License. + */ + +import AEPServices +import Foundation + +extension NamedCollectionDataStore { + static func clear(appGroup: String? = nil) { + if let appGroup = appGroup, !appGroup.isEmpty { + guard let directory = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: appGroup)?.appendingPathComponent("com.adobe.aep.datastore", isDirectory: true).path else { + return + } + guard let filePaths = try? FileManager.default.contentsOfDirectory(atPath: directory) else { + return + } + for filePath in filePaths { + try? FileManager.default.removeItem(atPath: directory + "/" + filePath) + } + } else { + let directory = FileManager.default.urls(for: .libraryDirectory, in: .allDomainsMask)[0].appendingPathComponent("com.adobe.aep.datastore", isDirectory: true).path + guard let filePaths = try? FileManager.default.contentsOfDirectory(atPath: directory) else { + return + } + for filePath in filePaths { + try? FileManager.default.removeItem(atPath: directory + "/" + filePath) + } + } + } +} diff --git a/AEPTarget/Tests/TestHelpers/TargetTestConstants.swift b/AEPTarget/Tests/TestHelpers/TargetTestConstants.swift index 3d8d7b8..8e19b87 100644 --- a/AEPTarget/Tests/TestHelpers/TargetTestConstants.swift +++ b/AEPTarget/Tests/TestHelpers/TargetTestConstants.swift @@ -11,7 +11,7 @@ */ enum TargetTestConstants { - static let EXTENSION_VERSION = "4.0.2" + static let EXTENSION_VERSION = "4.0.3" // preview parameters static let PREVIEW_MESSAGE_ID = "target-preview-message-id" static let PREVIEW_PARAMETERS = "at_preview_params" diff --git a/AEPTarget/Tests/TestHelpers/UserDefaults+clear.swift b/AEPTarget/Tests/TestHelpers/UserDefaults+clear.swift index bd10ef3..19f7114 100644 --- a/AEPTarget/Tests/TestHelpers/UserDefaults+clear.swift +++ b/AEPTarget/Tests/TestHelpers/UserDefaults+clear.swift @@ -12,10 +12,20 @@ import Foundation extension UserDefaults { - static func clear() { - for _ in 0 ... 5 { - for key in UserDefaults.standard.dictionaryRepresentation().keys { - UserDefaults.standard.removeObject(forKey: key) + static func clear(appGroup: String? = nil) { + if let appGroup = appGroup, + !appGroup.isEmpty, + let userDefaults = UserDefaults(suiteName: appGroup) { + for _ in 0 ... 5 { + for key in userDefaults.dictionaryRepresentation().keys { + userDefaults.removeObject(forKey: key) + } + } + } else { + for _ in 0 ... 5 { + for key in UserDefaults.standard.dictionaryRepresentation().keys { + UserDefaults.standard.removeObject(forKey: key) + } } } } diff --git a/AEPTarget/Tests/UnitTests/TargetStateTests.swift b/AEPTarget/Tests/UnitTests/TargetStateTests.swift index 8464837..7966ea6 100644 --- a/AEPTarget/Tests/UnitTests/TargetStateTests.swift +++ b/AEPTarget/Tests/UnitTests/TargetStateTests.swift @@ -17,7 +17,7 @@ import XCTest class TargetStateTests: XCTestCase { override func setUpWithError() throws { - UserDefaults.clear() + NamedCollectionDataStore.clear() ServiceProvider.shared.namedKeyValueService.setAppGroup(nil) } diff --git a/AEPTarget/Tests/UnitTests/TargetTests.swift b/AEPTarget/Tests/UnitTests/TargetTests.swift index bd74e7f..c307af6 100644 --- a/AEPTarget/Tests/UnitTests/TargetTests.swift +++ b/AEPTarget/Tests/UnitTests/TargetTests.swift @@ -25,32 +25,6 @@ class TargetTests: XCTestCase { target.onRegistered() } - private func cleanUserDefaults() { - for _ in 0 ... 5 { - for key in getUserDefaults().dictionaryRepresentation().keys { - UserDefaults.standard.removeObject(forKey: key) - } - } - for _ in 0 ... 5 { - for key in UserDefaults.standard.dictionaryRepresentation().keys { - UserDefaults.standard.removeObject(forKey: key) - } - } - ServiceProvider.shared.namedKeyValueService.setAppGroup(nil) - } - - private func getTargetDataStore() -> NamedCollectionDataStore { - return NamedCollectionDataStore(name: "com.adobe.module.target") - } - - private func getUserDefaults() -> UserDefaults { - if let appGroup = ServiceProvider.shared.namedKeyValueService.getAppGroup(), !appGroup.isEmpty { - return UserDefaults(suiteName: appGroup) ?? UserDefaults.standard - } - - return UserDefaults.standard - } - // MARK: - Unit Tests func testRegisterExtension() { diff --git a/AEPTarget/Tests/UnitTests/TargetV4MigratorTests.swift b/AEPTarget/Tests/UnitTests/TargetV4MigratorTests.swift index eb816fc..0e88f41 100644 --- a/AEPTarget/Tests/UnitTests/TargetV4MigratorTests.swift +++ b/AEPTarget/Tests/UnitTests/TargetV4MigratorTests.swift @@ -19,18 +19,11 @@ class TargetV4MigratorTests: XCTestCase { private let appGroup = "test_app_group" override func setUpWithError() throws { - if let userDefaults = UserDefaults(suiteName: appGroup) { - for _ in 0 ... 5 { - for key in userDefaults.dictionaryRepresentation().keys { - userDefaults.removeObject(forKey: key) - } - } - } - for _ in 0 ... 5 { - for key in UserDefaults.standard.dictionaryRepresentation().keys { - UserDefaults.standard.removeObject(forKey: key) - } - } + UserDefaults.clear() + UserDefaults.clear(appGroup: appGroup) + + NamedCollectionDataStore.clear() + NamedCollectionDataStore.clear(appGroup: appGroup) ServiceProvider.shared.namedKeyValueService.setAppGroup(nil) } diff --git a/AEPTarget/Tests/UnitTests/TargetV5MigratorTests.swift b/AEPTarget/Tests/UnitTests/TargetV5MigratorTests.swift index e1af10f..6be6268 100644 --- a/AEPTarget/Tests/UnitTests/TargetV5MigratorTests.swift +++ b/AEPTarget/Tests/UnitTests/TargetV5MigratorTests.swift @@ -19,18 +19,11 @@ class TargetV5MigratorTests: XCTestCase { private let appGroup = "test_app_group" override func setUpWithError() throws { - if let userDefaults = UserDefaults(suiteName: appGroup) { - for _ in 0 ... 5 { - for key in userDefaults.dictionaryRepresentation().keys { - userDefaults.removeObject(forKey: key) - } - } - } - for _ in 0 ... 5 { - for key in UserDefaults.standard.dictionaryRepresentation().keys { - UserDefaults.standard.removeObject(forKey: key) - } - } + UserDefaults.clear() + UserDefaults.clear(appGroup: appGroup) + + NamedCollectionDataStore.clear() + NamedCollectionDataStore.clear(appGroup: appGroup) ServiceProvider.shared.namedKeyValueService.setAppGroup(nil) } diff --git a/AEPTargetDemoApp/ContentView.swift b/AEPTargetDemoApp/ContentView.swift index 19aa815..e686d99 100644 --- a/AEPTargetDemoApp/ContentView.swift +++ b/AEPTargetDemoApp/ContentView.swift @@ -156,7 +156,7 @@ struct ContentView: View { print("------") print("Content: \(content ?? "")") - let responseTokens = data?["responseTokens"] as? [String: String] ?? [:] + let responseTokens = data?["responseTokens"] as? [String: Any] ?? [:] print("Response tokens: \(responseTokens as AnyObject)") let analyticsPayload = data?["analytics.payload"] as? [String: String] ?? [:] @@ -169,7 +169,7 @@ struct ContentView: View { print("------") print("Content: \(content ?? "")") - let responseTokens = data?["responseTokens"] as? [String: String] ?? [:] + let responseTokens = data?["responseTokens"] as? [String: Any] ?? [:] print("Response tokens: \(responseTokens as AnyObject)") let analyticsPayload = data?["analytics.payload"] as? [String: String] ?? [:] diff --git a/Documentation/AEPTarget.md b/Documentation/AEPTarget.md index 2c64d71..80365c1 100644 --- a/Documentation/AEPTarget.md +++ b/Documentation/AEPTarget.md @@ -184,7 +184,7 @@ static func retrieveLocationContent(_ requestArray: [TargetRequest], with target // Read the data dictionary containing one or more of response tokens, analytics payload and click-tracking analytics payload, if available. if let data = data { - let responseTokens = data["responseTokens"] as? [String: String] ?? [:] + let responseTokens = data["responseTokens"] as? [String: Any] ?? [:] let analyticsPayload = data["analytics.payload"] as? [String: String] ?? [:] diff --git a/Podfile.lock b/Podfile.lock index f981056..885ad5b 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -2,20 +2,20 @@ PODS: - AEPAnalytics (4.0.0): - AEPCore (>= 4.0.0) - AEPServices (>= 4.0.0) - - AEPAssurance (4.0.0): + - AEPAssurance (4.1.1): - AEPCore (>= 4.0.0) - AEPServices (>= 4.0.0) - - AEPCore (4.1.0): + - AEPCore (4.2.2): - AEPRulesEngine (>= 4.0.0) - - AEPServices (>= 4.1.0) - - AEPIdentity (4.1.0): - - AEPCore (>= 4.1.0) - - AEPLifecycle (4.1.0): - - AEPCore (>= 4.1.0) + - AEPServices (>= 4.2.2) + - AEPIdentity (4.2.2): + - AEPCore (>= 4.2.2) + - AEPLifecycle (4.2.2): + - AEPCore (>= 4.2.2) - AEPRulesEngine (4.0.0) - - AEPServices (4.1.0) - - AEPSignal (4.1.0): - - AEPCore (>= 4.1.0) + - AEPServices (4.2.2) + - AEPSignal (4.2.2): + - AEPCore (>= 4.2.2) - SwiftLint (0.52.0) - SwiftyJSON (5.0.1) @@ -44,16 +44,16 @@ SPEC REPOS: SPEC CHECKSUMS: AEPAnalytics: a510eb9653fac7f913965ad4291c8d51f74ffdcd - AEPAssurance: 4fa3138ddd7308c1f9923570f4d2b0b8526a916f - AEPCore: 20fb832a7467b25ca4aca186c0a5a1e3c0c6abc3 - AEPIdentity: 88671626d6043a488896ee7d71483a8bcec80739 - AEPLifecycle: 97693ea99ef9deb818b726a4e429ef96abb1353e + AEPAssurance: 765587ef65481bab544aa25efcfa294e14161d49 + AEPCore: 3c0367f3454ae9950ae1f92f0d5f417ed747a49b + AEPIdentity: 57e6b330e8665389ac260c0c53dd779900335fb7 + AEPLifecycle: 7391e64fc0dc0b85735bf807e471d8076edb391d AEPRulesEngine: 458450a34922823286ead045a0c2bd8c27e224c6 - AEPServices: d94555679870311d2f1391c5d7a5de590fd1f3c0 - AEPSignal: 9152e68bae462276f57ac63666e879cc7ff7c302 + AEPServices: cc895946c9fb56a74334bf3950a3b067b073fcd1 + AEPSignal: 092b5f92bf2d64db844309fe8b0fe81e0898f513 SwiftLint: 13280e21cdda6786ad908dc6e416afe5acd1fcb7 SwiftyJSON: 2f33a42c6fbc52764d96f13368585094bfd8aa5e PODFILE CHECKSUM: 1bd89ae58d6428500bd6e1790c6f8c5528439c6c -COCOAPODS: 1.12.1 +COCOAPODS: 1.14.2