From 0c04ba1786dc5e08df132c8d9e8dcdb5760d952b Mon Sep 17 00:00:00 2001 From: Joel Reis Date: Wed, 27 May 2020 16:26:53 -0400 Subject: [PATCH] Fix #2565: Retry ref code lookup on subsequent launches. (#2574) --- .../Analytics/UserReferralProgram.swift | 40 ++++++++++++++++++- BraveShared/Preferences.swift | 2 + .../Application/Delegates/AppDelegate.swift | 17 +++++++- 3 files changed, 56 insertions(+), 3 deletions(-) diff --git a/BraveShared/Analytics/UserReferralProgram.swift b/BraveShared/Analytics/UserReferralProgram.swift index 3aebe1cfa54..7240bf550d5 100644 --- a/BraveShared/Analytics/UserReferralProgram.swift +++ b/BraveShared/Analytics/UserReferralProgram.swift @@ -23,6 +23,17 @@ public class UserReferralProgram { static let prod = "https://laptop-updates.brave.com" } + // In case of network problems when looking for referrral code + // we retry the call few times while the app is still alive. + private struct ReferralLookupRetry { + var timer: Timer? + var currentCount = 0 + let retryLimit = 10 + let retryTimeInterval = AppConstants.buildChannel.isPublic ? 3.minutes : 1.minutes + } + + private var referralLookupRetry = ReferralLookupRetry() + let service: UrpService public init?() { @@ -49,7 +60,31 @@ public class UserReferralProgram { public func referralLookup(refCode: String?, completion: @escaping (_ refCode: String?, _ offerUrl: String?) -> Void) { UrpLog.log("first run referral lookup") - let referralBlock: (ReferralData?, UrpError?) -> Void = { referral, _ in + let referralBlock: (ReferralData?, UrpError?) -> Void = { [weak self] referral, error in + guard let self = self else { return } + + if error == BraveShared.UrpError.endpointError { + UrpLog.log("URP look up had endpoint error, will retry on next launch.") + self.referralLookupRetry.timer?.invalidate() + self.referralLookupRetry.timer = nil + + // Hit max retry attempts. + if self.referralLookupRetry.currentCount > self.referralLookupRetry.retryLimit { return } + + self.referralLookupRetry.currentCount += 1 + self.referralLookupRetry.timer = + Timer.scheduledTimer(withTimeInterval: self.referralLookupRetry.retryTimeInterval, + repeats: true) { [weak self] _ in + self?.referralLookup(refCode: refCode) { refCode, offerUrl in + completion(refCode, offerUrl) + } + } + return + } + + // Connection "succeeded" + + Preferences.URP.referralLookupOutstanding.value = false guard let ref = referral else { log.info("No referral code found") UrpLog.log("No referral code found") @@ -75,6 +110,9 @@ public class UserReferralProgram { Preferences.URP.downloadId.value = ref.downloadId Preferences.URP.referralCode.value = ref.referralCode + self.referralLookupRetry.timer?.invalidate() + self.referralLookupRetry.timer = nil + UrpLog.log("Found referral: downloadId: \(ref.downloadId), code: \(ref.referralCode)") // In case of network errors or getting `isFinalized = false`, we retry the api call. self.initRetryPingConnection(numberOfTimes: 30) diff --git a/BraveShared/Preferences.swift b/BraveShared/Preferences.swift index e65961fba18..e665ad7d640 100644 --- a/BraveShared/Preferences.swift +++ b/BraveShared/Preferences.swift @@ -41,6 +41,8 @@ extension Preferences { static let downloadId = Option(key: "urp.referral.download-id", default: nil) public static let referralCode = Option(key: "urp.referral.code", default: nil) static let referralCodeDeleteDate = Option(key: "urp.referral.delete-date", default: nil) + /// Whether the ref code lookup has still yet to occur + public static let referralLookupOutstanding = Option(key: "urp.referral.lookkup-completed", default: nil) } public final class NTP { diff --git a/Client/Application/Delegates/AppDelegate.swift b/Client/Application/Delegates/AppDelegate.swift index 064771edcd8..a6851c27812 100644 --- a/Client/Application/Delegates/AppDelegate.swift +++ b/Client/Application/Delegates/AppDelegate.swift @@ -260,9 +260,22 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UIViewControllerRestorati } if let urp = UserReferralProgram.shared { - if isFirstLaunch { + if Preferences.URP.referralLookupOutstanding.value == nil { + // This preference has never been set, and this means it is a new or upgraded user. + // That distinction must be made to know if a network request for ref-code look up should be made. + + // Setting this to an explicit value so it will never get overwritten on subsequent launches. + // Upgrade users should not have ref code ping happening. + Preferences.URP.referralLookupOutstanding.value = isFirstLaunch + } + + if Preferences.URP.referralLookupOutstanding.value == true { let refCode = UserReferralProgram.sanitize(input: UIPasteboard.general.string) - if refCode != nil { UIPasteboard.general.clearPasteboard() } + if refCode != nil { + UrpLog.log("Clipboard ref code found: " + (UIPasteboard.general.string ?? "!Clipboard Empty!")) + UrpLog.log("Clearing clipboard.") + UIPasteboard.general.clearPasteboard() + } urp.referralLookup(refCode: refCode) { referralCode, offerUrl in if let code = referralCode {