From 7d817d1fa259ac1e2a97c076eeb987c0ceb52e02 Mon Sep 17 00:00:00 2001 From: Alex Guretzki Date: Wed, 4 Dec 2024 14:30:57 +0100 Subject: [PATCH 01/10] allow setting maxIssuerNumber in drop-in configuration --- AdyenActions/AdyenActionComponent.swift | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/AdyenActions/AdyenActionComponent.swift b/AdyenActions/AdyenActionComponent.swift index 68d7d06485..398304e4be 100644 --- a/AdyenActions/AdyenActionComponent.swift +++ b/AdyenActions/AdyenActionComponent.swift @@ -72,20 +72,35 @@ public final class AdyenActionComponent: ActionComponent, ActionHandlingComponen public struct Twint { /// The callback app scheme invoked once the Twint app is done with the payment + /// + /// - Important: This value is required to only provide the scheme, + /// without a host/path/.... (e.g. "my-app", not a url "my-app://...") public var callbackAppScheme: String + /// The issuer number of the highest scheme you listed under `LSApplicationQueriesSchemes`. + /// E.g. pass 39, if you listed all schemes from "twint-issuer1" up to and including "twint-issuer39". The value is clamped between 0 and 39. + /// + /// - Important: All apps above "twint-issuer39" will always be returned if one of these apps is installed. For this to work, `LSApplicationQueriesSchemes` must include "twint-extended". + /// If you configure any `maxIssuerNumber` below 39, the result will always contain all apps above `maxIssuerNumber` up to and including 39, even if none of them are installed. + /// Additionally, if the fetch fails and the cache is empty, none of these apps will be found when probing. + public var maxIssuerNumber: Int + /// Initializes a new instance /// /// - Parameter callbackAppScheme: The callback app scheme invoked once the Twint app is done with the payment /// /// - Important: The value of ``callbackAppScheme`` is required to only provide the scheme, /// without a host/path/... (e.g. "my-app", not a url "my-app://...") - public init(callbackAppScheme: String) { + public init( + callbackAppScheme: String, + maxIssuerNumber: Int = .max + ) { if !Self.isCallbackSchemeValid(callbackAppScheme) { AdyenAssertion.assertionFailure(message: "Format of provided callbackAppScheme '\(callbackAppScheme)' is incorrect.") } self.callbackAppScheme = callbackAppScheme + self.maxIssuerNumber = maxIssuerNumber } /// Validating whether or not the provided `callbackAppScheme` only contains a scheme @@ -265,6 +280,7 @@ public final class AdyenActionComponent: ActionComponent, ActionHandlingComponen configuration: .init( style: configuration.style.awaitComponentStyle, callbackAppScheme: twintConfiguration.callbackAppScheme, + maxIssuerNumber: twintConfiguration.maxIssuerNumber, localizationParameters: configuration.localizationParameters ) ) From 1cd676f5702d3f26b7c7c65f3e2c6e18fd82ce95 Mon Sep 17 00:00:00 2001 From: Alex Guretzki Date: Fri, 6 Dec 2024 14:18:31 +0100 Subject: [PATCH 02/10] Using static framework to not interfere with other TwintSDK versions --- Package.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Package.swift b/Package.swift index add0fb41ce..31f8d51e63 100644 --- a/Package.swift +++ b/Package.swift @@ -182,7 +182,7 @@ let package = Package( ), .binaryTarget( name: "TwintSDK", - path: "XCFramework/Dynamic/TwintSDK.xcframework" + path: "XCFramework/Static/TwintSDK.xcframework" ), .target( name: "AdyenDelegatedAuthentication", From 58ceab3ef3e3734a6223a7392a1da1d865640802 Mon Sep 17 00:00:00 2001 From: Alex Guretzki Date: Tue, 10 Dec 2024 11:40:35 +0100 Subject: [PATCH 03/10] Reverting Static TwintSDK change --- Package.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Package.swift b/Package.swift index 31f8d51e63..add0fb41ce 100644 --- a/Package.swift +++ b/Package.swift @@ -182,7 +182,7 @@ let package = Package( ), .binaryTarget( name: "TwintSDK", - path: "XCFramework/Static/TwintSDK.xcframework" + path: "XCFramework/Dynamic/TwintSDK.xcframework" ), .target( name: "AdyenDelegatedAuthentication", From 71c71d0d29a78d560349206a66f70400c9a58cc9 Mon Sep 17 00:00:00 2001 From: Alex Guretzki Date: Tue, 10 Dec 2024 11:41:28 +0100 Subject: [PATCH 04/10] re-casting to TWAppConfiguration --- AdyenActions/Components/SDK/Twint+Injectable.swift | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/AdyenActions/Components/SDK/Twint+Injectable.swift b/AdyenActions/Components/SDK/Twint+Injectable.swift index 4827ed06fb..ef171e9e81 100644 --- a/AdyenActions/Components/SDK/Twint+Injectable.swift +++ b/AdyenActions/Components/SDK/Twint+Injectable.swift @@ -16,7 +16,8 @@ import Foundation completion: @escaping ([TWAppConfiguration]) -> Void ) { Twint.fetchInstalledAppConfigurations(withMaxIssuerNumber: maxIssuerNumber) { configurations in - completion(configurations ?? []) + let configurationObjects = (configurations as [NSObject]?) ?? [] + completion(configurationObjects.compactMap { $0 as? TWAppConfiguration }) } } @@ -55,7 +56,7 @@ import Foundation cancelHandler: @escaping () -> Void ) -> UIAlertController? { Twint.controller( - for: installedAppConfigurations.map { $0 }, + for: installedAppConfigurations, selectedConfigurationHandler: { selectionHandler($0) }, cancelHandler: { cancelHandler() } ) From da44dfe5cf510e64ac2fdcf7cdcd4d601b781b98 Mon Sep 17 00:00:00 2001 From: Alex Guretzki Date: Tue, 10 Dec 2024 11:42:59 +0100 Subject: [PATCH 05/10] removed useless mapping --- AdyenActions/Components/SDK/Twint+Injectable.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/AdyenActions/Components/SDK/Twint+Injectable.swift b/AdyenActions/Components/SDK/Twint+Injectable.swift index 4827ed06fb..b938364224 100644 --- a/AdyenActions/Components/SDK/Twint+Injectable.swift +++ b/AdyenActions/Components/SDK/Twint+Injectable.swift @@ -55,7 +55,7 @@ import Foundation cancelHandler: @escaping () -> Void ) -> UIAlertController? { Twint.controller( - for: installedAppConfigurations.map { $0 }, + for: installedAppConfigurations, selectedConfigurationHandler: { selectionHandler($0) }, cancelHandler: { cancelHandler() } ) From 7b9c68ee0a5c6f55b33b10e2327c9c172080029a Mon Sep 17 00:00:00 2001 From: Alex Guretzki Date: Wed, 11 Dec 2024 13:12:00 +0100 Subject: [PATCH 06/10] Adding documentation --- .../Components/SDK/Twint+Injectable.swift | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/AdyenActions/Components/SDK/Twint+Injectable.swift b/AdyenActions/Components/SDK/Twint+Injectable.swift index ef171e9e81..c11b88c0f7 100644 --- a/AdyenActions/Components/SDK/Twint+Injectable.swift +++ b/AdyenActions/Components/SDK/Twint+Injectable.swift @@ -11,13 +11,13 @@ import Foundation #if canImport(TwintSDK) extension Twint { + @objc func fetchInstalledAppConfigurations( maxIssuerNumber: Int, completion: @escaping ([TWAppConfiguration]) -> Void ) { Twint.fetchInstalledAppConfigurations(withMaxIssuerNumber: maxIssuerNumber) { configurations in - let configurationObjects = (configurations as [NSObject]?) ?? [] - completion(configurationObjects.compactMap { $0 as? TWAppConfiguration }) + completion(Self.reCastedAppConfigurations(from: configurations)) } } @@ -68,5 +68,17 @@ import Foundation ) -> Bool { Twint.handleOpen(url, withResponseHandler: responseHandler) } + + /// Re-casting **`[TWAppConfiguration]`** into **`[TWAppConfiguration]`** via **`[NSObject]`** + /// + /// - **Background:** If different SDKs that use the **TwintSDK** internally are imported by an app + /// it can lead to the system providing a **TwintSDK** class of the other SDK resulting in a runtime crash when type checking. + /// - **Solution:** To work around this we implicitly cast the `[TWAppConfiguration]` to an `[NSObject]` + /// and then explicitly back to `[TWAppConfiguration]` which makes sure the correctly loaded class is used. + /// + /// - SeeAlso: [Github Issue](https://github.com/Adyen/adyen-ios/issues/1902) + private static func reCastedAppConfigurations(from configurations: [NSObject]?) -> [TWAppConfiguration] { + configurations?.compactMap { $0 as? TWAppConfiguration } ?? [] + } } #endif From 07ca50a44a4d3360e22633485b266211fa9b55b9 Mon Sep 17 00:00:00 2001 From: Alex Guretzki Date: Wed, 11 Dec 2024 13:18:11 +0100 Subject: [PATCH 07/10] better documentation --- AdyenActions/Components/SDK/Twint+Injectable.swift | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/AdyenActions/Components/SDK/Twint+Injectable.swift b/AdyenActions/Components/SDK/Twint+Injectable.swift index c11b88c0f7..fdbd715e49 100644 --- a/AdyenActions/Components/SDK/Twint+Injectable.swift +++ b/AdyenActions/Components/SDK/Twint+Injectable.swift @@ -72,11 +72,9 @@ import Foundation /// Re-casting **`[TWAppConfiguration]`** into **`[TWAppConfiguration]`** via **`[NSObject]`** /// /// - **Background:** If different SDKs that use the **TwintSDK** internally are imported by an app - /// it can lead to the system providing a **TwintSDK** class of the other SDK resulting in a runtime crash when type checking. + /// it can lead to the system providing a **TwintSDK** class of the other SDK resulting in a runtime crash when type checking. See: [Github Issue](https://github.com/Adyen/adyen-ios/issues/1902) /// - **Solution:** To work around this we implicitly cast the `[TWAppConfiguration]` to an `[NSObject]` /// and then explicitly back to `[TWAppConfiguration]` which makes sure the correctly loaded class is used. - /// - /// - SeeAlso: [Github Issue](https://github.com/Adyen/adyen-ios/issues/1902) private static func reCastedAppConfigurations(from configurations: [NSObject]?) -> [TWAppConfiguration] { configurations?.compactMap { $0 as? TWAppConfiguration } ?? [] } From c452d74605a0f5ce3eb343c3ed80bf5f5b2739c0 Mon Sep 17 00:00:00 2001 From: Alex Guretzki Date: Wed, 11 Dec 2024 13:23:19 +0100 Subject: [PATCH 08/10] fixing linter warning --- AdyenActions/Components/SDK/Twint+Injectable.swift | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/AdyenActions/Components/SDK/Twint+Injectable.swift b/AdyenActions/Components/SDK/Twint+Injectable.swift index fdbd715e49..07c215d420 100644 --- a/AdyenActions/Components/SDK/Twint+Injectable.swift +++ b/AdyenActions/Components/SDK/Twint+Injectable.swift @@ -72,7 +72,8 @@ import Foundation /// Re-casting **`[TWAppConfiguration]`** into **`[TWAppConfiguration]`** via **`[NSObject]`** /// /// - **Background:** If different SDKs that use the **TwintSDK** internally are imported by an app - /// it can lead to the system providing a **TwintSDK** class of the other SDK resulting in a runtime crash when type checking. See: [Github Issue](https://github.com/Adyen/adyen-ios/issues/1902) + /// it can lead to the system providing a **TwintSDK** class of the other SDK resulting in a runtime crash when type checking. + /// See: [Github Issue](https://github.com/Adyen/adyen-ios/issues/1902) /// - **Solution:** To work around this we implicitly cast the `[TWAppConfiguration]` to an `[NSObject]` /// and then explicitly back to `[TWAppConfiguration]` which makes sure the correctly loaded class is used. private static func reCastedAppConfigurations(from configurations: [NSObject]?) -> [TWAppConfiguration] { From 912d4ec34adbe5c2746b7cd57b40fba3b08c6606 Mon Sep 17 00:00:00 2001 From: Alex Guretzki Date: Wed, 11 Dec 2024 13:42:18 +0100 Subject: [PATCH 09/10] fixing spell checker warnings --- AdyenActions/Components/SDK/Twint+Injectable.swift | 4 ++-- spell-check-word-allow-list.yaml | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/AdyenActions/Components/SDK/Twint+Injectable.swift b/AdyenActions/Components/SDK/Twint+Injectable.swift index 07c215d420..f36cbe0397 100644 --- a/AdyenActions/Components/SDK/Twint+Injectable.swift +++ b/AdyenActions/Components/SDK/Twint+Injectable.swift @@ -71,8 +71,8 @@ import Foundation /// Re-casting **`[TWAppConfiguration]`** into **`[TWAppConfiguration]`** via **`[NSObject]`** /// - /// - **Background:** If different SDKs that use the **TwintSDK** internally are imported by an app - /// it can lead to the system providing a **TwintSDK** class of the other SDK resulting in a runtime crash when type checking. + /// - **Background:** If different SDKs that use the **TwintSDK** internally are imported by an app, + /// it can lead to the system providing a **TwintSDK** class of the other SDK, resulting in a runtime crash when type checking. /// See: [Github Issue](https://github.com/Adyen/adyen-ios/issues/1902) /// - **Solution:** To work around this we implicitly cast the `[TWAppConfiguration]` to an `[NSObject]` /// and then explicitly back to `[TWAppConfiguration]` which makes sure the correctly loaded class is used. diff --git a/spell-check-word-allow-list.yaml b/spell-check-word-allow-list.yaml index 4538060f76..13b3845560 100644 --- a/spell-check-word-allow-list.yaml +++ b/spell-check-word-allow-list.yaml @@ -207,3 +207,4 @@ whiteList: - youtrack - itau - primeiropay + - SDKs From 38f8eca5b0d096cc9a7fdc16ab438cc8a7f8bafb Mon Sep 17 00:00:00 2001 From: Alex Guretzki Date: Wed, 11 Dec 2024 14:18:49 +0100 Subject: [PATCH 10/10] adding ks to spell check allow list --- spell-check-word-allow-list.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/spell-check-word-allow-list.yaml b/spell-check-word-allow-list.yaml index 13b3845560..d3930bbd62 100644 --- a/spell-check-word-allow-list.yaml +++ b/spell-check-word-allow-list.yaml @@ -208,3 +208,4 @@ whiteList: - itau - primeiropay - SDKs + - ks