From 40a323d6843e3911cb707b0eae5eb0000efcdf1c Mon Sep 17 00:00:00 2001 From: Vladimir Espinola Date: Thu, 13 Jun 2024 12:00:28 -0400 Subject: [PATCH 1/7] added update domain method --- Example/Base.lproj/Main.storyboard | 157 +++++++++++++------- Example/CreativeUITest/Pages/HomePage.swift | 1 + Example/Example/ViewController.m | 75 +++++++--- Sources/API/ATTNAPI.swift | 5 + Sources/Public/SDK/ATTNSDK.swift | 8 + 5 files changed, 169 insertions(+), 77 deletions(-) diff --git a/Example/Base.lproj/Main.storyboard b/Example/Base.lproj/Main.storyboard index 1194a61..821d493 100644 --- a/Example/Base.lproj/Main.storyboard +++ b/Example/Base.lproj/Main.storyboard @@ -1,9 +1,9 @@ - + - + @@ -16,7 +16,7 @@ - + @@ -35,66 +35,107 @@ - + - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + + + + + - + + + + + + + - + @@ -159,7 +200,7 @@ - + @@ -174,6 +215,8 @@ + + diff --git a/Example/CreativeUITest/Pages/HomePage.swift b/Example/CreativeUITest/Pages/HomePage.swift index af6e323..d81226f 100644 --- a/Example/CreativeUITest/Pages/HomePage.swift +++ b/Example/CreativeUITest/Pages/HomePage.swift @@ -28,6 +28,7 @@ struct HomePage: Page { XCTFail("Push me to Creative is not visible") return self } + sleep(1) XCTAssertTrue(creativeButton.isHittable) return self } diff --git a/Example/Example/ViewController.m b/Example/Example/ViewController.m index 1ea95c9..e41e2f4 100644 --- a/Example/Example/ViewController.m +++ b/Example/Example/ViewController.m @@ -22,27 +22,9 @@ @implementation ViewController { - (void)viewDidLoad { [super viewDidLoad]; - self.view.backgroundColor = [UIColor systemGray3Color]; - - CGFloat contentWidth = self.scrollView.bounds.size.width; - CGFloat contentHeight = self.scrollView.bounds.size.height * 3; - self.scrollView.contentSize = CGSizeMake(contentWidth, contentHeight); - - CGFloat subviewHeight = (CGFloat)120; - CGFloat currentViewOffset = (CGFloat)600; - - while (currentViewOffset < contentHeight) { - CGRect frame = CGRectInset(CGRectMake(0, currentViewOffset, contentWidth, subviewHeight), 5, 5); - CGFloat hue = currentViewOffset / contentHeight; - UIView *subview = [[UIView alloc] initWithFrame:frame]; - subview.backgroundColor = [UIColor colorWithHue:hue saturation:1 brightness:1 alpha:1]; - [self.scrollView addSubview:subview]; - - currentViewOffset += subviewHeight; - } // Replace with your Attentive domain to test with your Attentive account - _domain = @"YOUR_ATTENTIVE_DOMAIN"; + _domain = @"mobileapps"; _mode = @"production"; // Setup for Testing purposes only @@ -66,7 +48,7 @@ - (void)viewDidLoad { [sdk identify:_userIdentifiers]; // Attentive Example app specific setup code - [_domainLabel setText:_domain]; + [_domainLabel setText: [NSString stringWithFormat:@"Domain: %@", _domain]]; } - (IBAction)creativeButtonPress:(id)sender { @@ -113,6 +95,45 @@ - (IBAction)clearUserButtonPressed:(id)sender { [sdk clearUser]; } +- (IBAction)swichDomainTapped:(id)sender { + [self showAlertForSwitchingDomains]; +} + +- (void)showAlertForSwitchingDomains { + UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"Switch Domain" + message:@"Here you will test switching domains" + preferredStyle:UIAlertControllerStyleAlert]; + + [alertController addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) { + textField.placeholder = @"Enter the new Domain here"; + }]; + + UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"OK" + style:UIAlertActionStyleDefault + handler:^(UIAlertAction * _Nonnull action) { + UITextField *textField = alertController.textFields.firstObject; + [self handleDomainInput:textField.text]; + }]; + + UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"Cancel" + style:UIAlertActionStyleDefault + handler:nil]; + [alertController addAction:okAction]; + [alertController addAction:cancelAction]; + + [self presentViewController:alertController animated:YES completion:nil]; +} + +- (void)handleDomainInput:(NSString *)text { + [sdk updateDomain:text]; + + _domain = text; + + [_domainLabel setText: [NSString stringWithFormat:@"Domain: %@", _domain]]; + + [self showToast:[NSString stringWithFormat:@"New domain is %@", text]]; +} + // Method for setting up UI Tests. Only used for testing purposes - (void)setupForUITests { // Override the hard-coded domain & mode with the values from the environment variables @@ -135,4 +156,18 @@ - (void)setupForUITests { } } +- (void)showToast:(NSString*)message { + UIAlertController* alert = [UIAlertController alertControllerWithTitle:nil + message:message + preferredStyle:UIAlertControllerStyleAlert]; + + [self presentViewController:alert animated:YES completion:nil]; + + int duration = 3; // duration in seconds + + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, duration * NSEC_PER_SEC), dispatch_get_main_queue(), ^{ + [alert dismissViewControllerAnimated:YES completion:nil]; + }); +} + @end diff --git a/Sources/API/ATTNAPI.swift b/Sources/API/ATTNAPI.swift index 0700b6d..94ebeb5 100644 --- a/Sources/API/ATTNAPI.swift +++ b/Sources/API/ATTNAPI.swift @@ -66,6 +66,11 @@ final class ATTNAPI { self?.sendEventInternal(event: event, userIdentity: userIdentity, domain: geoAdjustedDomain, callback: callback) } } + + func update(domain newDomain: String) { + domain = newDomain + cachedGeoAdjustedDomain = nil + } } fileprivate extension ATTNAPI { diff --git a/Sources/Public/SDK/ATTNSDK.swift b/Sources/Public/SDK/ATTNSDK.swift index c9ae36c..5cfbbf2 100644 --- a/Sources/Public/SDK/ATTNSDK.swift +++ b/Sources/Public/SDK/ATTNSDK.swift @@ -147,6 +147,13 @@ public final class ATTNSDK: NSObject { public func clearUser() { userIdentity.clearUser() } + + @objc(updateDomain:) + public func update(domain: String) { + self.domain = domain + api.update(domain: domain) + api.send(userIdentity: userIdentity) + } } // MARK: Private Helpers @@ -157,6 +164,7 @@ fileprivate extension ATTNSDK { func closeCreative() { webView?.removeFromSuperview() + webView = nil ATTNSDK.isCreativeOpen = false triggerHandler?(ATTNCreativeTriggerStatus.closed) NSLog("Successfully closed creative") From 3691904431850c84e10dbe5827c6a741940dc952 Mon Sep 17 00:00:00 2001 From: Vladimir Espinola Date: Thu, 13 Jun 2024 16:16:04 -0400 Subject: [PATCH 2/7] added unit test --- Sources/API/ATTNAPI.swift | 7 ++- Sources/API/ATTNAPIProtocol.swift | 19 ++++++ Sources/Public/SDK/ATTNSDK.swift | 10 ++- Tests/Doubles/Spies/ATTNAPISpy.swift | 56 +++++++++++++++++ Tests/TestCases/ATTNSDKTests.swift | 67 +++++++++++++++++++++ attentive-ios-sdk.xcodeproj/project.pbxproj | 20 ++++++ 6 files changed, 174 insertions(+), 5 deletions(-) create mode 100644 Sources/API/ATTNAPIProtocol.swift create mode 100644 Tests/Doubles/Spies/ATTNAPISpy.swift create mode 100644 Tests/TestCases/ATTNSDKTests.swift diff --git a/Sources/API/ATTNAPI.swift b/Sources/API/ATTNAPI.swift index 94ebeb5..763a620 100644 --- a/Sources/API/ATTNAPI.swift +++ b/Sources/API/ATTNAPI.swift @@ -9,7 +9,7 @@ import Foundation public typealias ATTNAPICallback = (Data?, URL?, URLResponse?, Error?) -> Void -final class ATTNAPI { +final class ATTNAPI: ATTNAPIProtocol { private enum RequestConstants { static var dtagUrlFormat: String { "https://cdn.attn.tv/%@/dtag.js" } static var regexPattern: String { "='([a-z0-9-]+)[.]attn[.]tv'" } @@ -19,9 +19,10 @@ final class ATTNAPI { private var eventUrlProvider: ATTNEventURLProviding = ATTNEventURLProvider() private(set) var urlSession: URLSession - private(set) var cachedGeoAdjustedDomain: String? - private var domain: String + // MARK: ATTNAPIProtocol Properties + var cachedGeoAdjustedDomain: String? + var domain: String init(domain: String) { self.urlSession = URLSession.build(withUserAgent: userAgentBuilder.buildUserAgent()) diff --git a/Sources/API/ATTNAPIProtocol.swift b/Sources/API/ATTNAPIProtocol.swift new file mode 100644 index 0000000..392d61a --- /dev/null +++ b/Sources/API/ATTNAPIProtocol.swift @@ -0,0 +1,19 @@ +// +// ATTNAPIProtocol.swift +// attentive-ios-sdk-framework +// +// Created by Vladimir - Work on 2024-06-13. +// + +import Foundation + +protocol ATTNAPIProtocol { + var domain: String { get set } + var cachedGeoAdjustedDomain: String? { get set } + + func send(userIdentity: ATTNUserIdentity) + func send(userIdentity: ATTNUserIdentity, callback: ATTNAPICallback?) + func send(event: ATTNEvent, userIdentity: ATTNUserIdentity) + func send(event: ATTNEvent, userIdentity: ATTNUserIdentity, callback: ATTNAPICallback?) + func update(domain newDomain: String) +} diff --git a/Sources/Public/SDK/ATTNSDK.swift b/Sources/Public/SDK/ATTNSDK.swift index 5cfbbf2..f3bf68c 100644 --- a/Sources/Public/SDK/ATTNSDK.swift +++ b/Sources/Public/SDK/ATTNSDK.swift @@ -44,7 +44,7 @@ public final class ATTNSDK: NSObject { private var webView: WKWebView? private var triggerHandler: ATTNCreativeTriggerCompletionHandler? - private(set) var api: ATTNAPI + private(set) var api: ATTNAPIProtocol private(set) var userIdentity: ATTNUserIdentity private var domain: String @@ -57,7 +57,7 @@ public final class ATTNSDK: NSObject { self.mode = mode self.userIdentity = .init() - self.api = .init(domain: domain) + self.api = ATTNAPI(domain: domain) super.init() @@ -150,6 +150,7 @@ public final class ATTNSDK: NSObject { @objc(updateDomain:) public func update(domain: String) { + guard self.domain != domain else { return } self.domain = domain api.update(domain: domain) api.send(userIdentity: userIdentity) @@ -277,4 +278,9 @@ extension ATTNSDK { self.init(domain: domain, mode: mode) self.urlBuilder = urlBuilder } + + convenience init(api: ATTNAPIProtocol) { + self.init(domain: api.domain) + self.api = api + } } diff --git a/Tests/Doubles/Spies/ATTNAPISpy.swift b/Tests/Doubles/Spies/ATTNAPISpy.swift new file mode 100644 index 0000000..2b5ac75 --- /dev/null +++ b/Tests/Doubles/Spies/ATTNAPISpy.swift @@ -0,0 +1,56 @@ +// +// ATTNAPISpy.swift +// attentive-ios-sdk-framework +// +// Created by Vladimir - Work on 2024-06-13. +// + +import Foundation + +final class ATTNAPISpy: ATTNAPIProtocol { + private(set) var sendUserIdentityWasCalled = false + private(set) var sendUserIdentityCallbackWasCalled = false + private(set) var sendEventWasCalled = false + private(set) var sendEventCallbackWasCalled = false + private(set) var updateDomainWasCalled = false + private(set) var domainWasSetted = false + private(set) var cachedGeoAdjustedDomainWasSetted = false + + var domain: String { + didSet { + domainWasSetted = true + } + } + + var cachedGeoAdjustedDomain: String? { + didSet { + cachedGeoAdjustedDomainWasSetted = true + } + } + + init(domain: String) { + self.domain = domain + domainWasSetted = false + } + + func send(userIdentity: ATTNUserIdentity) { + sendUserIdentityWasCalled = true + } + + func send(userIdentity: ATTNUserIdentity, callback: ATTNAPICallback?) { + sendUserIdentityCallbackWasCalled = true + } + + func send(event: any ATTNEvent, userIdentity: ATTNUserIdentity) { + sendEventWasCalled = true + } + + func send(event: any ATTNEvent, userIdentity: ATTNUserIdentity, callback: ATTNAPICallback?) { + sendEventCallbackWasCalled = true + } + + func update(domain newDomain: String) { + domain = newDomain + updateDomainWasCalled = true + } +} diff --git a/Tests/TestCases/ATTNSDKTests.swift b/Tests/TestCases/ATTNSDKTests.swift new file mode 100644 index 0000000..e6192d5 --- /dev/null +++ b/Tests/TestCases/ATTNSDKTests.swift @@ -0,0 +1,67 @@ +// +// ATTNSDKTests.swift +// attentive-ios-sdk Tests +// +// Created by Vladimir - Work on 2024-06-13. +// + +import XCTest +@testable import ATTNSDKFramework + +final class ATTNSDKTests: XCTestCase { + private var sut: ATTNSDK! + private var apiSpy: ATTNAPISpy! + private let testDomain = "TEST_DOMAIN" + + override func setUp() { + super.setUp() + apiSpy = ATTNAPISpy(domain: testDomain) + sut = ATTNSDK(api: apiSpy) + } + + override func tearDown() { + sut = nil + apiSpy = nil + super.tearDown() + } + + func testUpdateDomain_newDomain_willUpdateAPIDomainProperty() { + let newDomain = "NEW_DOMAIN" + + XCTAssertFalse(apiSpy.updateDomainWasCalled) + XCTAssertEqual(apiSpy.domain, testDomain) + + sut.update(domain: newDomain) + + XCTAssertTrue(apiSpy.updateDomainWasCalled) + XCTAssertTrue(apiSpy.domainWasSetted) + XCTAssertTrue(apiSpy.sendUserIdentityWasCalled) + + XCTAssertEqual(apiSpy.domain, newDomain) + } + + func testUpdateDomain_sameDomain_willNotUpdateAPIDomainProperty() { + XCTAssertFalse(apiSpy.updateDomainWasCalled) + XCTAssertEqual(apiSpy.domain, testDomain) + + sut.update(domain: testDomain) + + XCTAssertFalse(apiSpy.updateDomainWasCalled) + XCTAssertFalse(apiSpy.domainWasSetted) + XCTAssertFalse(apiSpy.sendUserIdentityWasCalled) + + XCTAssertEqual(apiSpy.domain, testDomain) + } + +// func testUpdateDomain_newDomain_willUpdateCreativeURL() { +// XCTAssertFalse(apiSpy.updateDomainWasCalled) +// XCTAssertEqual(apiSpy.domain, testDomain) +// +// sut.update(domain: testDomain) +// +// XCTAssertEqual(apiSpy.domain, testDomain) +// +// +// } +} + diff --git a/attentive-ios-sdk.xcodeproj/project.pbxproj b/attentive-ios-sdk.xcodeproj/project.pbxproj index 2781f6c..9b492e7 100644 --- a/attentive-ios-sdk.xcodeproj/project.pbxproj +++ b/attentive-ios-sdk.xcodeproj/project.pbxproj @@ -41,6 +41,9 @@ FB35C1992C0E5365009FA048 /* ATTNInfoEvent+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = FB35C1982C0E5365009FA048 /* ATTNInfoEvent+Extension.swift */; }; FB35C19B2C0E53F9009FA048 /* ATTNCustomEvent+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = FB35C19A2C0E53F9009FA048 /* ATTNCustomEvent+Extension.swift */; }; FB60AF0B2C1211C700C61537 /* ATTNEventURLProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = FB60AF0A2C1211C700C61537 /* ATTNEventURLProvider.swift */; }; + FB65536A2C1B72D4008DB3B1 /* ATTNSDKTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = FB6553692C1B72D4008DB3B1 /* ATTNSDKTests.swift */; }; + FB65536C2C1B74A9008DB3B1 /* ATTNAPIProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = FB65536B2C1B74A9008DB3B1 /* ATTNAPIProtocol.swift */; }; + FB65536E2C1B7747008DB3B1 /* ATTNAPISpy.swift in Sources */ = {isa = PBXBuildFile; fileRef = FB65536D2C1B7747008DB3B1 /* ATTNAPISpy.swift */; }; FB90EF0B2C109CB4004DFC4A /* ATTNAPIITTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = FB90EF0A2C109CB4004DFC4A /* ATTNAPIITTests.swift */; }; FB90EF0D2C10A7F7004DFC4A /* NSURLSessionDataTaskMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = FB90EF0C2C10A7F7004DFC4A /* NSURLSessionDataTaskMock.swift */; }; FB90EF0F2C10A81E004DFC4A /* NSURLSessionMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = FB90EF0E2C10A81E004DFC4A /* NSURLSessionMock.swift */; }; @@ -133,6 +136,9 @@ FB35C1982C0E5365009FA048 /* ATTNInfoEvent+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ATTNInfoEvent+Extension.swift"; sourceTree = ""; }; FB35C19A2C0E53F9009FA048 /* ATTNCustomEvent+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ATTNCustomEvent+Extension.swift"; sourceTree = ""; }; FB60AF0A2C1211C700C61537 /* ATTNEventURLProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ATTNEventURLProvider.swift; sourceTree = ""; }; + FB6553692C1B72D4008DB3B1 /* ATTNSDKTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ATTNSDKTests.swift; sourceTree = ""; }; + FB65536B2C1B74A9008DB3B1 /* ATTNAPIProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ATTNAPIProtocol.swift; sourceTree = ""; }; + FB65536D2C1B7747008DB3B1 /* ATTNAPISpy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ATTNAPISpy.swift; sourceTree = ""; }; FB90EF0A2C109CB4004DFC4A /* ATTNAPIITTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ATTNAPIITTests.swift; sourceTree = ""; }; FB90EF0C2C10A7F7004DFC4A /* NSURLSessionDataTaskMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSURLSessionDataTaskMock.swift; sourceTree = ""; }; FB90EF0E2C10A81E004DFC4A /* NSURLSessionMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSURLSessionMock.swift; sourceTree = ""; }; @@ -272,6 +278,7 @@ FB2983D32C0F73990039759C /* Doubles */ = { isa = PBXGroup; children = ( + FB65536F2C1B775D008DB3B1 /* Spies */, FB2983D22C0F73990039759C /* Mocks */, ); path = Doubles; @@ -300,6 +307,7 @@ FB2984052C0FA2DA0039759C /* ATTNEventTrackerTests.swift */, FB2984072C0FAE040039759C /* ATTNAPITests.swift */, FB90EF0A2C109CB4004DFC4A /* ATTNAPIITTests.swift */, + FB6553692C1B72D4008DB3B1 /* ATTNSDKTests.swift */, ); path = TestCases; sourceTree = ""; @@ -340,6 +348,14 @@ path = SDK; sourceTree = ""; }; + FB65536F2C1B775D008DB3B1 /* Spies */ = { + isa = PBXGroup; + children = ( + FB65536D2C1B7747008DB3B1 /* ATTNAPISpy.swift */, + ); + path = Spies; + sourceTree = ""; + }; FBA9F9E62C0A77AB00C65024 /* API */ = { isa = PBXGroup; children = ( @@ -347,6 +363,7 @@ FBA9F9E52C0A77AB00C65024 /* ATTNEventRequest.swift */, FB35C1862C0E3929009FA048 /* ATTNEventTypes.swift */, FB35C1882C0E3AF8009FA048 /* ATTNExternalVendorTypes.swift */, + FB65536B2C1B74A9008DB3B1 /* ATTNAPIProtocol.swift */, ); path = API; sourceTree = ""; @@ -592,6 +609,7 @@ FB35C1832C0E1FD7009FA048 /* URLSession+Extension.swift in Sources */, FB35C1872C0E3929009FA048 /* ATTNEventTypes.swift in Sources */, FBA9FA162C0A77AB00C65024 /* ATTNPrice.swift in Sources */, + FB65536E2C1B7747008DB3B1 /* ATTNAPISpy.swift in Sources */, FB35C1912C0E506D009FA048 /* ATTNEventRequestProvider.swift in Sources */, FB35C18B2C0E3F27009FA048 /* ATTNEvent+Extension.swift in Sources */, FB60AF0B2C1211C700C61537 /* ATTNEventURLProvider.swift in Sources */, @@ -613,6 +631,7 @@ FBA9FA102C0A77AB00C65024 /* ATTNAddToCartEvent.swift in Sources */, FB35C17B2C0E0353009FA048 /* ATTNIdentifierType.swift in Sources */, FBA9FA0A2C0A77AB00C65024 /* ATTNCreativeUrlProvider.swift in Sources */, + FB65536C2C1B74A9008DB3B1 /* ATTNAPIProtocol.swift in Sources */, FB35C17D2C0E039E009FA048 /* ATTNConstants.swift in Sources */, FBA9FA082C0A77AB00C65024 /* Dictionary+Extension.swift in Sources */, FBA9FA152C0A77AB00C65024 /* ATTNOrder.swift in Sources */, @@ -635,6 +654,7 @@ FB2983FA2C0F80A30039759C /* ATTNPersistentStorageTests.swift in Sources */, FB2983E52C0F73990039759C /* ATTNUserAgentBuilderMock.swift in Sources */, FB2984082C0FAE040039759C /* ATTNAPITests.swift in Sources */, + FB65536A2C1B72D4008DB3B1 /* ATTNSDKTests.swift in Sources */, FB90EF0D2C10A7F7004DFC4A /* NSURLSessionDataTaskMock.swift in Sources */, FB2983FE2C0F85770039759C /* ATTNCustomEventTests.swift in Sources */, FB2984002C0F86270039759C /* ATTNCreativeUrlFormatterTests.swift in Sources */, From 2c83adada6543d5de4878ed99c77dadd26ce6561 Mon Sep 17 00:00:00 2001 From: Vladimir Espinola Date: Fri, 14 Jun 2024 09:43:57 -0400 Subject: [PATCH 3/7] expanded code coverage for ATTNSDK --- Sources/Public/ATTNEventTracker.swift | 4 ++ Sources/Public/SDK/ATTNSDK.swift | 8 +++- Tests/Doubles/Spies/ATTNAPISpy.swift | 1 + .../Spies/ATTNCreativeUrlProviderSpy.swift | 20 ++++++++ Tests/TestCases/ATTNSDKTests.swift | 48 ++++++++++++++----- attentive-ios-sdk.xcodeproj/project.pbxproj | 8 +++- 6 files changed, 73 insertions(+), 16 deletions(-) create mode 100644 Tests/Doubles/Spies/ATTNCreativeUrlProviderSpy.swift diff --git a/Sources/Public/ATTNEventTracker.swift b/Sources/Public/ATTNEventTracker.swift index d2bd90a..89c1d96 100644 --- a/Sources/Public/ATTNEventTracker.swift +++ b/Sources/Public/ATTNEventTracker.swift @@ -44,4 +44,8 @@ extension ATTNEventTracker { static func destroy() { _sharedInstance = nil } + + func getSdk() -> ATTNSDK { + sdk + } } diff --git a/Sources/Public/SDK/ATTNSDK.swift b/Sources/Public/SDK/ATTNSDK.swift index f3bf68c..dffc4a7 100644 --- a/Sources/Public/SDK/ATTNSDK.swift +++ b/Sources/Public/SDK/ATTNSDK.swift @@ -279,8 +279,14 @@ extension ATTNSDK { self.urlBuilder = urlBuilder } - convenience init(api: ATTNAPIProtocol) { + convenience init(api: ATTNAPIProtocol, urlBuilder: ATTNCreativeUrlProviding? = nil) { self.init(domain: api.domain) self.api = api + guard let urlBuilder = urlBuilder else { return } + self.urlBuilder = urlBuilder + } + + func getDomain() -> String { + domain } } diff --git a/Tests/Doubles/Spies/ATTNAPISpy.swift b/Tests/Doubles/Spies/ATTNAPISpy.swift index 2b5ac75..cb278e2 100644 --- a/Tests/Doubles/Spies/ATTNAPISpy.swift +++ b/Tests/Doubles/Spies/ATTNAPISpy.swift @@ -6,6 +6,7 @@ // import Foundation +@testable import ATTNSDKFramework final class ATTNAPISpy: ATTNAPIProtocol { private(set) var sendUserIdentityWasCalled = false diff --git a/Tests/Doubles/Spies/ATTNCreativeUrlProviderSpy.swift b/Tests/Doubles/Spies/ATTNCreativeUrlProviderSpy.swift new file mode 100644 index 0000000..eea8460 --- /dev/null +++ b/Tests/Doubles/Spies/ATTNCreativeUrlProviderSpy.swift @@ -0,0 +1,20 @@ +// +// ATTNCreativeUrlProviderSpy.swift +// attentive-ios-sdk-framework +// +// Created by Vladimir - Work on 2024-06-14. +// + +import Foundation +@testable import ATTNSDKFramework + +final class ATTNCreativeUrlProviderSpy: ATTNCreativeUrlProviding { + private(set) var buildCompanyCreativeUrlWasCalled = false + private(set) var usedDomain: String? + + func buildCompanyCreativeUrl(forDomain domain: String, mode: String, userIdentity: ATTNSDKFramework.ATTNUserIdentity) -> String { + buildCompanyCreativeUrlWasCalled = true + usedDomain = domain + return "" + } +} diff --git a/Tests/TestCases/ATTNSDKTests.swift b/Tests/TestCases/ATTNSDKTests.swift index e6192d5..151674b 100644 --- a/Tests/TestCases/ATTNSDKTests.swift +++ b/Tests/TestCases/ATTNSDKTests.swift @@ -11,23 +11,29 @@ import XCTest final class ATTNSDKTests: XCTestCase { private var sut: ATTNSDK! private var apiSpy: ATTNAPISpy! + private var creativeUrlProviderSpy: ATTNCreativeUrlProviderSpy! + private let testDomain = "TEST_DOMAIN" + private let newDomain = "NEW_DOMAIN" override func setUp() { super.setUp() + creativeUrlProviderSpy = ATTNCreativeUrlProviderSpy() apiSpy = ATTNAPISpy(domain: testDomain) - sut = ATTNSDK(api: apiSpy) + sut = ATTNSDK(api: apiSpy, urlBuilder: creativeUrlProviderSpy) } override func tearDown() { + ATTNEventTracker.destroy() + + creativeUrlProviderSpy = nil sut = nil apiSpy = nil + super.tearDown() } func testUpdateDomain_newDomain_willUpdateAPIDomainProperty() { - let newDomain = "NEW_DOMAIN" - XCTAssertFalse(apiSpy.updateDomainWasCalled) XCTAssertEqual(apiSpy.domain, testDomain) @@ -53,15 +59,31 @@ final class ATTNSDKTests: XCTestCase { XCTAssertEqual(apiSpy.domain, testDomain) } -// func testUpdateDomain_newDomain_willUpdateCreativeURL() { -// XCTAssertFalse(apiSpy.updateDomainWasCalled) -// XCTAssertEqual(apiSpy.domain, testDomain) -// -// sut.update(domain: testDomain) -// -// XCTAssertEqual(apiSpy.domain, testDomain) -// -// -// } + func testUpdateDomain_newDomain_willUpdateCreativeURL() { + XCTAssertNotEqual(creativeUrlProviderSpy.usedDomain, newDomain) + + sut.update(domain: newDomain) + + XCTAssertEqual(apiSpy.domain, newDomain) + + sut.trigger(UIView()) + + XCTAssertTrue(creativeUrlProviderSpy.buildCompanyCreativeUrlWasCalled) + XCTAssertEqual(creativeUrlProviderSpy.usedDomain, newDomain) + } + + func testUpdateDomain_newDomain_willBeReflectedOnEventTracking() { + sut.update(domain: newDomain) + + ATTNEventTracker.setup(with: sut) + + ATTNEventTracker.sharedInstance()?.record(event: ATTNInfoEvent()) + + XCTAssertTrue(apiSpy.sendEventWasCalled) + + let sdk = ATTNEventTracker.sharedInstance()?.getSdk() + + XCTAssertEqual(sdk?.getDomain(), newDomain) + } } diff --git a/attentive-ios-sdk.xcodeproj/project.pbxproj b/attentive-ios-sdk.xcodeproj/project.pbxproj index 9b492e7..8a3d068 100644 --- a/attentive-ios-sdk.xcodeproj/project.pbxproj +++ b/attentive-ios-sdk.xcodeproj/project.pbxproj @@ -12,6 +12,8 @@ 58332EE1292EC26000B1ECF3 /* LICENSE in Resources */ = {isa = PBXBuildFile; fileRef = 58332EDF292EC26000B1ECF3 /* LICENSE */; }; 58B01AC5294D44140001CEBF /* libOCMock.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 58B01AB6294D44140001CEBF /* libOCMock.a */; }; 58D52E1D292EC52B00CF32DE /* ATTNSDKFramework.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 58332EC3292EC18800B1ECF3 /* ATTNSDKFramework.framework */; }; + FB080C712C1C755A00834BAA /* ATTNAPISpy.swift in Sources */ = {isa = PBXBuildFile; fileRef = FB65536D2C1B7747008DB3B1 /* ATTNAPISpy.swift */; }; + FB080C722C1C755F00834BAA /* ATTNCreativeUrlProviderSpy.swift in Sources */ = {isa = PBXBuildFile; fileRef = FB080C6F2C1C752E00834BAA /* ATTNCreativeUrlProviderSpy.swift */; }; FB2983E42C0F73990039759C /* ATTNAppInfoMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = FB2983D02C0F73990039759C /* ATTNAppInfoMock.swift */; }; FB2983E52C0F73990039759C /* ATTNUserAgentBuilderMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = FB2983D12C0F73990039759C /* ATTNUserAgentBuilderMock.swift */; }; FB2983F42C0F759D0039759C /* ATTNVisitorServiceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = FB2983F32C0F759D0039759C /* ATTNVisitorServiceTests.swift */; }; @@ -43,7 +45,6 @@ FB60AF0B2C1211C700C61537 /* ATTNEventURLProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = FB60AF0A2C1211C700C61537 /* ATTNEventURLProvider.swift */; }; FB65536A2C1B72D4008DB3B1 /* ATTNSDKTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = FB6553692C1B72D4008DB3B1 /* ATTNSDKTests.swift */; }; FB65536C2C1B74A9008DB3B1 /* ATTNAPIProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = FB65536B2C1B74A9008DB3B1 /* ATTNAPIProtocol.swift */; }; - FB65536E2C1B7747008DB3B1 /* ATTNAPISpy.swift in Sources */ = {isa = PBXBuildFile; fileRef = FB65536D2C1B7747008DB3B1 /* ATTNAPISpy.swift */; }; FB90EF0B2C109CB4004DFC4A /* ATTNAPIITTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = FB90EF0A2C109CB4004DFC4A /* ATTNAPIITTests.swift */; }; FB90EF0D2C10A7F7004DFC4A /* NSURLSessionDataTaskMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = FB90EF0C2C10A7F7004DFC4A /* NSURLSessionDataTaskMock.swift */; }; FB90EF0F2C10A81E004DFC4A /* NSURLSessionMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = FB90EF0E2C10A81E004DFC4A /* NSURLSessionMock.swift */; }; @@ -106,6 +107,7 @@ 58B01AC3294D44140001CEBF /* OCMConstraint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OCMConstraint.h; sourceTree = ""; }; 58B01AC4294D44140001CEBF /* OCMArg.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OCMArg.h; sourceTree = ""; }; 58D52E19292EC52B00CF32DE /* attentive-ios-sdk Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "attentive-ios-sdk Tests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; + FB080C6F2C1C752E00834BAA /* ATTNCreativeUrlProviderSpy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ATTNCreativeUrlProviderSpy.swift; sourceTree = ""; }; FB0E49E52BFBB1900025E281 /* Package.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Package.swift; sourceTree = ""; }; FB2983D02C0F73990039759C /* ATTNAppInfoMock.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ATTNAppInfoMock.swift; sourceTree = ""; }; FB2983D12C0F73990039759C /* ATTNUserAgentBuilderMock.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ATTNUserAgentBuilderMock.swift; sourceTree = ""; }; @@ -352,6 +354,7 @@ isa = PBXGroup; children = ( FB65536D2C1B7747008DB3B1 /* ATTNAPISpy.swift */, + FB080C6F2C1C752E00834BAA /* ATTNCreativeUrlProviderSpy.swift */, ); path = Spies; sourceTree = ""; @@ -609,7 +612,6 @@ FB35C1832C0E1FD7009FA048 /* URLSession+Extension.swift in Sources */, FB35C1872C0E3929009FA048 /* ATTNEventTypes.swift in Sources */, FBA9FA162C0A77AB00C65024 /* ATTNPrice.swift in Sources */, - FB65536E2C1B7747008DB3B1 /* ATTNAPISpy.swift in Sources */, FB35C1912C0E506D009FA048 /* ATTNEventRequestProvider.swift in Sources */, FB35C18B2C0E3F27009FA048 /* ATTNEvent+Extension.swift in Sources */, FB60AF0B2C1211C700C61537 /* ATTNEventURLProvider.swift in Sources */, @@ -645,6 +647,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + FB080C712C1C755A00834BAA /* ATTNAPISpy.swift in Sources */, FB90EF0B2C109CB4004DFC4A /* ATTNAPIITTests.swift in Sources */, FB90EF0F2C10A81E004DFC4A /* NSURLSessionMock.swift in Sources */, FB2983E42C0F73990039759C /* ATTNAppInfoMock.swift in Sources */, @@ -652,6 +655,7 @@ FB2983F62C0F7CF10039759C /* ATTNUserIdentityTests.swift in Sources */, FB2983F42C0F759D0039759C /* ATTNVisitorServiceTests.swift in Sources */, FB2983FA2C0F80A30039759C /* ATTNPersistentStorageTests.swift in Sources */, + FB080C722C1C755F00834BAA /* ATTNCreativeUrlProviderSpy.swift in Sources */, FB2983E52C0F73990039759C /* ATTNUserAgentBuilderMock.swift in Sources */, FB2984082C0FAE040039759C /* ATTNAPITests.swift in Sources */, FB65536A2C1B72D4008DB3B1 /* ATTNSDKTests.swift in Sources */, From 35f5da19e29a6ba3abc03795aa14224dd914ebff Mon Sep 17 00:00:00 2001 From: Vladimir Espinola Date: Fri, 14 Jun 2024 11:12:59 -0400 Subject: [PATCH 4/7] added UI Test for validating switch domain --- Example/CreativeUITest/CreativeUITest.swift | 25 +++++++- Example/CreativeUITest/Pages/HomePage.swift | 22 +++++++ Example/CreativeUITest/Pages/Page.swift | 12 ++++ .../Pages/SwitchDomainPage.swift | 58 +++++++++++++++++++ Example/Example.xcodeproj/project.pbxproj | 4 ++ Example/Example/ViewController.m | 2 +- 6 files changed, 121 insertions(+), 2 deletions(-) create mode 100644 Example/CreativeUITest/Pages/SwitchDomainPage.swift diff --git a/Example/CreativeUITest/CreativeUITest.swift b/Example/CreativeUITest/CreativeUITest.swift index 6fc9fe6..8af0c3f 100644 --- a/Example/CreativeUITest/CreativeUITest.swift +++ b/Example/CreativeUITest/CreativeUITest.swift @@ -30,7 +30,7 @@ final class CreativeUITest: XCTestCase, BaseXCTestCase { HomePage .tapOnPushMeToCreative() - .addDelay(seconds: 3) + .addDelay(seconds: 4) CreativePage.tapOnCloseCreative() @@ -96,6 +96,29 @@ final class CreativeUITest: XCTestCase, BaseXCTestCase { HomePage.verifyPushMeToCreativeIsHittable() } + + func testLoadCreative_switchDomain_shouldDisplayNewCreative() { + launch(with: .production) + + HomePage + .verifyDomainTitle(text: "mobileapps") + .tapOnSwitchDomain() + + SwitchDomainPage + .verifyIfTitleExists() + .fillDomainInput(text: "games") + .tapOnOk() + .addDelay(seconds: 1) + + HomePage + .verifyDomainTitle(text: "games") + .tapOnPushMeToCreative() + .addDelay(seconds: 4) + + CreativePage + .verifyIfElementExists(label: "AttentiveGames", elementType: .image) + .tapOnCloseCreative() + } } extension CreativeUITest { diff --git a/Example/CreativeUITest/Pages/HomePage.swift b/Example/CreativeUITest/Pages/HomePage.swift index d81226f..c70f94c 100644 --- a/Example/CreativeUITest/Pages/HomePage.swift +++ b/Example/CreativeUITest/Pages/HomePage.swift @@ -38,6 +38,24 @@ struct HomePage: Page { productTabItem.tapOnElement() return self } + + @discardableResult + static func tapOnSwitchDomain() -> Self.Type { + switchDomainButton.tapOnElement() + return self + } + + @discardableResult + static func verifyDomainTitle(text: String) -> Self.Type { + let domainLabel = app.staticTexts["Domain: \(text)"] + + guard domainLabel.elementExists() else { + XCTFail("Domain label does not exists") + return self + } + + return self + } } fileprivate extension HomePage { @@ -52,4 +70,8 @@ fileprivate extension HomePage { static var productTabItem: XCUIElement { app.tabBars.buttons["Product"] } + + static var switchDomainButton: XCUIElement { + app.buttons["Switch Domain"] + } } diff --git a/Example/CreativeUITest/Pages/Page.swift b/Example/CreativeUITest/Pages/Page.swift index 309390c..eb1fcbb 100644 --- a/Example/CreativeUITest/Pages/Page.swift +++ b/Example/CreativeUITest/Pages/Page.swift @@ -37,4 +37,16 @@ extension Page { window.tap() return self } + + @discardableResult + static func verifyIfElementExists(label: String, elementType: XCUIElement.ElementType) -> Self.Type { + let element = app.descendants(matching: elementType)[label] + + guard element.elementExists() else { + XCTFail("Element with label \(label) of type \(elementType) does not exists") + return self + } + + return self + } } diff --git a/Example/CreativeUITest/Pages/SwitchDomainPage.swift b/Example/CreativeUITest/Pages/SwitchDomainPage.swift new file mode 100644 index 0000000..d2c9e82 --- /dev/null +++ b/Example/CreativeUITest/Pages/SwitchDomainPage.swift @@ -0,0 +1,58 @@ +// +// SwitchDomainPage.swift +// CreativeUITest +// +// Created by Vladimir - Work on 2024-06-14. +// + +import XCTest + +struct SwitchDomainPage: Page { + private init() { } + + @discardableResult + static func tapOnOk() -> Self.Type { + okButton.tapOnElement() + return self + } + + @discardableResult + static func tapOnCancel() -> Self.Type { + cancelButton.tapOnElement() + return self + } + + @discardableResult + static func fillDomainInput(text: String) -> Self.Type { + domainTextField.tapOnElement() + domainTextField.fillTextField(text) + return self + } + + @discardableResult + static func verifyIfTitleExists() -> Self.Type { + guard title.elementExists() else { + XCTFail("Title does not exists") + return self + } + return self + } +} + +fileprivate extension SwitchDomainPage { + static var title: XCUIElement { + app.staticTexts["Switch Domain"] + } + + static var domainTextField: XCUIElement { + app.textFields["Enter the new Domain here"] + } + + static var okButton: XCUIElement { + app.buttons["OK"] + } + + static var cancelButton: XCUIElement { + app.buttons["Cancel"] + } +} diff --git a/Example/Example.xcodeproj/project.pbxproj b/Example/Example.xcodeproj/project.pbxproj index a17d584..e6f9499 100644 --- a/Example/Example.xcodeproj/project.pbxproj +++ b/Example/Example.xcodeproj/project.pbxproj @@ -25,6 +25,7 @@ 69CCAF5C28DCDE5A007620BD /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 69CCAF5B28DCDE5A007620BD /* Assets.xcassets */; }; 69CCAF5F28DCDE5A007620BD /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 69CCAF5D28DCDE5A007620BD /* LaunchScreen.storyboard */; }; 69CCAF6228DCDE5A007620BD /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 69CCAF6128DCDE5A007620BD /* main.m */; }; + FB080C742C1C8AE500834BAA /* SwitchDomainPage.swift in Sources */ = {isa = PBXBuildFile; fileRef = FB080C732C1C8AE500834BAA /* SwitchDomainPage.swift */; }; FB2F35B32C18D4CE0016CAE8 /* ATTNSDKFramework.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FB2F35B22C18D4CE0016CAE8 /* ATTNSDKFramework.framework */; }; FB2F35B42C18D4CE0016CAE8 /* ATTNSDKFramework.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = FB2F35B22C18D4CE0016CAE8 /* ATTNSDKFramework.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; FB90EF122C10AE66004DFC4A /* CreativeUITest.swift in Sources */ = {isa = PBXBuildFile; fileRef = FB90EF112C10AE66004DFC4A /* CreativeUITest.swift */; }; @@ -82,6 +83,7 @@ 69CCAF6028DCDE5A007620BD /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 69CCAF6128DCDE5A007620BD /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 69D3C149299EF2D10027934F /* CreativeUITest.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CreativeUITest.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + FB080C732C1C8AE500834BAA /* SwitchDomainPage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwitchDomainPage.swift; sourceTree = ""; }; FB2F35B22C18D4CE0016CAE8 /* ATTNSDKFramework.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = ATTNSDKFramework.framework; sourceTree = BUILT_PRODUCTS_DIR; }; FB6723742C134C13008D5516 /* Example - Pod-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Example - Pod-Bridging-Header.h"; sourceTree = ""; }; FB90EF102C10AE66004DFC4A /* CreativeUITest-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "CreativeUITest-Bridging-Header.h"; sourceTree = ""; }; @@ -211,6 +213,7 @@ FB90EF1F2C10CF13004DFC4A /* SMSPage.swift */, FB90EF212C10D412004DFC4A /* PricacyPolicyPage.swift */, FB90EF232C10D83B004DFC4A /* ProductPage.swift */, + FB080C732C1C8AE500834BAA /* SwitchDomainPage.swift */, ); path = Pages; sourceTree = ""; @@ -392,6 +395,7 @@ FB90EF202C10CF13004DFC4A /* SMSPage.swift in Sources */, FB90EF152C10B871004DFC4A /* HomePage.swift in Sources */, FB90EF122C10AE66004DFC4A /* CreativeUITest.swift in Sources */, + FB080C742C1C8AE500834BAA /* SwitchDomainPage.swift in Sources */, FB90EF1C2C10B959004DFC4A /* XCUIElement+Extension.swift in Sources */, FB90EF172C10B887004DFC4A /* BaseXCTestCase.swift in Sources */, FB90EF222C10D412004DFC4A /* PricacyPolicyPage.swift in Sources */, diff --git a/Example/Example/ViewController.m b/Example/Example/ViewController.m index e41e2f4..caafe09 100644 --- a/Example/Example/ViewController.m +++ b/Example/Example/ViewController.m @@ -24,7 +24,7 @@ - (void)viewDidLoad { [super viewDidLoad]; // Replace with your Attentive domain to test with your Attentive account - _domain = @"mobileapps"; + _domain = @"YOUR_ATTENTIVE_DOMAIN"; _mode = @"production"; // Setup for Testing purposes only From 02e81642ab3993c0955cd1a537ee70e22fb29225 Mon Sep 17 00:00:00 2001 From: Vladimir Espinola Date: Fri, 14 Jun 2024 12:03:18 -0400 Subject: [PATCH 5/7] updated README --- README.md | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 51a3ec5..49f6718 100644 --- a/README.md +++ b/README.md @@ -72,7 +72,7 @@ file after installing the SDK: #### Swift ```swift -import attentive_ios_sdk +import ATTNSDKFramework ``` ```swift @@ -89,7 +89,8 @@ ATTNEventTracker.setup(with: sdk) #### Objective-C ```objectiveC -#import "attentive_ios_sdk/attentive-ios-sdk-umbrella.h" +#import "ATTNSDKFramework-Swift.h" +#import "ATTNSDKFramework-umbrella.h" ``` ```objectiveC @@ -223,6 +224,24 @@ ATTNPurchaseEvent* purchase = [[ATTNPurchaseEvent alloc] initWithItems:@[item] o [[ATTNEventTracker sharedInstance] recordEvent:purchase]; ``` +### Switch to another domain + +Reinitialize the SDK with a different domain. + +#### Swift + +```swift +let sdk = ATTNSDK(domain: "domain") +sdk.update(domain: "differentDomain") +``` + +#### Objective-C + +```objectivec +ATTNSDK *sdk = [[ATTNSDK alloc] initWithDomain:@"domain"]; +[sdk updateDomain: @"differentDomain"]; +``` + ### Clear the current user If the user logs out then the current user identifiers should be deleted: From 543517c9844a9e50fdc9a6a85cdb03765a9c716d Mon Sep 17 00:00:00 2001 From: Vladimir Espinola Date: Fri, 14 Jun 2024 13:07:12 -0400 Subject: [PATCH 6/7] replaced deprecated methods calls with new ones --- .../ExampleSwift.xcodeproj/project.pbxproj | 20 +++++++++---------- ExampleSwift/ExampleSwift/AppDelegate.swift | 12 +++++------ .../ExampleSwift/ProductViewController.swift | 10 +++++----- .../xcshareddata/swiftpm/Package.resolved | 8 ++++---- 4 files changed, 25 insertions(+), 25 deletions(-) diff --git a/ExampleSwift/ExampleSwift.xcodeproj/project.pbxproj b/ExampleSwift/ExampleSwift.xcodeproj/project.pbxproj index 385beec..0c5cd1c 100644 --- a/ExampleSwift/ExampleSwift.xcodeproj/project.pbxproj +++ b/ExampleSwift/ExampleSwift.xcodeproj/project.pbxproj @@ -21,9 +21,9 @@ 588EB7242995BC3A00C0163A /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 588EB7182995BBB700C0163A /* LaunchScreen.storyboard */; }; 588EB7252995BC3A00C0163A /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 587DC5C3299554B00082F8D0 /* Assets.xcassets */; }; 588EB7262995BC3A00C0163A /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 587DC5C82995551A0082F8D0 /* Main.storyboard */; }; + FB080C772C1CAF5C00834BAA /* ATTNSDKFramework in Frameworks */ = {isa = PBXBuildFile; productRef = FB080C762C1CAF5C00834BAA /* ATTNSDKFramework */; }; FB2F35B62C18D6950016CAE8 /* ATTNSDKFramework.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FB2F35B52C18D6950016CAE8 /* ATTNSDKFramework.framework */; }; FB2F35B72C18D6950016CAE8 /* ATTNSDKFramework.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = FB2F35B52C18D6950016CAE8 /* ATTNSDKFramework.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - FB6723732C134958008D5516 /* ATTNSDKFramework in Frameworks */ = {isa = PBXBuildFile; productRef = FB6723722C134958008D5516 /* ATTNSDKFramework */; }; /* End PBXBuildFile section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -68,7 +68,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - FB6723732C134958008D5516 /* ATTNSDKFramework in Frameworks */, + FB080C772C1CAF5C00834BAA /* ATTNSDKFramework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -169,7 +169,7 @@ ); name = "ExampleSwift - SPM"; packageProductDependencies = ( - FB6723722C134958008D5516 /* ATTNSDKFramework */, + FB080C762C1CAF5C00834BAA /* ATTNSDKFramework */, ); productName = ExampleSwift; productReference = 588EB72C2995BC3A00C0163A /* ExampleSwift - SPM.app */; @@ -200,7 +200,7 @@ ); mainGroup = 58389AA12987647900A31A35; packageReferences = ( - FB6723712C134958008D5516 /* XCRemoteSwiftPackageReference "attentive-ios-sdk" */, + FB080C752C1CAF5B00834BAA /* XCRemoteSwiftPackageReference "attentive-ios-sdk" */, ); productRefGroup = 58389AAB2987647900A31A35 /* Products */; projectDirPath = ""; @@ -600,20 +600,20 @@ /* End XCConfigurationList section */ /* Begin XCRemoteSwiftPackageReference section */ - FB6723712C134958008D5516 /* XCRemoteSwiftPackageReference "attentive-ios-sdk" */ = { + FB080C752C1CAF5B00834BAA /* XCRemoteSwiftPackageReference "attentive-ios-sdk" */ = { isa = XCRemoteSwiftPackageReference; - repositoryURL = "https://github.com/vespinola/attentive-ios-sdk.git"; + repositoryURL = "https://github.com/attentive-mobile/attentive-ios-sdk"; requirement = { - branch = main; - kind = branch; + kind = upToNextMajorVersion; + minimumVersion = 0.6.0; }; }; /* End XCRemoteSwiftPackageReference section */ /* Begin XCSwiftPackageProductDependency section */ - FB6723722C134958008D5516 /* ATTNSDKFramework */ = { + FB080C762C1CAF5C00834BAA /* ATTNSDKFramework */ = { isa = XCSwiftPackageProductDependency; - package = FB6723712C134958008D5516 /* XCRemoteSwiftPackageReference "attentive-ios-sdk" */; + package = FB080C752C1CAF5B00834BAA /* XCRemoteSwiftPackageReference "attentive-ios-sdk" */; productName = ATTNSDKFramework; }; /* End XCSwiftPackageProductDependency section */ diff --git a/ExampleSwift/ExampleSwift/AppDelegate.swift b/ExampleSwift/ExampleSwift/AppDelegate.swift index 1a5566a..1e62293 100644 --- a/ExampleSwift/ExampleSwift/AppDelegate.swift +++ b/ExampleSwift/ExampleSwift/AppDelegate.swift @@ -39,12 +39,12 @@ class AppDelegate : UIResponder, UIApplicationDelegate { public static func createUserIdentifiers() -> [String: Any] { [ - IDENTIFIER_TYPE_PHONE: "+15671230987", - IDENTIFIER_TYPE_EMAIL: "someemail@email.com", - IDENTIFIER_TYPE_CLIENT_USER_ID: "APP_USER_ID", - IDENTIFIER_TYPE_SHOPIFY_ID: "207119551", - IDENTIFIER_TYPE_KLAVIYO_ID: "555555", - IDENTIFIER_TYPE_CUSTOM_IDENTIFIERS: ["customId": "customIdValue"] + ATTNIdentifierType.phone: "+15671230987", + ATTNIdentifierType.email: "someemail@email.com", + ATTNIdentifierType.clientUserId: "APP_USER_ID", + ATTNIdentifierType.shopifyId: "207119551", + ATTNIdentifierType.klaviyoId: "555555", + ATTNIdentifierType.customIdentifiers: ["customId": "customIdValue"] ] } } diff --git a/ExampleSwift/ExampleSwift/ProductViewController.swift b/ExampleSwift/ExampleSwift/ProductViewController.swift index 61f1780..7762bf2 100644 --- a/ExampleSwift/ExampleSwift/ProductViewController.swift +++ b/ExampleSwift/ExampleSwift/ProductViewController.swift @@ -20,15 +20,15 @@ class ProductViewController : UIViewController { let item : ATTNItem = buildItem() let productView : ATTNProductViewEvent = ATTNProductViewEvent(items: [item]) - ATTNEventTracker.sharedInstance()?.record(productView) - + ATTNEventTracker.sharedInstance()?.record(event: productView) + showToast(message: "Product View event sent") } @IBAction func addToCartBtnPressed(sender: Any) { let item : ATTNItem = self.buildItem() let addToCart : ATTNAddToCartEvent = ATTNAddToCartEvent(items: [item]) - ATTNEventTracker.sharedInstance()?.record(addToCart) + ATTNEventTracker.sharedInstance()?.record(event: addToCart) showToast(message: "Add To Cart event sent") } @@ -41,14 +41,14 @@ class ProductViewController : UIViewController { // Create PurchaseEvent let purchase : ATTNPurchaseEvent = ATTNPurchaseEvent(items: [item], order: order) // Send the PurchaseEvent - ATTNEventTracker.sharedInstance()?.record(purchase) + ATTNEventTracker.sharedInstance()?.record(event: purchase) showToast(message: "Purchase event sent") } @IBAction func customEventBtnPressed(sender: Any) { guard let customEvent = ATTNCustomEvent(type: "Added to Wishlist", properties: ["wishlistName": "Gift Ideas"]) else { return } - ATTNEventTracker.sharedInstance()?.record(customEvent) + ATTNEventTracker.sharedInstance()?.record(event: customEvent) showToast(message: "Custom event sent") } diff --git a/attentive-ios-sdk.xcworkspace/xcshareddata/swiftpm/Package.resolved b/attentive-ios-sdk.xcworkspace/xcshareddata/swiftpm/Package.resolved index 62609f3..40aed93 100644 --- a/attentive-ios-sdk.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/attentive-ios-sdk.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -1,13 +1,13 @@ { - "originHash" : "6b3de92165125b4410ec54f34acb3ca6e0b8fc849f4bd109516c1eddb59f6bf0", + "originHash" : "62dc5f9606142e259275d938027b59c944959560f934dd2210d0e0cc4420a08d", "pins" : [ { "identity" : "attentive-ios-sdk", "kind" : "remoteSourceControl", - "location" : "https://github.com/vespinola/attentive-ios-sdk.git", + "location" : "https://github.com/attentive-mobile/attentive-ios-sdk", "state" : { - "branch" : "main", - "revision" : "46691f276e02add53c6f6a0af5cd1c13c04c9497" + "revision" : "16ea6c5924b6431d996f38d057b9a55e6639ed03", + "version" : "0.6.0" } } ], From 82a56d04eeddcf26096ca889c9cf006ae28223a9 Mon Sep 17 00:00:00 2001 From: Vladimir Espinola Date: Fri, 14 Jun 2024 13:17:37 -0400 Subject: [PATCH 7/7] fixed dependency on ExampleSwift --- .../ExampleSwift.xcodeproj/project.pbxproj | 18 +++++++++--------- .../xcshareddata/swiftpm/Package.resolved | 4 ++-- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/ExampleSwift/ExampleSwift.xcodeproj/project.pbxproj b/ExampleSwift/ExampleSwift.xcodeproj/project.pbxproj index 0c5cd1c..992980c 100644 --- a/ExampleSwift/ExampleSwift.xcodeproj/project.pbxproj +++ b/ExampleSwift/ExampleSwift.xcodeproj/project.pbxproj @@ -21,7 +21,7 @@ 588EB7242995BC3A00C0163A /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 588EB7182995BBB700C0163A /* LaunchScreen.storyboard */; }; 588EB7252995BC3A00C0163A /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 587DC5C3299554B00082F8D0 /* Assets.xcassets */; }; 588EB7262995BC3A00C0163A /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 587DC5C82995551A0082F8D0 /* Main.storyboard */; }; - FB080C772C1CAF5C00834BAA /* ATTNSDKFramework in Frameworks */ = {isa = PBXBuildFile; productRef = FB080C762C1CAF5C00834BAA /* ATTNSDKFramework */; }; + FB080C7A2C1CB28500834BAA /* ATTNSDKFramework in Frameworks */ = {isa = PBXBuildFile; productRef = FB080C792C1CB28500834BAA /* ATTNSDKFramework */; }; FB2F35B62C18D6950016CAE8 /* ATTNSDKFramework.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FB2F35B52C18D6950016CAE8 /* ATTNSDKFramework.framework */; }; FB2F35B72C18D6950016CAE8 /* ATTNSDKFramework.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = FB2F35B52C18D6950016CAE8 /* ATTNSDKFramework.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; /* End PBXBuildFile section */ @@ -68,7 +68,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - FB080C772C1CAF5C00834BAA /* ATTNSDKFramework in Frameworks */, + FB080C7A2C1CB28500834BAA /* ATTNSDKFramework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -169,7 +169,7 @@ ); name = "ExampleSwift - SPM"; packageProductDependencies = ( - FB080C762C1CAF5C00834BAA /* ATTNSDKFramework */, + FB080C792C1CB28500834BAA /* ATTNSDKFramework */, ); productName = ExampleSwift; productReference = 588EB72C2995BC3A00C0163A /* ExampleSwift - SPM.app */; @@ -200,7 +200,7 @@ ); mainGroup = 58389AA12987647900A31A35; packageReferences = ( - FB080C752C1CAF5B00834BAA /* XCRemoteSwiftPackageReference "attentive-ios-sdk" */, + FB080C782C1CB28500834BAA /* XCRemoteSwiftPackageReference "attentive-ios-sdk" */, ); productRefGroup = 58389AAB2987647900A31A35 /* Products */; projectDirPath = ""; @@ -600,20 +600,20 @@ /* End XCConfigurationList section */ /* Begin XCRemoteSwiftPackageReference section */ - FB080C752C1CAF5B00834BAA /* XCRemoteSwiftPackageReference "attentive-ios-sdk" */ = { + FB080C782C1CB28500834BAA /* XCRemoteSwiftPackageReference "attentive-ios-sdk" */ = { isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/attentive-mobile/attentive-ios-sdk"; requirement = { - kind = upToNextMajorVersion; - minimumVersion = 0.6.0; + branch = main; + kind = branch; }; }; /* End XCRemoteSwiftPackageReference section */ /* Begin XCSwiftPackageProductDependency section */ - FB080C762C1CAF5C00834BAA /* ATTNSDKFramework */ = { + FB080C792C1CB28500834BAA /* ATTNSDKFramework */ = { isa = XCSwiftPackageProductDependency; - package = FB080C752C1CAF5B00834BAA /* XCRemoteSwiftPackageReference "attentive-ios-sdk" */; + package = FB080C782C1CB28500834BAA /* XCRemoteSwiftPackageReference "attentive-ios-sdk" */; productName = ATTNSDKFramework; }; /* End XCSwiftPackageProductDependency section */ diff --git a/attentive-ios-sdk.xcworkspace/xcshareddata/swiftpm/Package.resolved b/attentive-ios-sdk.xcworkspace/xcshareddata/swiftpm/Package.resolved index 40aed93..893c9fc 100644 --- a/attentive-ios-sdk.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/attentive-ios-sdk.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -6,8 +6,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/attentive-mobile/attentive-ios-sdk", "state" : { - "revision" : "16ea6c5924b6431d996f38d057b9a55e6639ed03", - "version" : "0.6.0" + "branch" : "main", + "revision" : "16ea6c5924b6431d996f38d057b9a55e6639ed03" } } ],