From 7d414ff9dee0e7bedb2572466ef7e1e366c181ad Mon Sep 17 00:00:00 2001 From: Adam Szeremeta Date: Fri, 6 Mar 2026 08:22:23 +0100 Subject: [PATCH 1/2] Implemented deboosting event for Aureus --- .gitignore | 1 + .../project.pbxproj | 4 ++ .../Private/EventsFactory.swift | 19 ++++++- .../Private/Tracking/EventType.swift | 1 + .../Aureus/AureusDeboostingStrategy.swift | 18 ++++++ .../RingPublishingTracking+Aureus.swift | 12 ++++ .../AureusTests.swift | 55 +++++++++++++++++++ 7 files changed, 109 insertions(+), 1 deletion(-) create mode 100644 Sources/RingPublishingTracking/Public/Model/Aureus/AureusDeboostingStrategy.swift diff --git a/.gitignore b/.gitignore index 2ecdcbf..3c05a9a 100644 --- a/.gitignore +++ b/.gitignore @@ -33,6 +33,7 @@ Example/Pods ## SPM .swiftpm +.build fastlane/* !fastlane/.env diff --git a/Example/RingPublishingTracking.xcodeproj/project.pbxproj b/Example/RingPublishingTracking.xcodeproj/project.pbxproj index eacab72..77c5256 100644 --- a/Example/RingPublishingTracking.xcodeproj/project.pbxproj +++ b/Example/RingPublishingTracking.xcodeproj/project.pbxproj @@ -157,6 +157,7 @@ 7D7D5B9426FCA3DF00B79FDD /* ActionsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7D7D5B8726FCA3DF00B79FDD /* ActionsViewController.swift */; }; 7D7D5B9526FCA3DF00B79FDD /* PagerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7D7D5B8926FCA3DF00B79FDD /* PagerViewController.swift */; }; 7D7D5B9626FCA3DF00B79FDD /* TraceableScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7D7D5B8A26FCA3DF00B79FDD /* TraceableScreen.swift */; }; + 7DDC7E362F5AB4D6000F254C /* AureusDeboostingStrategy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7DDC7E352F5AB4D6000F254C /* AureusDeboostingStrategy.swift */; }; 7DE4453B26E8913900A93431 /* LoggerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7DE4453A26E8913900A93431 /* LoggerTests.swift */; }; 854F1289D6E3FA4BC790018B /* Pods_RingPublishingTracking_Example.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BF2945259492AA544792B04F /* Pods_RingPublishingTracking_Example.framework */; }; A039F65F2DF2D84400B9BD67 /* EffectivePageViewMetadata.swift in Sources */ = {isa = PBXBuildFile; fileRef = A039F65E2DF2D84400B9BD67 /* EffectivePageViewMetadata.swift */; }; @@ -361,6 +362,7 @@ 7D9F12B82791A15D00F3635A /* RingPublishingTracking.podspec */ = {isa = PBXFileReference; lastKnownFileType = text; name = RingPublishingTracking.podspec; path = ../RingPublishingTracking.podspec; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; 7D9F12B92791A15D00F3635A /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../README.md; sourceTree = ""; }; 7D9F12BA2791A15D00F3635A /* Changelogs */ = {isa = PBXFileReference; lastKnownFileType = folder; name = Changelogs; path = ../Changelogs; sourceTree = ""; }; + 7DDC7E352F5AB4D6000F254C /* AureusDeboostingStrategy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AureusDeboostingStrategy.swift; sourceTree = ""; }; 7DE4453A26E8913900A93431 /* LoggerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoggerTests.swift; sourceTree = ""; }; 8E2A37C5A1593C87B0EB5A44 /* Pods-RingPublishingTrackingTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RingPublishingTrackingTests.release.xcconfig"; path = "Target Support Files/Pods-RingPublishingTrackingTests/Pods-RingPublishingTrackingTests.release.xcconfig"; sourceTree = ""; }; A039F65E2DF2D84400B9BD67 /* EffectivePageViewMetadata.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EffectivePageViewMetadata.swift; sourceTree = ""; }; @@ -845,6 +847,7 @@ 7D54DA972E460B99009DA251 /* Aureus */ = { isa = PBXGroup; children = ( + 7DDC7E352F5AB4D6000F254C /* AureusDeboostingStrategy.swift */, 7D54DA982E460BF8009DA251 /* AureusTeaser.swift */, 7D54DA9A2E460C55009DA251 /* AureusEventContext.swift */, ); @@ -1299,6 +1302,7 @@ A04E94DD2CB7E6E10048B4AF /* AudioEventsTests.swift in Sources */, 60108E8D2B0515C6005656C1 /* ConsentProvider.swift in Sources */, 60108E702B0515C6005656C1 /* VideoStartMode.swift in Sources */, + 7DDC7E362F5AB4D6000F254C /* AureusDeboostingStrategy.swift in Sources */, 60108EBF2B0515C6005656C1 /* VideoAdsConfiguration+ParameterName.swift in Sources */, 204EAF3627294BF7009E2F0D /* EventTests.swift in Sources */, 60108ECA2B0515C6005656C1 /* KeepAliveIntervalsProvider.swift in Sources */, diff --git a/Sources/RingPublishingTracking/Private/EventsFactory.swift b/Sources/RingPublishingTracking/Private/EventsFactory.swift index 0ee3415..652347b 100644 --- a/Sources/RingPublishingTracking/Private/EventsFactory.swift +++ b/Sources/RingPublishingTracking/Private/EventsFactory.swift @@ -173,7 +173,7 @@ final class EventsFactory { eventParameters: parameters) } - // MARK: Aureus Impression event + // MARK: Aureus events func createAureusImpressionEvent(for teasers: [AureusTeaser], eventContext: AureusEventContext) -> Event { let eventDictionary: [String: AnyHashable] = [ @@ -192,6 +192,23 @@ final class EventsFactory { eventParameters: parameters) } + func createAureusDeboostingEvent(for teasers: [AureusTeaser], strategy: AureusDeboostingStrategy) -> Event { + let eventDictionary: [String: AnyHashable] = [ + "type": "deboosting", + "strategy": strategy.rawValue, + "items": teasers.asJsonArray + ] + + let parameters: [String: AnyHashable] = [ + "version": "1.0.0", + "events": [eventDictionary] + ] + + return Event(analyticsSystemName: AnalyticsSystem.generic.rawValue, + eventName: EventType.aureusEvent.rawValue, + eventParameters: parameters) + } + // MARK: Error func createErrorEvent(for event: Event, applicationRootPath: String?) -> Event { diff --git a/Sources/RingPublishingTracking/Private/Tracking/EventType.swift b/Sources/RingPublishingTracking/Private/Tracking/EventType.swift index 9801951..bcd726c 100644 --- a/Sources/RingPublishingTracking/Private/Tracking/EventType.swift +++ b/Sources/RingPublishingTracking/Private/Tracking/EventType.swift @@ -17,6 +17,7 @@ enum EventType: String { case videoEvent = "VidEvent" case paid = "PaidEvent" case effectivePageView = "PolarisEvent" + case aureusEvent = "AureusEvent" case aureusImpressionEvent = "AureusImpressionEvent" case error = "ErrEvent" } diff --git a/Sources/RingPublishingTracking/Public/Model/Aureus/AureusDeboostingStrategy.swift b/Sources/RingPublishingTracking/Public/Model/Aureus/AureusDeboostingStrategy.swift new file mode 100644 index 0000000..9f19fa2 --- /dev/null +++ b/Sources/RingPublishingTracking/Public/Model/Aureus/AureusDeboostingStrategy.swift @@ -0,0 +1,18 @@ +// +// AureusDeboostingStrategy.swift +// RingPublishingTracking +// +// Created by Adam Szeremeta on 05/03/2026. +// + +import Foundation + +/// Aureus deboosting strategy +public enum AureusDeboostingStrategy: String { + + /// User was engaged with content + case click + + /// User saw content multiple times but never interacted with it + case view +} diff --git a/Sources/RingPublishingTracking/Public/RingPublishingTracking+Aureus.swift b/Sources/RingPublishingTracking/Public/RingPublishingTracking+Aureus.swift index 3094b5b..ecd3a06 100644 --- a/Sources/RingPublishingTracking/Public/RingPublishingTracking+Aureus.swift +++ b/Sources/RingPublishingTracking/Public/RingPublishingTracking+Aureus.swift @@ -54,6 +54,18 @@ public extension RingPublishingTracking { teaser: teaser, eventContext: eventContext) } + + /// Report 'Aureus' deboosting event + /// + /// - Parameters: + /// - teasers: [AureusTeaser] + /// - strategy: AureusDeboostingStrategy + func reportAureusDeboostingEvent(for teasers: [AureusTeaser], strategy: AureusDeboostingStrategy) { + Logger.log("Reporting 'Aureus' deboosting event for teasers: '\(teasers)'") + + let event = eventsFactory.createAureusDeboostingEvent(for: teasers, strategy: strategy) + reportEvents([event]) + } } // MARK: Private diff --git a/Tests/RingPublishingTrackingTests/AureusTests.swift b/Tests/RingPublishingTrackingTests/AureusTests.swift index d90db67..38138b5 100644 --- a/Tests/RingPublishingTrackingTests/AureusTests.swift +++ b/Tests/RingPublishingTrackingTests/AureusTests.swift @@ -34,6 +34,7 @@ class AureusTests: XCTestCase { } // MARK: Tests + func testReportAureusOffersImpressions_offerIdsProvided_properlyReportedEvent() { // Given let expectation = XCTestExpectation(description: "Report Aureus Offers Impressions") @@ -135,4 +136,58 @@ class AureusTests: XCTestCase { wait(for: [expectation], timeout: 10.0) } + + func testReportAureusDeboostingEvent_offerIdsProvided_properlyReportedEvent() { + // Given + let expectation = XCTestExpectation(description: "Report Aureus Deboosting Event") + + let teaser = AureusTeaser(teaserId: "teaserId", offerId: "a1", contentId: "contentId") + let teaser2 = AureusTeaser(teaserId: "teaserId_2", offerId: "b2", contentId: "contentId_2") + let teaser3 = AureusTeaser(teaserId: "teaserId_3", offerId: "c3", contentId: "contentId_3") + let teaser4 = AureusTeaser(teaserId: "teaserId_3", offerId: "d4", contentId: "contentId_4") + + // When + RingPublishingTracking.shared.reportAureusDeboostingEvent(for: [teaser, teaser2, teaser3, teaser4], strategy: .click) + + // Then + DispatchQueue.main.asyncAfter(deadline: .now() + 3, execute: { + let request = self.ringPublishingTracking.eventsService?.buildEventRequest() + let event = request?.events.first + let params = event?.eventParameters + + XCTAssertEqual(params?["version"] as? String, "1.0.0", "version parameter should be correct") + + guard let events = params?["events"] as? [[String: AnyHashable]] else { + XCTFail("events parameter should be an array of dictionaries") + expectation.fulfill() + return + } + + XCTAssertEqual(events.count, 1, "events should contain one event") + + let eventDict = events[0] + XCTAssertEqual(eventDict["type"] as? String, "deboosting", "type should be deboosting") + XCTAssertEqual(eventDict["strategy"] as? String, "click", "strategy should be click") + + guard let items = eventDict["items"] as? [[String: AnyHashable]] else { + XCTFail("items should be an array of dictionaries") + expectation.fulfill() + return + } + + XCTAssertEqual(items.count, 4, "items should contain 4 teasers") + XCTAssertEqual(items[0]["content_id"] as? String, "contentId") + XCTAssertEqual(items[0]["teaser_id"] as? String, "teaserId") + XCTAssertEqual(items[1]["content_id"] as? String, "contentId_2") + XCTAssertEqual(items[1]["teaser_id"] as? String, "teaserId_2") + XCTAssertEqual(items[2]["content_id"] as? String, "contentId_3") + XCTAssertEqual(items[2]["teaser_id"] as? String, "teaserId_3") + XCTAssertEqual(items[3]["content_id"] as? String, "contentId_4") + XCTAssertEqual(items[3]["teaser_id"] as? String, "teaserId_3") + + expectation.fulfill() + }) + + wait(for: [expectation], timeout: 10.0) + } } From 8d32056db0f207852fc885785a11be2c9f2708e0 Mon Sep 17 00:00:00 2001 From: Adam Szeremeta Date: Fri, 6 Mar 2026 08:58:23 +0100 Subject: [PATCH 2/2] Changelog + demo --- Changelogs/1.12.0 | 8 +++++ .../project.pbxproj | 4 +-- .../Controller/ActionsViewController.swift | 11 ++++++- Example/RingPublishingTracking/Info.plist | 2 +- .../Resources/Base.lproj/Main.storyboard | 33 +++++++++++++------ RingPublishingTracking.podspec | 2 +- 6 files changed, 45 insertions(+), 15 deletions(-) create mode 100644 Changelogs/1.12.0 diff --git a/Changelogs/1.12.0 b/Changelogs/1.12.0 new file mode 100644 index 0000000..871fa75 --- /dev/null +++ b/Changelogs/1.12.0 @@ -0,0 +1,8 @@ +1.12.0 Release notes (2026-03-09) +================================ + +Improvements to the 'RingPublishingTracking' module. + +### Changes + +* Added new public method to report Aureus deboosting event diff --git a/Example/RingPublishingTracking.xcodeproj/project.pbxproj b/Example/RingPublishingTracking.xcodeproj/project.pbxproj index 77c5256..285ee13 100644 --- a/Example/RingPublishingTracking.xcodeproj/project.pbxproj +++ b/Example/RingPublishingTracking.xcodeproj/project.pbxproj @@ -1475,7 +1475,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.11.2; + MARKETING_VERSION = 1.12.0; PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.RingPublishingTracking-Example.RingPublishingTracking"; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -1499,7 +1499,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 1.11.2; + MARKETING_VERSION = 1.12.0; PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.RingPublishingTracking-Example.RingPublishingTracking"; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; diff --git a/Example/RingPublishingTracking/Controller/ActionsViewController.swift b/Example/RingPublishingTracking/Controller/ActionsViewController.swift index b20603d..7b68877 100644 --- a/Example/RingPublishingTracking/Controller/ActionsViewController.swift +++ b/Example/RingPublishingTracking/Controller/ActionsViewController.swift @@ -174,7 +174,7 @@ class ActionsViewController: UIViewController, PagerViewController, TraceableScr RingPublishingTracking.shared.setOptOutMode(enabled: false) } - // MARK: Actions (Aureus offers impression) + // MARK: Actions (Aureus) @IBAction func onReportAureusOffersImpressionActionTouch(_ sender: Any) { // If you have recomendations delivered by personalization engine (Aureus) you should report @@ -199,6 +199,15 @@ class ActionsViewController: UIViewController, PagerViewController, TraceableScr RingPublishingTracking.shared.reportAureusImpression(for: [teaser, teaser2, teaser3], eventContext: contextNew) } + @IBAction func onReportAureusDeboostingActionTouch(_ sender: Any) { + let teaser = AureusTeaser(teaserId: "teaserId", offerId: "offerId", contentId: "contentId") + let teaser2 = AureusTeaser(teaserId: "teaserId_2", offerId: "offerId_2", contentId: "contentId_2") + let teaser3 = AureusTeaser(teaserId: "teaserId_3", offerId: "offerId_3", contentId: "contentId_3") + + RingPublishingTracking.shared.reportAureusDeboostingEvent(for: [teaser, teaser2, teaser3], strategy: .click) + RingPublishingTracking.shared.reportAureusDeboostingEvent(for: [teaser, teaser2, teaser3], strategy: .view) + } + // MARK: Actions (Video event) @IBAction func onReportVideoPlaybackStartActionTouch(_ sender: Any) { diff --git a/Example/RingPublishingTracking/Info.plist b/Example/RingPublishingTracking/Info.plist index 711fda1..dfe9f69 100644 --- a/Example/RingPublishingTracking/Info.plist +++ b/Example/RingPublishingTracking/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType $(PRODUCT_BUNDLE_PACKAGE_TYPE) CFBundleShortVersionString - 1.10.0 + 1.12.0 CFBundleVersion 1 LSRequiresIPhoneOS diff --git a/Example/RingPublishingTracking/Resources/Base.lproj/Main.storyboard b/Example/RingPublishingTracking/Resources/Base.lproj/Main.storyboard index 9a6fb72..511c137 100644 --- a/Example/RingPublishingTracking/Resources/Base.lproj/Main.storyboard +++ b/Example/RingPublishingTracking/Resources/Base.lproj/Main.storyboard @@ -1,9 +1,9 @@ - + - + @@ -28,7 +28,7 @@ - + @@ -161,8 +161,21 @@ + + + + + + - +