From dced060aae9913638c981b95d2dfcfe40b968a3e Mon Sep 17 00:00:00 2001 From: Jax DesMarais-Leder Date: Tue, 17 Sep 2024 11:31:52 -0500 Subject: [PATCH 01/17] update Venmo flow to accept optional universal link --- .../Features/VenmoViewController.swift | 6 +++++- .../BTVenmoAppSwitchRedirectURL.swift | 16 ++++++++++++---- .../BTVenmoAppSwitchReturnURL.swift | 9 +++++---- Sources/BraintreeVenmo/BTVenmoClient.swift | 17 +++++++++++++++-- 4 files changed, 37 insertions(+), 11 deletions(-) diff --git a/Demo/Application/Features/VenmoViewController.swift b/Demo/Application/Features/VenmoViewController.swift index ee34a1ff57..7b33d0041e 100644 --- a/Demo/Application/Features/VenmoViewController.swift +++ b/Demo/Application/Features/VenmoViewController.swift @@ -7,7 +7,11 @@ class VenmoViewController: PaymentButtonBaseViewController { override func viewDidLoad() { super.viewDidLoad() - venmoClient = BTVenmoClient(apiClient: apiClient) + venmoClient = BTVenmoClient( + apiClient: apiClient, + // swiftlint:disable:next force_unwrapping + universalLink: URL(string: "https://mobile-sdk-demo-site-838cead5d3ab.herokuapp.com/braintree-payments")! + ) title = "Custom Venmo Button" } diff --git a/Sources/BraintreeVenmo/BTVenmoAppSwitchRedirectURL.swift b/Sources/BraintreeVenmo/BTVenmoAppSwitchRedirectURL.swift index b9d561e064..a83ebb2031 100644 --- a/Sources/BraintreeVenmo/BTVenmoAppSwitchRedirectURL.swift +++ b/Sources/BraintreeVenmo/BTVenmoAppSwitchRedirectURL.swift @@ -22,9 +22,10 @@ struct BTVenmoAppSwitchRedirectURL { // MARK: - Initializer init( - returnURLScheme: String, paymentContextID: String, metadata: BTClientMetadata, + returnURLScheme: String?, + universalLink: URL?, forMerchantID merchantID: String?, accessToken: String?, bundleDisplayName: String?, @@ -46,9 +47,6 @@ struct BTVenmoAppSwitchRedirectURL { let base64EncodedBraintreeData = serializedBraintreeData?.base64EncodedString() queryParameters = [ - "x-success": constructRedirectURL(with: returnURLScheme, result: "success"), - "x-error": constructRedirectURL(with: returnURLScheme, result: "error"), - "x-cancel": constructRedirectURL(with: returnURLScheme, result: "cancel"), "x-source": bundleDisplayName, "braintree_merchant_id": merchantID, "braintree_access_token": accessToken, @@ -57,6 +55,16 @@ struct BTVenmoAppSwitchRedirectURL { "braintree_sdk_data": base64EncodedBraintreeData ?? "", "customerClient": "MOBILE_APP" ] + + if let universalLink { + queryParameters["x-success"] = universalLink.absoluteString + "/success" + queryParameters["x-error"] = universalLink.absoluteString + "/error" + queryParameters["x-cancel"] = universalLink.absoluteString + "/cancel" + } else if let returnURLScheme { + queryParameters["x-success"] = constructRedirectURL(with: returnURLScheme, result: "success") + queryParameters["x-error"] = constructRedirectURL(with: returnURLScheme, result: "error") + queryParameters["x-cancel"] = constructRedirectURL(with: returnURLScheme, result: "cancel") + } } // MARK: - Internal Methods diff --git a/Sources/BraintreeVenmo/BTVenmoAppSwitchReturnURL.swift b/Sources/BraintreeVenmo/BTVenmoAppSwitchReturnURL.swift index b1fcd30be4..569054b539 100644 --- a/Sources/BraintreeVenmo/BTVenmoAppSwitchReturnURL.swift +++ b/Sources/BraintreeVenmo/BTVenmoAppSwitchReturnURL.swift @@ -41,7 +41,7 @@ struct BTVenmoAppSwitchReturnURL { init?(url: URL) { let parameters = BTURLUtils.queryParameters(for: url) - if url.path == "/vzero/auth/venmo/success" { + if url.path.contains("success") { if let resourceID = parameters["resource_id"] { state = .succeededWithPaymentContext paymentContextID = resourceID @@ -50,12 +50,12 @@ struct BTVenmoAppSwitchReturnURL { nonce = parameters["paymentMethodNonce"] ?? parameters["payment_method_nonce"] username = parameters["username"] } - } else if url.path == "/vzero/auth/venmo/error" { + } else if url.path.contains("error") { state = .failed let errorMessage: String? = parameters["errorMessage"] ?? parameters["error_message"] let errorCode = Int(parameters["errorCode"] ?? parameters["error_code"] ?? "0") error = BTVenmoAppSwitchError.returnURLError(errorCode ?? 0, errorMessage) - } else if url.path == "/vzero/auth/venmo/cancel" { + } else if url.path.contains("cancel") { state = .canceled } else { state = .unknown @@ -68,6 +68,7 @@ struct BTVenmoAppSwitchReturnURL { /// - Parameter url: an app switch return URL /// - Returns: `true` if the url represents a Venmo Touch app switch return static func isValid(url: URL) -> Bool { - url.host == "x-callback-url" && url.path.hasPrefix("/vzero/auth/venmo/") + (url.scheme == "https" && (url.path.contains("cancel") || url.path.contains("success") || url.path.contains("error"))) + || (url.host == "x-callback-url" && url.path.hasPrefix("/vzero/auth/venmo/")) } } diff --git a/Sources/BraintreeVenmo/BTVenmoClient.swift b/Sources/BraintreeVenmo/BTVenmoClient.swift index da09e31dfc..81f075c300 100644 --- a/Sources/BraintreeVenmo/BTVenmoClient.swift +++ b/Sources/BraintreeVenmo/BTVenmoClient.swift @@ -46,9 +46,11 @@ import BraintreeCore /// Used for sending the type of flow, universal vs deeplink to FPTI private var linkType: LinkType? + private var universalLink: URL? + // MARK: - Initializer - /// Creates an Apple Pay client + /// Creates an Venmo client /// - Parameter apiClient: An API client @objc(initWithAPIClient:) public init(apiClient: BTAPIClient) { @@ -56,6 +58,16 @@ import BraintreeCore self.apiClient = apiClient } + /// Initialize a new Venmo client instance. + /// - Parameters: + /// - apiClient: The API Client + /// - universalLink: The URL to use for the Venmo flow. Must be a valid HTTPS URL dedicated to Braintree app switch returns. + @objc(initWithAPIClient:universalLink:) + public convenience init(apiClient: BTAPIClient, universalLink: URL) { + self.init(apiClient: apiClient) + self.universalLink = universalLink + } + // MARK: - Public Methods /// Initiates Venmo login via app switch, which returns a BTVenmoAccountNonce when successful. @@ -151,9 +163,10 @@ import BraintreeCore do { let appSwitchURL = try BTVenmoAppSwitchRedirectURL( - returnURLScheme: returnURLScheme, paymentContextID: paymentContextID, metadata: metadata, + returnURLScheme: returnURLScheme, + universalLink: self.universalLink, forMerchantID: merchantProfileID, accessToken: configuration.venmoAccessToken, bundleDisplayName: bundleDisplayName, From 912eb0f355b483507dceaa140a2dc76081f036a3 Mon Sep 17 00:00:00 2001 From: Sammy Cannillo Date: Thu, 17 Oct 2024 12:24:12 -0500 Subject: [PATCH 02/17] Clarify Docstrings for universal link in BTVenmoClient --- Sources/BraintreeVenmo/BTVenmoClient.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/BraintreeVenmo/BTVenmoClient.swift b/Sources/BraintreeVenmo/BTVenmoClient.swift index 81f075c300..1b0f68021a 100644 --- a/Sources/BraintreeVenmo/BTVenmoClient.swift +++ b/Sources/BraintreeVenmo/BTVenmoClient.swift @@ -61,7 +61,7 @@ import BraintreeCore /// Initialize a new Venmo client instance. /// - Parameters: /// - apiClient: The API Client - /// - universalLink: The URL to use for the Venmo flow. Must be a valid HTTPS URL dedicated to Braintree app switch returns. + /// - universalLink: The URL to use for the Venmo app switch flow to redirect back to after completion. Must be a valid HTTPS URL dedicated to Braintree app switch returns. @objc(initWithAPIClient:universalLink:) public convenience init(apiClient: BTAPIClient, universalLink: URL) { self.init(apiClient: apiClient) From 9780698fcb00befbc3f99708b092f1f7c81734e4 Mon Sep 17 00:00:00 2001 From: Sammy Cannillo Date: Thu, 17 Oct 2024 12:24:25 -0500 Subject: [PATCH 03/17] Add Universal Link return toggle to Demo --- .../Features/VenmoViewController.swift | 28 +++++++++++++++---- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/Demo/Application/Features/VenmoViewController.swift b/Demo/Application/Features/VenmoViewController.swift index da33551790..4d0c7352f0 100644 --- a/Demo/Application/Features/VenmoViewController.swift +++ b/Demo/Application/Features/VenmoViewController.swift @@ -1,14 +1,25 @@ import UIKit import BraintreeVenmo +// swiftlint:disable implicitly_unwrapped_optional class VenmoViewController: PaymentButtonBaseViewController { - // swiftlint:disable:next implicitly_unwrapped_optional var venmoClient: BTVenmoClient! + var venmoClientUniversalLink: BTVenmoClient! + + lazy var universalLinkReturnToggleLabel: UILabel = { + let label = UILabel() + label.text = "Use Universal Link Return" + label.font = .preferredFont(forTextStyle: .footnote) + return label + }() + + let universalLinkReturnToggle = UISwitch() override func viewDidLoad() { super.viewDidLoad() - venmoClient = BTVenmoClient( + venmoClient = BTVenmoClient(apiClient: apiClient) + venmoClientUniversalLink = BTVenmoClient( apiClient: apiClient, // swiftlint:disable:next force_unwrapping universalLink: URL(string: "https://mobile-sdk-demo-site-838cead5d3ab.herokuapp.com/braintree-payments")! @@ -21,7 +32,14 @@ class VenmoViewController: PaymentButtonBaseViewController { let venmoECDButton = createButton(title: "Venmo (with ECD options)", action: #selector(tappedVenmoWithECD)) let venmoUniversalLinkButton = createButton(title: "Venmo Universal Links", action: #selector(tappedVenmoWithUniversalLinks)) - let stackView = UIStackView(arrangedSubviews: [venmoButton, venmoECDButton, venmoUniversalLinkButton]) + let stackView = UIStackView( + arrangedSubviews: [ + UIStackView(arrangedSubviews: [universalLinkReturnToggleLabel, universalLinkReturnToggle]), + venmoButton, + venmoECDButton, + venmoUniversalLinkButton + ] + ) stackView.axis = .vertical stackView.spacing = 5 stackView.alignment = .center @@ -69,10 +87,10 @@ class VenmoViewController: PaymentButtonBaseViewController { checkout(request: venmoRequest) } - func checkout(request: BTVenmoRequest) { + func checkout(request: BTVenmoRequest) { Task { do { - let venmoAccount = try await venmoClient.tokenize(request) + let venmoAccount = try await (universalLinkReturnToggle.isOn ? venmoClientUniversalLink : venmoClient).tokenize(request) progressBlock("Got a nonce 💎!") completionBlock(venmoAccount) } catch { From d4631bae7c1e0419ba4f0ab6ff43c935d2dee9c9 Mon Sep 17 00:00:00 2001 From: Jax DesMarais-Leder Date: Thu, 17 Oct 2024 15:50:04 -0500 Subject: [PATCH 04/17] swiftlint cleanup --- Demo/Application/Features/VenmoViewController.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Demo/Application/Features/VenmoViewController.swift b/Demo/Application/Features/VenmoViewController.swift index 4d0c7352f0..6a467a27ea 100644 --- a/Demo/Application/Features/VenmoViewController.swift +++ b/Demo/Application/Features/VenmoViewController.swift @@ -87,7 +87,7 @@ class VenmoViewController: PaymentButtonBaseViewController { checkout(request: venmoRequest) } - func checkout(request: BTVenmoRequest) { + func checkout(request: BTVenmoRequest) { Task { do { let venmoAccount = try await (universalLinkReturnToggle.isOn ? venmoClientUniversalLink : venmoClient).tokenize(request) From c78d2932d7cfaae3348734332894127452081e15 Mon Sep 17 00:00:00 2001 From: Sammy Cannillo Date: Thu, 17 Oct 2024 16:28:47 -0500 Subject: [PATCH 05/17] Fixup - cleanup Demo toggle b/w universal link return & regular return --- .../Features/VenmoViewController.swift | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/Demo/Application/Features/VenmoViewController.swift b/Demo/Application/Features/VenmoViewController.swift index 6a467a27ea..fd1acb19f0 100644 --- a/Demo/Application/Features/VenmoViewController.swift +++ b/Demo/Application/Features/VenmoViewController.swift @@ -5,7 +5,6 @@ import BraintreeVenmo class VenmoViewController: PaymentButtonBaseViewController { var venmoClient: BTVenmoClient! - var venmoClientUniversalLink: BTVenmoClient! lazy var universalLinkReturnToggleLabel: UILabel = { let label = UILabel() @@ -19,11 +18,6 @@ class VenmoViewController: PaymentButtonBaseViewController { override func viewDidLoad() { super.viewDidLoad() venmoClient = BTVenmoClient(apiClient: apiClient) - venmoClientUniversalLink = BTVenmoClient( - apiClient: apiClient, - // swiftlint:disable:next force_unwrapping - universalLink: URL(string: "https://mobile-sdk-demo-site-838cead5d3ab.herokuapp.com/braintree-payments")! - ) title = "Custom Venmo Button" } @@ -88,9 +82,17 @@ class VenmoViewController: PaymentButtonBaseViewController { } func checkout(request: BTVenmoRequest) { + if universalLinkReturnToggle.isOn { + venmoClient = BTVenmoClient( + apiClient: apiClient, + // swiftlint:disable:next force_unwrapping + universalLink: URL(string: "https://mobile-sdk-demo-site-838cead5d3ab.herokuapp.com/braintree-payments")! + ) + } + Task { do { - let venmoAccount = try await (universalLinkReturnToggle.isOn ? venmoClientUniversalLink : venmoClient).tokenize(request) + let venmoAccount = try await (venmoClient).tokenize(request) progressBlock("Got a nonce 💎!") completionBlock(venmoAccount) } catch { From b191177f51929f1cf2fec314b4de3fc1f1fb33a3 Mon Sep 17 00:00:00 2001 From: Jax DesMarais-Leder Date: Thu, 17 Oct 2024 16:29:08 -0500 Subject: [PATCH 06/17] update redirectURL tests --- .../BTVenmoAppSwitchRedirectURL_Tests.swift | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/UnitTests/BraintreeVenmoTests/BTVenmoAppSwitchRedirectURL_Tests.swift b/UnitTests/BraintreeVenmoTests/BTVenmoAppSwitchRedirectURL_Tests.swift index da92e9bc00..fef916e212 100644 --- a/UnitTests/BraintreeVenmoTests/BTVenmoAppSwitchRedirectURL_Tests.swift +++ b/UnitTests/BraintreeVenmoTests/BTVenmoAppSwitchRedirectURL_Tests.swift @@ -7,9 +7,10 @@ class BTVenmoAppSwitchRedirectURL_Tests: XCTestCase { func testUrlSchemeURL_whenAllValuesAreInitialized_returnsURLWithPaymentContextID() { do { let requestURL = try BTVenmoAppSwitchRedirectURL( - returnURLScheme: "url-scheme", paymentContextID: "12345", metadata: BTClientMetadata(), + returnURLScheme: "url-scheme", + universalLink: nil, forMerchantID: "merchant-id", accessToken: "access-token", bundleDisplayName: "display-name", @@ -29,9 +30,10 @@ class BTVenmoAppSwitchRedirectURL_Tests: XCTestCase { func testAppSwitchURL_whenMerchantIDNil_throwsError() { do { _ = try BTVenmoAppSwitchRedirectURL( - returnURLScheme: "url-scheme", paymentContextID: "12345", metadata: BTClientMetadata(), + returnURLScheme: "url-scheme", + universalLink: nil, forMerchantID: nil, accessToken: "access-token", bundleDisplayName: "display-name", @@ -47,9 +49,10 @@ class BTVenmoAppSwitchRedirectURL_Tests: XCTestCase { func testUniversalLinkURL_whenAllValuesInitialized_returnsURLWithAllValues() { do { let requestURL = try BTVenmoAppSwitchRedirectURL( - returnURLScheme: "url-scheme", paymentContextID: "12345", metadata: BTClientMetadata(), + returnURLScheme: nil, + universalLink: URL(string: "https://mywebsite.com/braintree-payments"), forMerchantID: "merchant-id", accessToken: "access-token", bundleDisplayName: "display-name", @@ -60,9 +63,9 @@ class BTVenmoAppSwitchRedirectURL_Tests: XCTestCase { let components = URLComponents(string: requestURL.universalLinksURL()!.absoluteString) guard let queryItems = components?.queryItems else { XCTFail(); return } - XCTAssertTrue(queryItems.contains(URLQueryItem(name: "x-success", value: "url-scheme://x-callback-url/vzero/auth/venmo/success"))) - XCTAssertTrue(queryItems.contains(URLQueryItem(name: "x-error", value: "url-scheme://x-callback-url/vzero/auth/venmo/error"))) - XCTAssertTrue(queryItems.contains(URLQueryItem(name: "x-cancel", value: "url-scheme://x-callback-url/vzero/auth/venmo/cancel"))) + XCTAssertTrue(queryItems.contains(URLQueryItem(name: "x-success", value: "https://mywebsite.com/braintree-payments/success"))) + XCTAssertTrue(queryItems.contains(URLQueryItem(name: "x-error", value: "https://mywebsite.com/braintree-payments/error"))) + XCTAssertTrue(queryItems.contains(URLQueryItem(name: "x-cancel", value: "https://mywebsite.com/braintree-payments/cancel"))) XCTAssertTrue(queryItems.contains(URLQueryItem(name: "x-source", value: "display-name"))) XCTAssertTrue(queryItems.contains(URLQueryItem(name: "braintree_merchant_id", value: "merchant-id"))) XCTAssertTrue(queryItems.contains(URLQueryItem(name: "braintree_access_token", value: "access-token"))) From 43eeea53459af9bfbc32636419338506e9d0576a Mon Sep 17 00:00:00 2001 From: Sammy Cannillo Date: Thu, 17 Oct 2024 16:29:38 -0500 Subject: [PATCH 07/17] Fixup - docstring clarification --- Sources/BraintreeVenmo/BTVenmoClient.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/BraintreeVenmo/BTVenmoClient.swift b/Sources/BraintreeVenmo/BTVenmoClient.swift index 1b0f68021a..d000e74744 100644 --- a/Sources/BraintreeVenmo/BTVenmoClient.swift +++ b/Sources/BraintreeVenmo/BTVenmoClient.swift @@ -61,7 +61,7 @@ import BraintreeCore /// Initialize a new Venmo client instance. /// - Parameters: /// - apiClient: The API Client - /// - universalLink: The URL to use for the Venmo app switch flow to redirect back to after completion. Must be a valid HTTPS URL dedicated to Braintree app switch returns. + /// - universalLink: The URL for the Venmo app to redirect to after user authentication completes. Must be a valid HTTPS URL dedicated to Braintree app switch returns. @objc(initWithAPIClient:universalLink:) public convenience init(apiClient: BTAPIClient, universalLink: URL) { self.init(apiClient: apiClient) From 91ea18e09abe2be1afd6d164d9f49db18a4440ca Mon Sep 17 00:00:00 2001 From: Jax DesMarais-Leder Date: Mon, 21 Oct 2024 08:59:52 -0500 Subject: [PATCH 08/17] add CHANGELOG entry --- CHANGELOG.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4d21b71a18..2dc781ff90 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,9 @@ ## unreleased * BraintreePayPal * Add `BTPayPalRequest.userPhoneNumber` optional property - +* BraintreeVenmo + * Add `BTVenmoClient(apiClient:universalLink:)` to use Universal Links when redirecting back from the Venmo flow + ## 6.24.0 (2024-10-15) * BraintreePayPal * Add `BTPayPalRecurringBillingDetails` and `BTPayPalRecurringBillingPlanType` opt-in request objects. Including these details will provide transparency to users on their billing schedule, dates, and amounts, as well as launch a modernized checkout UI. From 2e8ba83d8cbf669030929f2d1bce12f95c2ca18d Mon Sep 17 00:00:00 2001 From: Jax DesMarais-Leder Date: Mon, 21 Oct 2024 10:32:53 -0500 Subject: [PATCH 09/17] PR feedabck: update to handle formatting of merchant passed URL --- Sources/BraintreeVenmo/BTVenmoAppSwitchRedirectURL.swift | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Sources/BraintreeVenmo/BTVenmoAppSwitchRedirectURL.swift b/Sources/BraintreeVenmo/BTVenmoAppSwitchRedirectURL.swift index a83ebb2031..862a1c9ea9 100644 --- a/Sources/BraintreeVenmo/BTVenmoAppSwitchRedirectURL.swift +++ b/Sources/BraintreeVenmo/BTVenmoAppSwitchRedirectURL.swift @@ -57,9 +57,9 @@ struct BTVenmoAppSwitchRedirectURL { ] if let universalLink { - queryParameters["x-success"] = universalLink.absoluteString + "/success" - queryParameters["x-error"] = universalLink.absoluteString + "/error" - queryParameters["x-cancel"] = universalLink.absoluteString + "/cancel" + queryParameters["x-success"] = universalLink.appendingPathComponent("success").absoluteString + queryParameters["x-error"] = universalLink.appendingPathComponent("error").absoluteString + queryParameters["x-cancel"] = universalLink.appendingPathComponent("cancel").absoluteString } else if let returnURLScheme { queryParameters["x-success"] = constructRedirectURL(with: returnURLScheme, result: "success") queryParameters["x-error"] = constructRedirectURL(with: returnURLScheme, result: "error") From eef74ed839aff2f1c6357b54d2daa72b2710cfb4 Mon Sep 17 00:00:00 2001 From: Jax DesMarais-Leder Date: Mon, 21 Oct 2024 10:56:33 -0500 Subject: [PATCH 10/17] PR feedback: deprecate returnURLScheme --- Sources/BraintreeCore/BTAppContextSwitcher.swift | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Sources/BraintreeCore/BTAppContextSwitcher.swift b/Sources/BraintreeCore/BTAppContextSwitcher.swift index db875e268d..0e8dfb7d85 100644 --- a/Sources/BraintreeCore/BTAppContextSwitcher.swift +++ b/Sources/BraintreeCore/BTAppContextSwitcher.swift @@ -14,6 +14,11 @@ import UIKit /// The URL scheme to return to this app after switching to another app or opening a SFSafariViewController. /// This URL scheme must be registered as a URL Type in the app's info.plist, and it must start with the app's bundle ID. /// - Note: This property should only be used for the Venmo flow. + @available( + *, + deprecated, + message: "returnURLScheme is deprecated and will be removed in a future version. Use BTVenmoClient(apiClient:universalLink:)." + ) public var returnURLScheme: String = "" // MARK: - Private Properties From 37005b2c61f5481883ca0b01bdd3dc9ab843a533 Mon Sep 17 00:00:00 2001 From: Jax DesMarais-Leder Date: Mon, 21 Oct 2024 11:22:56 -0500 Subject: [PATCH 11/17] cleanup after merge from main --- .../Application/Features/VenmoViewController.swift | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/Demo/Application/Features/VenmoViewController.swift b/Demo/Application/Features/VenmoViewController.swift index 828e6d818a..bbe913bfe9 100644 --- a/Demo/Application/Features/VenmoViewController.swift +++ b/Demo/Application/Features/VenmoViewController.swift @@ -51,21 +51,9 @@ class VenmoViewController: PaymentButtonBaseViewController { ) } - checkout(request: venmoRequest) - } - - func checkout(request: BTVenmoRequest) { - if universalLinkReturnToggle.isOn { - venmoClient = BTVenmoClient( - apiClient: apiClient, - // swiftlint:disable:next force_unwrapping - universalLink: URL(string: "https://mobile-sdk-demo-site-838cead5d3ab.herokuapp.com/braintree-payments")! - ) - } - Task { do { - let venmoAccount = try await (venmoClient).tokenize(request) + let venmoAccount = try await (venmoClient).tokenize(venmoRequest) progressBlock("Got a nonce 💎!") completionBlock(venmoAccount) } catch { From 30e60dc9b963dd17907a2f76909c33abae82008c Mon Sep 17 00:00:00 2001 From: Jax DesMarais-Leder Date: Mon, 21 Oct 2024 11:24:47 -0500 Subject: [PATCH 12/17] update spacing and swiftlint disable scope --- Demo/Application/Features/VenmoViewController.swift | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Demo/Application/Features/VenmoViewController.swift b/Demo/Application/Features/VenmoViewController.swift index bbe913bfe9..5be1c43a30 100644 --- a/Demo/Application/Features/VenmoViewController.swift +++ b/Demo/Application/Features/VenmoViewController.swift @@ -1,9 +1,9 @@ import UIKit import BraintreeVenmo -// swiftlint:disable implicitly_unwrapped_optional class VenmoViewController: PaymentButtonBaseViewController { - + + // swiftlint:disable implicitly_unwrapped_optional var venmoClient: BTVenmoClient! let webFallbackToggle = Toggle(title: "Enable Web Fallback") @@ -19,8 +19,8 @@ class VenmoViewController: PaymentButtonBaseViewController { override func createPaymentButton() -> UIView { let venmoButton = createButton(title: "Venmo", action: #selector(tappedVenmo)) - let stackView = UIStackView(arrangedSubviews: [webFallbackToggle, vaultToggle, universalLinkReturnToggle, venmoButton]) + let stackView = UIStackView(arrangedSubviews: [webFallbackToggle, vaultToggle, universalLinkReturnToggle, venmoButton]) stackView.axis = .vertical stackView.spacing = 15 stackView.alignment = .fill @@ -53,7 +53,7 @@ class VenmoViewController: PaymentButtonBaseViewController { Task { do { - let venmoAccount = try await (venmoClient).tokenize(venmoRequest) + let venmoAccount = try await venmoClient.tokenize(venmoRequest) progressBlock("Got a nonce 💎!") completionBlock(venmoAccount) } catch { From 2fd461c229d380586c3784d738836bca2c200ef5 Mon Sep 17 00:00:00 2001 From: Jax DesMarais-Leder Date: Mon, 21 Oct 2024 13:18:45 -0500 Subject: [PATCH 13/17] Update Sources/BraintreeVenmo/BTVenmoClient.swift Co-authored-by: agedd <105314544+agedd@users.noreply.github.com> --- Sources/BraintreeVenmo/BTVenmoClient.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/BraintreeVenmo/BTVenmoClient.swift b/Sources/BraintreeVenmo/BTVenmoClient.swift index d000e74744..3ced113275 100644 --- a/Sources/BraintreeVenmo/BTVenmoClient.swift +++ b/Sources/BraintreeVenmo/BTVenmoClient.swift @@ -50,7 +50,7 @@ import BraintreeCore // MARK: - Initializer - /// Creates an Venmo client + /// Creates a Venmo client /// - Parameter apiClient: An API client @objc(initWithAPIClient:) public init(apiClient: BTAPIClient) { From f8b3c8d97fda990e41540ce19c95096627438ec7 Mon Sep 17 00:00:00 2001 From: Jax DesMarais-Leder Date: Mon, 21 Oct 2024 15:18:22 -0500 Subject: [PATCH 14/17] update to disable next --- Demo/Application/Features/VenmoViewController.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Demo/Application/Features/VenmoViewController.swift b/Demo/Application/Features/VenmoViewController.swift index 5be1c43a30..1668872139 100644 --- a/Demo/Application/Features/VenmoViewController.swift +++ b/Demo/Application/Features/VenmoViewController.swift @@ -3,7 +3,7 @@ import BraintreeVenmo class VenmoViewController: PaymentButtonBaseViewController { - // swiftlint:disable implicitly_unwrapped_optional + // swiftlint:disable:next implicitly_unwrapped_optional var venmoClient: BTVenmoClient! let webFallbackToggle = Toggle(title: "Enable Web Fallback") From 22ab7c0727f815d24333ea04c1fb71699a5d2ecf Mon Sep 17 00:00:00 2001 From: Jax DesMarais-Leder Date: Tue, 22 Oct 2024 09:28:42 -0500 Subject: [PATCH 15/17] remove deprecated so pod lib lint passes --- Sources/BraintreeCore/BTAppContextSwitcher.swift | 5 ----- 1 file changed, 5 deletions(-) diff --git a/Sources/BraintreeCore/BTAppContextSwitcher.swift b/Sources/BraintreeCore/BTAppContextSwitcher.swift index 0e8dfb7d85..db875e268d 100644 --- a/Sources/BraintreeCore/BTAppContextSwitcher.swift +++ b/Sources/BraintreeCore/BTAppContextSwitcher.swift @@ -14,11 +14,6 @@ import UIKit /// The URL scheme to return to this app after switching to another app or opening a SFSafariViewController. /// This URL scheme must be registered as a URL Type in the app's info.plist, and it must start with the app's bundle ID. /// - Note: This property should only be used for the Venmo flow. - @available( - *, - deprecated, - message: "returnURLScheme is deprecated and will be removed in a future version. Use BTVenmoClient(apiClient:universalLink:)." - ) public var returnURLScheme: String = "" // MARK: - Private Properties From 2705af71d15b7b0ee218ad97d9d27db7ff362c70 Mon Sep 17 00:00:00 2001 From: Jax DesMarais-Leder Date: Tue, 22 Oct 2024 09:55:49 -0500 Subject: [PATCH 16/17] add CHANGELOG and update deprecation message to work with cocoapods --- CHANGELOG.md | 2 ++ Sources/BraintreeCore/BTAppContextSwitcher.swift | 16 +++++++++++++++- Sources/BraintreeVenmo/BTVenmoClient.swift | 2 +- 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bfac171650..edb103d9c3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,8 @@ * BraintreeVenmo * Send `url` in `event_params` for App Switch events to PayPal's analytics service (FPTI) * Add `BTVenmoClient(apiClient:universalLink:)` to use Universal Links when redirecting back from the Venmo flow +* BraintreeCore + * Deprecate `BTAppContextSwitcher.sharedInstance.returnURLScheme` ## 6.24.0 (2024-10-15) * BraintreePayPal diff --git a/Sources/BraintreeCore/BTAppContextSwitcher.swift b/Sources/BraintreeCore/BTAppContextSwitcher.swift index db875e268d..be8287b8e9 100644 --- a/Sources/BraintreeCore/BTAppContextSwitcher.swift +++ b/Sources/BraintreeCore/BTAppContextSwitcher.swift @@ -14,7 +14,21 @@ import UIKit /// The URL scheme to return to this app after switching to another app or opening a SFSafariViewController. /// This URL scheme must be registered as a URL Type in the app's info.plist, and it must start with the app's bundle ID. /// - Note: This property should only be used for the Venmo flow. - public var returnURLScheme: String = "" + @available( + *, + deprecated, + message: "returnURLScheme is deprecated and will be removed in a future version. Use BTVenmoClient(apiClient:universalLink:)." + ) + public var returnURLScheme: String { + get { _returnURLScheme } + set { _returnURLScheme = newValue } + } + + /// :nodoc: This method is exposed for internal Braintree use only. Do not use. It is not covered by Semantic Versioning and may change or be removed at any time. + /// Property for `returnURLScheme`. Created to avoid deprecation warnings upon accessing + /// `returnURLScheme` directly within our SDK. Use this value instead. + // swiftlint:disable:next identifier_name + public var _returnURLScheme: String = "" // MARK: - Private Properties diff --git a/Sources/BraintreeVenmo/BTVenmoClient.swift b/Sources/BraintreeVenmo/BTVenmoClient.swift index 2dbd943932..7193bb8758 100644 --- a/Sources/BraintreeVenmo/BTVenmoClient.swift +++ b/Sources/BraintreeVenmo/BTVenmoClient.swift @@ -81,7 +81,7 @@ import BraintreeCore public func tokenize(_ request: BTVenmoRequest, completion: @escaping (BTVenmoAccountNonce?, Error?) -> Void) { linkType = request.fallbackToWeb ? .universal : .deeplink apiClient.sendAnalyticsEvent(BTVenmoAnalytics.tokenizeStarted, isVaultRequest: shouldVault, linkType: linkType) - let returnURLScheme = BTAppContextSwitcher.sharedInstance.returnURLScheme + let returnURLScheme = BTAppContextSwitcher.sharedInstance._returnURLScheme if returnURLScheme.isEmpty { NSLog( From 6b90aee361f036e80cdfb2bca4c3e1771e773009 Mon Sep 17 00:00:00 2001 From: Jax DesMarais-Leder Date: Tue, 22 Oct 2024 09:58:29 -0500 Subject: [PATCH 17/17] update for swiftlint --- Sources/BraintreeCore/BTAppContextSwitcher.swift | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Sources/BraintreeCore/BTAppContextSwitcher.swift b/Sources/BraintreeCore/BTAppContextSwitcher.swift index be8287b8e9..1ea5738eff 100644 --- a/Sources/BraintreeCore/BTAppContextSwitcher.swift +++ b/Sources/BraintreeCore/BTAppContextSwitcher.swift @@ -24,11 +24,12 @@ import UIKit set { _returnURLScheme = newValue } } + // swiftlint:disable identifier_name /// :nodoc: This method is exposed for internal Braintree use only. Do not use. It is not covered by Semantic Versioning and may change or be removed at any time. /// Property for `returnURLScheme`. Created to avoid deprecation warnings upon accessing /// `returnURLScheme` directly within our SDK. Use this value instead. - // swiftlint:disable:next identifier_name public var _returnURLScheme: String = "" + // swiftlint:enable identifier_name // MARK: - Private Properties