From b42ce0852794e3c24966c899c1db94200783ceb2 Mon Sep 17 00:00:00 2001 From: Salim Braksa Date: Sat, 11 Nov 2023 15:26:55 +0100 Subject: [PATCH 1/3] Custom analyticsSource for the checkout web view when presented from the All Domains flow --- .../RegisterDomainCoordinator.swift | 15 +++++++++++++-- .../AllDomainsAddDomainCoordinator.swift | 2 +- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/WordPress/Classes/ViewRelated/Domains/Domain registration/RegisterDomainSuggestions/RegisterDomainCoordinator.swift b/WordPress/Classes/ViewRelated/Domains/Domain registration/RegisterDomainSuggestions/RegisterDomainCoordinator.swift index e282e2ab91c8..3835e69870cf 100644 --- a/WordPress/Classes/ViewRelated/Domains/Domain registration/RegisterDomainSuggestions/RegisterDomainCoordinator.swift +++ b/WordPress/Classes/ViewRelated/Domains/Domain registration/RegisterDomainSuggestions/RegisterDomainCoordinator.swift @@ -15,6 +15,7 @@ class RegisterDomainCoordinator { // MARK: Variables private let crashLogger: CrashLogging + private let analyticsSource: String? var site: Blog? var domainPurchasedCallback: DomainPurchasedCallback? @@ -23,12 +24,21 @@ class RegisterDomainCoordinator { private var webViewURLChangeObservation: NSKeyValueObservation? + /// Initializes a `RegisterDomainCoordinator` with the specified parameters. + /// + /// - Parameters: + /// - site: An optional `Blog` object representing the blog associated with the domain registration. + /// - domainPurchasedCallback: An optional closure to be called when a domain is successfully purchased. + /// - analyticsSource: A string representing the source for analytics tracking. Defaults to `domains_register` if not provided. + /// - crashLogger: An instance of `CrashLogging` to handle crash logging. Defaults to `.main` if not provided. init(site: Blog?, domainPurchasedCallback: RegisterDomainCoordinator.DomainPurchasedCallback? = nil, + analyticsSource: String? = "domains_register", crashLogger: CrashLogging = .main) { self.site = site self.domainPurchasedCallback = domainPurchasedCallback self.crashLogger = crashLogger + self.analyticsSource = analyticsSource } // MARK: Public Functions @@ -153,8 +163,9 @@ class RegisterDomainCoordinator { let webViewController = WebViewControllerFactory.controllerWithDefaultAccountAndSecureInteraction( url: url, - source: "domains_register", // TODO: Update source - title: title) + source: analyticsSource ?? "", + title: title + ) let navController = LightNavigationController(rootViewController: webViewController) // WORKAROUND: The reason why we have to use this mechanism to detect success and failure conditions diff --git a/WordPress/Classes/ViewRelated/Me/All Domains/Coordinators/AllDomainsAddDomainCoordinator.swift b/WordPress/Classes/ViewRelated/Me/All Domains/Coordinators/AllDomainsAddDomainCoordinator.swift index b108e3a5336e..baec4e08281a 100644 --- a/WordPress/Classes/ViewRelated/Me/All Domains/Coordinators/AllDomainsAddDomainCoordinator.swift +++ b/WordPress/Classes/ViewRelated/Me/All Domains/Coordinators/AllDomainsAddDomainCoordinator.swift @@ -2,7 +2,7 @@ import Foundation @objc final class AllDomainsAddDomainCoordinator: NSObject { static func presentAddDomainFlow(in allDomainsViewController: AllDomainsListViewController) { - let coordinator = RegisterDomainCoordinator(site: nil) + let coordinator = RegisterDomainCoordinator(site: nil, analyticsSource: "all_domains") let domainSuggestionsViewController = RegisterDomainSuggestionsViewController.instance( coordinator: coordinator, domainSelectionType: .purchaseFromDomainManagement, From 1ad6c6299948cca4fa1c53ef5b1f0fe3cb3ea4d1 Mon Sep 17 00:00:00 2001 From: Salim Braksa Date: Sat, 11 Nov 2023 16:36:39 +0100 Subject: [PATCH 2/3] Update analyticsSource when presenting the Plans web view from the All DOmains flow --- .../Free to Paid Plans/FreeToPaidPlansCoordinator.swift | 7 ++++++- .../Domain registration/PlanSelectionViewController.swift | 3 ++- .../Coordinators/AllDomainsAddDomainCoordinator.swift | 7 +++++-- .../All Domains/Views/AllDomainsListViewController.swift | 4 ++++ 4 files changed, 17 insertions(+), 4 deletions(-) diff --git a/WordPress/Classes/ViewRelated/Blog/Blog Dashboard/Cards/Free to Paid Plans/FreeToPaidPlansCoordinator.swift b/WordPress/Classes/ViewRelated/Blog/Blog Dashboard/Cards/Free to Paid Plans/FreeToPaidPlansCoordinator.swift index 40bf050dfafb..a4fa0c9fc7cb 100644 --- a/WordPress/Classes/ViewRelated/Blog/Blog Dashboard/Cards/Free to Paid Plans/FreeToPaidPlansCoordinator.swift +++ b/WordPress/Classes/ViewRelated/Blog/Blog Dashboard/Cards/Free to Paid Plans/FreeToPaidPlansCoordinator.swift @@ -46,6 +46,7 @@ import SwiftUI /// - customTitle: Title of of the presented view. If nil the title displays the title of the webview.. /// - purchaseCallback: closure to be called when user completes a plan purchase. static func plansFlowAfterDomainAddedToCartBlock(customTitle: String?, + analyticsSource: String? = nil, purchaseCallback: @escaping PurchaseCallback) -> RegisterDomainCoordinator.DomainAddedToCartCallback { let planSelected = { (planSelectionViewController: PlanSelectionViewController, domainName: String, checkoutURL: URL) in let viewModel = CheckoutViewModel(url: checkoutURL) @@ -59,7 +60,11 @@ import SwiftUI let domainAddedToCart = { (domainViewController: UIViewController, domainName: String, blog: Blog) in guard let viewModel = PlanSelectionViewModel(blog: blog) else { return } - let planSelectionViewController = PlanSelectionViewController(viewModel: viewModel, customTitle: customTitle) + let planSelectionViewController = PlanSelectionViewController( + viewModel: viewModel, + customTitle: customTitle, + analyticsSource: analyticsSource + ) planSelectionViewController.planSelectedCallback = { planSelectionViewController, checkoutURL in planSelected(planSelectionViewController, domainName, checkoutURL) } diff --git a/WordPress/Classes/ViewRelated/Domains/Domain registration/PlanSelectionViewController.swift b/WordPress/Classes/ViewRelated/Domains/Domain registration/PlanSelectionViewController.swift index 2d023d8e94a9..83c27ac2241c 100644 --- a/WordPress/Classes/ViewRelated/Domains/Domain registration/PlanSelectionViewController.swift +++ b/WordPress/Classes/ViewRelated/Domains/Domain registration/PlanSelectionViewController.swift @@ -44,13 +44,14 @@ final class PlanSelectionViewController: WebKitViewController { private var webViewURLChangeObservation: NSKeyValueObservation? - init(viewModel: PlanSelectionViewModel, customTitle: String?) { + init(viewModel: PlanSelectionViewModel, customTitle: String?, analyticsSource: String? = nil) { self.viewModel = viewModel let configuration = WebViewControllerConfiguration(url: viewModel.url) configuration.authenticateWithDefaultAccount() configuration.secureInteraction = true configuration.customTitle = customTitle + configuration.analyticsSource = analyticsSource ?? "" super.init(configuration: configuration) } diff --git a/WordPress/Classes/ViewRelated/Me/All Domains/Coordinators/AllDomainsAddDomainCoordinator.swift b/WordPress/Classes/ViewRelated/Me/All Domains/Coordinators/AllDomainsAddDomainCoordinator.swift index baec4e08281a..0a478f438503 100644 --- a/WordPress/Classes/ViewRelated/Me/All Domains/Coordinators/AllDomainsAddDomainCoordinator.swift +++ b/WordPress/Classes/ViewRelated/Me/All Domains/Coordinators/AllDomainsAddDomainCoordinator.swift @@ -2,7 +2,8 @@ import Foundation @objc final class AllDomainsAddDomainCoordinator: NSObject { static func presentAddDomainFlow(in allDomainsViewController: AllDomainsListViewController) { - let coordinator = RegisterDomainCoordinator(site: nil, analyticsSource: "all_domains") + let analyticsSource = AllDomainsListViewController.Constants.analyticsSource + let coordinator = RegisterDomainCoordinator(site: nil, analyticsSource: analyticsSource) let domainSuggestionsViewController = RegisterDomainSuggestionsViewController.instance( coordinator: coordinator, domainSelectionType: .purchaseFromDomainManagement, @@ -18,7 +19,9 @@ import Foundation let domainAddedToCart = FreeToPaidPlansCoordinator.plansFlowAfterDomainAddedToCartBlock( customTitle: RegisterDomainCoordinator.TextContent.checkoutTitle, - purchaseCallback: domainPurchasedCallback) + analyticsSource: analyticsSource, + purchaseCallback: domainPurchasedCallback + ) coordinator.domainPurchasedCallback = domainPurchasedCallback // For no site flow (domain only) coordinator.domainAddedToCartAndLinkedToSiteCallback = domainAddedToCart // For existing site flow (plans) diff --git a/WordPress/Classes/ViewRelated/Me/All Domains/Views/AllDomainsListViewController.swift b/WordPress/Classes/ViewRelated/Me/All Domains/Views/AllDomainsListViewController.swift index 06b2b93b595c..db96cfafe248 100644 --- a/WordPress/Classes/ViewRelated/Me/All Domains/Views/AllDomainsListViewController.swift +++ b/WordPress/Classes/ViewRelated/Me/All Domains/Views/AllDomainsListViewController.swift @@ -6,6 +6,10 @@ final class AllDomainsListViewController: UIViewController { // MARK: - Types + enum Constants { + static let analyticsSource = "all_domains" + } + private enum Layout { static let interRowSpacing = Length.Padding.double } From cc4be24c2786950bcc3343704dfc4fddfd8bd6a4 Mon Sep 17 00:00:00 2001 From: Salim Braksa Date: Mon, 13 Nov 2023 21:35:53 +0100 Subject: [PATCH 3/3] Track analytics event when No-Site checkout web view is viewed --- .../Analytics/WPAnalytics+Domains.swift | 27 ++++++++++++++----- .../RegisterDomainCoordinator.swift | 6 +++-- 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/WordPress/Classes/Utility/Analytics/WPAnalytics+Domains.swift b/WordPress/Classes/Utility/Analytics/WPAnalytics+Domains.swift index c55260d4f62c..05b0d18da3b0 100644 --- a/WordPress/Classes/Utility/Analytics/WPAnalytics+Domains.swift +++ b/WordPress/Classes/Utility/Analytics/WPAnalytics+Domains.swift @@ -2,24 +2,39 @@ import Foundation extension WPAnalytics { - /// Checks if the Domain Purchasing Feature Flag and AB Experiment are enabled + /// Checks if the Domain Purchasing Feature Flag is enabled. private static var domainPurchasingEnabled: Bool { RemoteFeatureFlag.plansInSiteCreation.enabled() } - static func domainsProperties(for blog: Blog, origin: SiteCreationWebViewViewOrigin? = .menu) -> [AnyHashable: Any] { - domainsProperties(usingCredit: blog.canRegisterDomainWithPaidPlan, origin: origin) + /// Checks if the Domain Management Feature Flag is enabled. + private static var domainManagementEnabled: Bool { + return RemoteFeatureFlag.domainManagement.enabled() + } + + static func domainsProperties( + for blog: Blog, + origin: SiteCreationWebViewViewOrigin? = .menu + ) -> [AnyHashable: Any] { + domainsProperties( + usingCredit: blog.canRegisterDomainWithPaidPlan, + origin: origin, + domainOnly: false + ) } static func domainsProperties( usingCredit: Bool, - origin: SiteCreationWebViewViewOrigin? + origin: SiteCreationWebViewViewOrigin? = nil, + domainOnly: Bool = false ) -> [AnyHashable: Any] { var dict: [AnyHashable: Any] = ["using_credit": usingCredit.stringLiteral] - if Self.domainPurchasingEnabled, - let origin = origin { + if Self.domainPurchasingEnabled, let origin = origin { dict["origin"] = origin.rawValue } + if Self.domainManagementEnabled { + dict["domain_only"] = domainOnly.stringLiteral + } return dict } } diff --git a/WordPress/Classes/ViewRelated/Domains/Domain registration/RegisterDomainSuggestions/RegisterDomainCoordinator.swift b/WordPress/Classes/ViewRelated/Domains/Domain registration/RegisterDomainSuggestions/RegisterDomainCoordinator.swift index 3835e69870cf..a5fdd3688e60 100644 --- a/WordPress/Classes/ViewRelated/Domains/Domain registration/RegisterDomainSuggestions/RegisterDomainCoordinator.swift +++ b/WordPress/Classes/ViewRelated/Domains/Domain registration/RegisterDomainSuggestions/RegisterDomainCoordinator.swift @@ -192,9 +192,11 @@ class RegisterDomainCoordinator { } if let site { - WPAnalytics.track(.domainsPurchaseWebviewViewed, properties: WPAnalytics.domainsProperties(for: site), blog: site) + let properties = WPAnalytics.domainsProperties(for: site) + WPAnalytics.track(.domainsPurchaseWebviewViewed, properties: properties, blog: site) } else { - // TODO: Track showing no site checkout + let properties = WPAnalytics.domainsProperties(usingCredit: false, domainOnly: true) + WPAnalytics.track(.domainsPurchaseWebviewViewed, properties: properties) } webViewController.configureSandboxStore {