From 02bc512143396caa0d6b4724250edeaf0b29d90b Mon Sep 17 00:00:00 2001 From: Tim Nowaczynski Date: Wed, 16 Apr 2025 13:58:41 +0200 Subject: [PATCH 1/5] [MOB-1589] Configured user prompt [MOB-1589] MOB-1589: App Store rating prompt improvements --- .../Main/AppSettingsTableViewController.swift | 29 +++++++++++++++++-- firefox-ios/Client/Frontend/Strings.swift | 15 ++++++++++ .../Ecosia/Core/Environment/URLProvider.swift | 11 +++++++ .../Ecosia/L10N/en.lproj/Ecosia.strings | 3 ++ 4 files changed, 56 insertions(+), 2 deletions(-) diff --git a/firefox-ios/Client/Frontend/Settings/Main/AppSettingsTableViewController.swift b/firefox-ios/Client/Frontend/Settings/Main/AppSettingsTableViewController.swift index 8e0f6f8dd2513..1b9d85ee1198a 100644 --- a/firefox-ios/Client/Frontend/Settings/Main/AppSettingsTableViewController.swift +++ b/firefox-ios/Client/Frontend/Settings/Main/AppSettingsTableViewController.swift @@ -44,6 +44,11 @@ class AppSettingsTableViewController: SettingsTableViewController, DebugSettingsDelegate, SearchBarLocationProvider, SharedSettingsDelegate { + + enum activityType: String { + case openURL = "org.mozilla.ios.Firefox.newTab" + } + // MARK: - Properties private var showDebugSettings = false private var debugSettingsClickCount: Int = 0 @@ -137,7 +142,7 @@ class AppSettingsTableViewController: SettingsTableViewController, case .creditCard: authenticateUserFor(route: route) case .rateApp: - RatingPromptManager.goToAppStoreReview() + interceptNegativeReviews() default: break } @@ -153,7 +158,25 @@ class AppSettingsTableViewController: SettingsTableViewController, } } - // MARK: - User Authentication + // MARK: Ecosia + + private func interceptNegativeReviews() { + let rateAction = UIAlertAction(title: .localized("Yes"), style: .default) { _ in + RatingPromptManager.goToAppStoreReview() + } + + let helpAction = UIAlertAction(title: .localized("No"), style: .destructive) { _ in + let helpActivity = NSUserActivity(activityType: activityType.openURL.rawValue) + // TODO: open help page + } + + let alertController = UIAlertController(title: .SettingsRatingPromptTitle, message: nil, preferredStyle: .alert) + alertController.addAction(rateAction) + alertController.addAction(helpAction) + present(alertController, animated: true) + } + + // MARK: - User AutheSntication // Authenticates the user prior to allowing access to sensitive sections private func authenticateUserFor(route: Route.SettingsSection) { @@ -387,6 +410,8 @@ class AppSettingsTableViewController: SettingsTableViewController, } private func getAboutSettings() -> [SettingSection] { + + let aboutSettings = [ AppStoreReviewSetting(settingsDelegate: parentCoordinator), VersionSetting(settingsDelegate: self), diff --git a/firefox-ios/Client/Frontend/Strings.swift b/firefox-ios/Client/Frontend/Strings.swift index 39ace6fdc1254..24754e7d53115 100644 --- a/firefox-ios/Client/Frontend/Strings.swift +++ b/firefox-ios/Client/Frontend/Strings.swift @@ -2829,6 +2829,21 @@ extension String { tableName: "Settings", value: "Addresses", comment: "Label used as an item in Settings screen. When touched, it will take user to address autofill settings page to that will allow user to add or modify saved addresses to allow for autofill in a webpage.") + public static let SettingsRatingPromptTitle = MZLocalizedString( + key: "Settings.RatingPrompt.Title", + tableName: "Settings", + value: "Do you enjoy Ecosia?", + comment: "This is what we prompt our users if they hit the rate button from within the settings") + public static let SettingsRatingPromptYes = MZLocalizedString( + key: "Settings.RatingPrompt.Yes", + tableName: "Settings", + value: "Yes", + comment: "When hit will redirect the user to rate the app on the app store") + public static let SettingsRatingPromptNo = MZLocalizedString( + key: "Settings.RatingPrompt.No", + tableName: "Settings", + value: "No", + comment: "Used to indicate the user does not like ecosia and will redirect them to our help pages") } // MARK: - Error pages diff --git a/firefox-ios/Ecosia/Core/Environment/URLProvider.swift b/firefox-ios/Ecosia/Core/Environment/URLProvider.swift index af92a1c105bc4..2f4a5455dfd40 100644 --- a/firefox-ios/Ecosia/Core/Environment/URLProvider.swift +++ b/firefox-ios/Ecosia/Core/Environment/URLProvider.swift @@ -162,4 +162,15 @@ public enum URLProvider { ] return components.url! } + + public var storePage: URL { + switch Language.current { + case .de: + return URL(string: "https://apps.apple.com/de/app/ecosia/id1474845552")! + case .fr: + return URL(string: "https://apps.apple.com/fr/app/ecosia/id1474845552")! + default: + return URL(string: "https://apps.apple.com/us/app/ecosia/id1474845552")! + } + } } diff --git a/firefox-ios/Ecosia/L10N/en.lproj/Ecosia.strings b/firefox-ios/Ecosia/L10N/en.lproj/Ecosia.strings index 17cb89d48828a..f3b2941ca3763 100644 --- a/firefox-ios/Ecosia/L10N/en.lproj/Ecosia.strings +++ b/firefox-ios/Ecosia/L10N/en.lproj/Ecosia.strings @@ -65,6 +65,9 @@ "Show on homepage" = "Show on homepage"; "Top Sites" = "Top Sites"; "Not now" = "Not now"; +"Do you enjoy Ecosia?" = "Do you enjoy Ecosia?"; +"Yes" = "Yes"; +"No" = "No"; // Impact "A friend accepted your invitation and each of you will help plant 1 tree!" = "A friend has accepted your invite! You have each helped plant 1 extra tree."; From 59d11c9c177a06079e90a2f7088a7b1c76a5c0d5 Mon Sep 17 00:00:00 2001 From: Tim Nowaczynski Date: Wed, 3 Sep 2025 13:01:45 +0200 Subject: [PATCH 2/5] [MOB-1589] Removed duplicated strings --- firefox-ios/Ecosia/L10N/en.lproj/Ecosia.strings | 3 --- 1 file changed, 3 deletions(-) diff --git a/firefox-ios/Ecosia/L10N/en.lproj/Ecosia.strings b/firefox-ios/Ecosia/L10N/en.lproj/Ecosia.strings index f3b2941ca3763..17cb89d48828a 100644 --- a/firefox-ios/Ecosia/L10N/en.lproj/Ecosia.strings +++ b/firefox-ios/Ecosia/L10N/en.lproj/Ecosia.strings @@ -65,9 +65,6 @@ "Show on homepage" = "Show on homepage"; "Top Sites" = "Top Sites"; "Not now" = "Not now"; -"Do you enjoy Ecosia?" = "Do you enjoy Ecosia?"; -"Yes" = "Yes"; -"No" = "No"; // Impact "A friend accepted your invitation and each of you will help plant 1 tree!" = "A friend has accepted your invite! You have each helped plant 1 extra tree."; From 9031268ed53a15ccd0afc3211bd9f4ed62cf2984 Mon Sep 17 00:00:00 2001 From: Tim Nowaczynski Date: Wed, 3 Sep 2025 16:21:39 +0200 Subject: [PATCH 3/5] [MOB-1589] * Fixed help URLs * Open help URL if user hit's no on rating prompt --- .../Main/AppSettingsTableViewController.swift | 11 +++------- .../Ecosia/Core/Environment/URLProvider.swift | 22 +++++++++++-------- 2 files changed, 16 insertions(+), 17 deletions(-) diff --git a/firefox-ios/Client/Frontend/Settings/Main/AppSettingsTableViewController.swift b/firefox-ios/Client/Frontend/Settings/Main/AppSettingsTableViewController.swift index 1b9d85ee1198a..b6ed2ac275ad5 100644 --- a/firefox-ios/Client/Frontend/Settings/Main/AppSettingsTableViewController.swift +++ b/firefox-ios/Client/Frontend/Settings/Main/AppSettingsTableViewController.swift @@ -45,10 +45,6 @@ class AppSettingsTableViewController: SettingsTableViewController, SearchBarLocationProvider, SharedSettingsDelegate { - enum activityType: String { - case openURL = "org.mozilla.ios.Firefox.newTab" - } - // MARK: - Properties private var showDebugSettings = false private var debugSettingsClickCount: Int = 0 @@ -162,12 +158,11 @@ class AppSettingsTableViewController: SettingsTableViewController, private func interceptNegativeReviews() { let rateAction = UIAlertAction(title: .localized("Yes"), style: .default) { _ in - RatingPromptManager.goToAppStoreReview() + UIApplication.shared.open(Environment.current.urlProvider.helpPage) } - let helpAction = UIAlertAction(title: .localized("No"), style: .destructive) { _ in - let helpActivity = NSUserActivity(activityType: activityType.openURL.rawValue) - // TODO: open help page + let helpAction = UIAlertAction(title: .localized("No"), style: .destructive) { [weak self] _ in + self?.settingsDelegate?.settingsOpenURLInNewTab(Environment.current.urlProvider.helpPage) } let alertController = UIAlertController(title: .SettingsRatingPromptTitle, message: nil, preferredStyle: .alert) diff --git a/firefox-ios/Ecosia/Core/Environment/URLProvider.swift b/firefox-ios/Ecosia/Core/Environment/URLProvider.swift index 2f4a5455dfd40..e5a95f06b9c43 100644 --- a/firefox-ios/Ecosia/Core/Environment/URLProvider.swift +++ b/firefox-ios/Ecosia/Core/Environment/URLProvider.swift @@ -152,6 +152,17 @@ public enum URLProvider { return URL(string: "https://ecosia.typeform.com/to/LlUGlFT9")! } } + + public var helpPage: URL { + switch Language.current { + case .de: + return URL(string: "https://de.support.ecosia.org/category/695-ecosia-ios-app")! + case .fr: + return URL(string: "https://fr.support.ecosia.org/category/805-ecosia-ios-app")! + default: + return URL(string: "https://support.ecosia.org/category/827-ecosia-ios-app")! + } + } public var notifications: URL { var components = URLComponents(url: URL(string: "https://api.ecosia.org/v1/notifications")!, resolvingAgainstBaseURL: false)! @@ -163,14 +174,7 @@ public enum URLProvider { return components.url! } - public var storePage: URL { - switch Language.current { - case .de: - return URL(string: "https://apps.apple.com/de/app/ecosia/id1474845552")! - case .fr: - return URL(string: "https://apps.apple.com/fr/app/ecosia/id1474845552")! - default: - return URL(string: "https://apps.apple.com/us/app/ecosia/id1474845552")! - } + public var storeWriteReviewPage: URL { + URL(string: "https://itunes.apple.com/app/id1474845552/action=write-review")! } } From 07130817db1f775f16ba42e923bda1407f0289df Mon Sep 17 00:00:00 2001 From: Tim Nowaczynski Date: Wed, 3 Sep 2025 16:42:10 +0200 Subject: [PATCH 4/5] [MOB-1589] Moved strings to our Ecosia Strings file & used them in AppSettingsTableViewController --- .../Main/AppSettingsTableViewController.swift | 6 +++--- firefox-ios/Client/Frontend/Strings.swift | 15 --------------- firefox-ios/Ecosia/L10N/String.swift | 5 ++++- 3 files changed, 7 insertions(+), 19 deletions(-) diff --git a/firefox-ios/Client/Frontend/Settings/Main/AppSettingsTableViewController.swift b/firefox-ios/Client/Frontend/Settings/Main/AppSettingsTableViewController.swift index b6ed2ac275ad5..94a6be5cfb06d 100644 --- a/firefox-ios/Client/Frontend/Settings/Main/AppSettingsTableViewController.swift +++ b/firefox-ios/Client/Frontend/Settings/Main/AppSettingsTableViewController.swift @@ -157,15 +157,15 @@ class AppSettingsTableViewController: SettingsTableViewController, // MARK: Ecosia private func interceptNegativeReviews() { - let rateAction = UIAlertAction(title: .localized("Yes"), style: .default) { _ in + let rateAction = UIAlertAction(title: .localized(.settingsRatingPromptYes), style: .default) { _ in UIApplication.shared.open(Environment.current.urlProvider.helpPage) } - let helpAction = UIAlertAction(title: .localized("No"), style: .destructive) { [weak self] _ in + let helpAction = UIAlertAction(title: .localized(.settingsRatingPromptNo), style: .destructive) { [weak self] _ in self?.settingsDelegate?.settingsOpenURLInNewTab(Environment.current.urlProvider.helpPage) } - let alertController = UIAlertController(title: .SettingsRatingPromptTitle, message: nil, preferredStyle: .alert) + let alertController = UIAlertController(title: .localized(.settingsRatingPromptTitle), message: nil, preferredStyle: .alert) alertController.addAction(rateAction) alertController.addAction(helpAction) present(alertController, animated: true) diff --git a/firefox-ios/Client/Frontend/Strings.swift b/firefox-ios/Client/Frontend/Strings.swift index 24754e7d53115..39ace6fdc1254 100644 --- a/firefox-ios/Client/Frontend/Strings.swift +++ b/firefox-ios/Client/Frontend/Strings.swift @@ -2829,21 +2829,6 @@ extension String { tableName: "Settings", value: "Addresses", comment: "Label used as an item in Settings screen. When touched, it will take user to address autofill settings page to that will allow user to add or modify saved addresses to allow for autofill in a webpage.") - public static let SettingsRatingPromptTitle = MZLocalizedString( - key: "Settings.RatingPrompt.Title", - tableName: "Settings", - value: "Do you enjoy Ecosia?", - comment: "This is what we prompt our users if they hit the rate button from within the settings") - public static let SettingsRatingPromptYes = MZLocalizedString( - key: "Settings.RatingPrompt.Yes", - tableName: "Settings", - value: "Yes", - comment: "When hit will redirect the user to rate the app on the app store") - public static let SettingsRatingPromptNo = MZLocalizedString( - key: "Settings.RatingPrompt.No", - tableName: "Settings", - value: "No", - comment: "Used to indicate the user does not like ecosia and will redirect them to our help pages") } // MARK: - Error pages diff --git a/firefox-ios/Ecosia/L10N/String.swift b/firefox-ios/Ecosia/L10N/String.swift index 8a4c8cbf0bdd4..b5dad5bdfebd6 100644 --- a/firefox-ios/Ecosia/L10N/String.swift +++ b/firefox-ios/Ecosia/L10N/String.swift @@ -233,7 +233,7 @@ extension String { case defaultBrowserCardDetailInstructionStep2 = "Select **Default Browser App**" case defaultBrowserCardDetailInstructionStep3 = "Choose **Ecosia**" case defaultBrowserCardDetailButton = "Make default in settings" - + // MARK: - Feedback View case reportIssue = "Report an issue" case helpCenter = "Help Center" @@ -242,5 +242,8 @@ extension String { case send = "Send" case close = "Close" case thankYouForYourFeedback = "Thank you for your feedback!" + case settingsRatingPromptTitle = "Do you enjoy Ecosia?" + case settingsRatingPromptYes = "Yes" + case settingsRatingPromptNo = "No" } } From 65f505e330984b6b9514693658cadafebf6f5145 Mon Sep 17 00:00:00 2001 From: Tim Nowaczynski Date: Thu, 4 Sep 2025 12:11:59 +0200 Subject: [PATCH 5/5] [MOB-1589] Update AppSettingsTableViewController.swift Fixed copy&paste error: used correct URL for writing reviews --- .../Frontend/Settings/Main/AppSettingsTableViewController.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/firefox-ios/Client/Frontend/Settings/Main/AppSettingsTableViewController.swift b/firefox-ios/Client/Frontend/Settings/Main/AppSettingsTableViewController.swift index 94a6be5cfb06d..1e078958162bb 100644 --- a/firefox-ios/Client/Frontend/Settings/Main/AppSettingsTableViewController.swift +++ b/firefox-ios/Client/Frontend/Settings/Main/AppSettingsTableViewController.swift @@ -158,7 +158,7 @@ class AppSettingsTableViewController: SettingsTableViewController, private func interceptNegativeReviews() { let rateAction = UIAlertAction(title: .localized(.settingsRatingPromptYes), style: .default) { _ in - UIApplication.shared.open(Environment.current.urlProvider.helpPage) + UIApplication.shared.open(Environment.current.urlProvider.storeWriteReviewPage) } let helpAction = UIAlertAction(title: .localized(.settingsRatingPromptNo), style: .destructive) { [weak self] _ in