From 465ab0f603252ddb3f416fcd8561dcc6f170a04f Mon Sep 17 00:00:00 2001 From: Cesar de la Vega Date: Fri, 30 Aug 2024 14:09:41 +0200 Subject: [PATCH] Add `feedbackSurveyCompleted` event to Customer Center events (#4194) Sends a `feedbackSurveyCompleted` event when an option in the feedback survey is pressed --- .../Data/CustomerCenterAction.swift | 2 ++ .../ViewModels/FeedbackSurveyViewModel.swift | 15 +++++++++++--- .../Views/FeedbackSurveyView.swift | 6 ++++-- .../Views/ManageSubscriptionsView.swift | 20 +++++++++++++------ .../UI/Views/SamplePaywallsList.swift | 4 +++- 5 files changed, 35 insertions(+), 12 deletions(-) diff --git a/RevenueCatUI/CustomerCenter/Data/CustomerCenterAction.swift b/RevenueCatUI/CustomerCenter/Data/CustomerCenterAction.swift index 33dba7a0f6..a862549d52 100644 --- a/RevenueCatUI/CustomerCenter/Data/CustomerCenterAction.swift +++ b/RevenueCatUI/CustomerCenter/Data/CustomerCenterAction.swift @@ -20,6 +20,8 @@ public enum CustomerCenterAction { case refundRequestStarted(_ productId: String) /// Refund request process finished, with result provided. case refundRequestCompleted(_ refundRequestStatus: RefundRequestStatus) + /// An option of the feedback survey has been selected + case feedbackSurveyCompleted(_ feedbackSurveyOptionId: String) } diff --git a/RevenueCatUI/CustomerCenter/ViewModels/FeedbackSurveyViewModel.swift b/RevenueCatUI/CustomerCenter/ViewModels/FeedbackSurveyViewModel.swift index f811e91c56..28b6e12569 100644 --- a/RevenueCatUI/CustomerCenter/ViewModels/FeedbackSurveyViewModel.swift +++ b/RevenueCatUI/CustomerCenter/ViewModels/FeedbackSurveyViewModel.swift @@ -36,22 +36,31 @@ class FeedbackSurveyViewModel: ObservableObject { private var purchasesProvider: CustomerCenterPurchasesType private let loadPromotionalOfferUseCase: LoadPromotionalOfferUseCaseType + private let customerCenterActionHandler: CustomerCenterActionHandler? - convenience init(feedbackSurveyData: FeedbackSurveyData) { + convenience init(feedbackSurveyData: FeedbackSurveyData, + customerCenterActionHandler: CustomerCenterActionHandler?) { self.init(feedbackSurveyData: feedbackSurveyData, purchasesProvider: CustomerCenterPurchases(), - loadPromotionalOfferUseCase: LoadPromotionalOfferUseCase()) + loadPromotionalOfferUseCase: LoadPromotionalOfferUseCase(), + customerCenterActionHandler: customerCenterActionHandler) } init(feedbackSurveyData: FeedbackSurveyData, purchasesProvider: CustomerCenterPurchasesType, - loadPromotionalOfferUseCase: LoadPromotionalOfferUseCaseType) { + loadPromotionalOfferUseCase: LoadPromotionalOfferUseCaseType, + customerCenterActionHandler: CustomerCenterActionHandler?) { self.feedbackSurveyData = feedbackSurveyData self.purchasesProvider = purchasesProvider self.loadPromotionalOfferUseCase = loadPromotionalOfferUseCase + self.customerCenterActionHandler = customerCenterActionHandler } func handleAction(for option: CustomerCenterConfigData.HelpPath.FeedbackSurvey.Option) async { + if let customerCenterActionHandler = self.customerCenterActionHandler { + customerCenterActionHandler(.feedbackSurveyCompleted(option.id)) + } + if let promotionalOffer = option.promotionalOffer, promotionalOffer.eligible { self.loadingState = option.id diff --git a/RevenueCatUI/CustomerCenter/Views/FeedbackSurveyView.swift b/RevenueCatUI/CustomerCenter/Views/FeedbackSurveyView.swift index e40a5a2ab1..436d433bca 100644 --- a/RevenueCatUI/CustomerCenter/Views/FeedbackSurveyView.swift +++ b/RevenueCatUI/CustomerCenter/Views/FeedbackSurveyView.swift @@ -35,8 +35,10 @@ struct FeedbackSurveyView: View { @Environment(\.colorScheme) private var colorScheme - init(feedbackSurveyData: FeedbackSurveyData) { - let viewModel = FeedbackSurveyViewModel(feedbackSurveyData: feedbackSurveyData) + init(feedbackSurveyData: FeedbackSurveyData, + customerCenterActionHandler: CustomerCenterActionHandler?) { + let viewModel = FeedbackSurveyViewModel(feedbackSurveyData: feedbackSurveyData, + customerCenterActionHandler: customerCenterActionHandler) self._viewModel = StateObject(wrappedValue: viewModel) } diff --git a/RevenueCatUI/CustomerCenter/Views/ManageSubscriptionsView.swift b/RevenueCatUI/CustomerCenter/Views/ManageSubscriptionsView.swift index b908a344b5..99b01c6956 100644 --- a/RevenueCatUI/CustomerCenter/Views/ManageSubscriptionsView.swift +++ b/RevenueCatUI/CustomerCenter/Views/ManageSubscriptionsView.swift @@ -36,15 +36,19 @@ struct ManageSubscriptionsView: View { @StateObject private var viewModel: ManageSubscriptionsViewModel + private let customerCenterActionHandler: CustomerCenterActionHandler? + init(screen: CustomerCenterConfigData.Screen, customerCenterActionHandler: CustomerCenterActionHandler?) { let viewModel = ManageSubscriptionsViewModel(screen: screen, customerCenterActionHandler: customerCenterActionHandler) - self._viewModel = .init(wrappedValue: viewModel) + self.init(viewModel: viewModel, customerCenterActionHandler: customerCenterActionHandler) } - fileprivate init(viewModel: ManageSubscriptionsViewModel) { + fileprivate init(viewModel: ManageSubscriptionsViewModel, + customerCenterActionHandler: CustomerCenterActionHandler?) { self._viewModel = .init(wrappedValue: viewModel) + self.customerCenterActionHandler = customerCenterActionHandler } var body: some View { @@ -52,14 +56,16 @@ struct ManageSubscriptionsView: View { content .navigationDestination(isPresented: .isNotNil(self.$viewModel.feedbackSurveyData)) { if let feedbackSurveyData = self.viewModel.feedbackSurveyData { - FeedbackSurveyView(feedbackSurveyData: feedbackSurveyData) + FeedbackSurveyView(feedbackSurveyData: feedbackSurveyData, + customerCenterActionHandler: self.customerCenterActionHandler) } } } else { content .background(NavigationLink( destination: self.viewModel.feedbackSurveyData.map { data in - FeedbackSurveyView(feedbackSurveyData: data) + FeedbackSurveyView(feedbackSurveyData: data, + customerCenterActionHandler: self.customerCenterActionHandler) }, isActive: .isNotNil(self.$viewModel.feedbackSurveyData) ) { @@ -209,7 +215,8 @@ struct ManageSubscriptionsView_Previews: PreviewProvider { subscriptionInformation: CustomerCenterConfigTestData.subscriptionInformationMonthlyRenewing, customerCenterActionHandler: nil, refundRequestStatusMessage: "Refund granted successfully!") - ManageSubscriptionsView(viewModel: viewModelMonthlyRenewing) + ManageSubscriptionsView(viewModel: viewModelMonthlyRenewing, + customerCenterActionHandler: nil) .previewDisplayName("Monthly renewing") .environment(\.localization, CustomerCenterConfigTestData.customerCenterData.localization) .environment(\.appearance, CustomerCenterConfigTestData.customerCenterData.appearance) @@ -220,7 +227,8 @@ struct ManageSubscriptionsView_Previews: PreviewProvider { screen: CustomerCenterConfigTestData.customerCenterData.screens[.management]!, subscriptionInformation: CustomerCenterConfigTestData.subscriptionInformationYearlyExpiring, customerCenterActionHandler: nil) - ManageSubscriptionsView(viewModel: viewModelYearlyExpiring) + ManageSubscriptionsView(viewModel: viewModelYearlyExpiring, + customerCenterActionHandler: nil) .previewDisplayName("Yearly expiring") .environment(\.localization, CustomerCenterConfigTestData.customerCenterData.localization) .environment(\.appearance, CustomerCenterConfigTestData.customerCenterData.appearance) diff --git a/Tests/TestingApps/PaywallsTester/PaywallsTester/UI/Views/SamplePaywallsList.swift b/Tests/TestingApps/PaywallsTester/PaywallsTester/UI/Views/SamplePaywallsList.swift index 7e2c481c2b..aec736354b 100644 --- a/Tests/TestingApps/PaywallsTester/PaywallsTester/UI/Views/SamplePaywallsList.swift +++ b/Tests/TestingApps/PaywallsTester/PaywallsTester/UI/Views/SamplePaywallsList.swift @@ -89,7 +89,7 @@ struct SamplePaywallsList: View { ) case .customerCenter: #if CUSTOMER_CENTER_ENABLED - CustomerCenterView() + CustomerCenterView(customerCenterActionHandler: self.handleCustomerCenterAction) #endif #if PAYWALL_COMPONENTS case .componentPaywall(let data): @@ -248,6 +248,8 @@ extension SamplePaywallsList { print("CustomerCenter: refundRequestStarted. ProductId: \(productId)") case .refundRequestCompleted(let status): print("CustomerCenter: refundRequestCompleted. Result: \(status)") + case .feedbackSurveyCompleted(let option): + print("CustomerCenter: feedbackSurveyCompleted. Option selected: \(option)") } } }