diff --git a/Example/README.md b/Example/README.md index ed01dcc35..3aebf1fbf 100644 --- a/Example/README.md +++ b/Example/README.md @@ -4,7 +4,7 @@ Project demonstrates multiple flows that ProcessOut framework is capable of. ## Requirements -- A recent version of Xcode (tested with 16.0) +- Xcode 26.2 or later - [Homebrew](https://brew.sh) package manager ### Installation diff --git a/README.md b/README.md index f95bb96aa..7820ae2ce 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,7 @@ Get started with our ProcessOut [documentation](https://docs.processout.com/) or - [ProcessOut](https://swiftpackageindex.com/processout/processout-ios/documentation/processout) - [ProcessOutCheckout3DS](https://swiftpackageindex.com/processout/processout-ios/documentation/processoutcheckout3ds) +- [ProcessOutCoreUI](https://swiftpackageindex.com/processout/processout-ios/documentation/processoutcoreui) - [ProcessOutNetcetera3DS](https://swiftpackageindex.com/processout/processout-ios/documentation/processoutnetcetera3ds) - [ProcessOutUI](https://swiftpackageindex.com/processout/processout-ios/documentation/processoutui) @@ -17,6 +18,7 @@ Get started with our ProcessOut [documentation](https://docs.processout.com/) or | ---------------------- | ---------------------------------------------------------------------------- | | ProcessOut | Allows to interact with ProcessOut API and provides a UI to handle payments. | | ProcessOutCheckout3DS | Integration with Checkout.com 3D Secure (3DS) mobile SDK. | +| ProcessOutCoreUI | Shared styling primitives used by ProcessOutUI. | | ProcessOutNetcetera3DS | Integration with Netcetera 3D Secure (3DS) mobile SDK. | | ProcessOutUI | ProcessOut prebuilt UI to handle payments. | @@ -32,7 +34,7 @@ We welcome contributions of any kind including new features, bug fixes, and gene ### Development requirements -- A recent version of Xcode (tested with 16.0) +- Xcode 26.2 or later - [Homebrew](https://brew.sh/) package manager ### Installation diff --git a/Sources/ProcessOut/Sources/Core/Utils/POTypedRepresentation.swift b/Sources/ProcessOut/Sources/Core/Utils/POTypedRepresentation.swift index 2c034f3bc..1b9cb906e 100644 --- a/Sources/ProcessOut/Sources/Core/Utils/POTypedRepresentation.swift +++ b/Sources/ProcessOut/Sources/Core/Utils/POTypedRepresentation.swift @@ -17,7 +17,6 @@ public struct POTypedRepresentation { self._wrappedValue = wrappedValue } - @available(*, deprecated, message: "Use typed representation accessible via projectedValue.typed instead.") public var wrappedValue: Wrapped { get { _wrappedValue } set { _wrappedValue = newValue } diff --git a/Sources/ProcessOut/Sources/Repositories/Cards/Requests/POCardTokenizationRequest.swift b/Sources/ProcessOut/Sources/Repositories/Cards/Requests/POCardTokenizationRequest.swift index 79abfd34e..4672af8cb 100644 --- a/Sources/ProcessOut/Sources/Repositories/Cards/Requests/POCardTokenizationRequest.swift +++ b/Sources/ProcessOut/Sources/Repositories/Cards/Requests/POCardTokenizationRequest.swift @@ -29,6 +29,7 @@ public struct POCardTokenizationRequest: Codable, Sendable { public let contact: POContact? /// Preferred scheme defined by the Customer. + @available(*, deprecated, message: "Use $preferredScheme.typed instead.") @POTypedRepresentation public private(set) var preferredScheme: String? diff --git a/Sources/ProcessOut/Sources/Repositories/Cards/Requests/POCardUpdateRequest.swift b/Sources/ProcessOut/Sources/Repositories/Cards/Requests/POCardUpdateRequest.swift index bd9e30602..b36d33f0b 100644 --- a/Sources/ProcessOut/Sources/Repositories/Cards/Requests/POCardUpdateRequest.swift +++ b/Sources/ProcessOut/Sources/Repositories/Cards/Requests/POCardUpdateRequest.swift @@ -17,6 +17,7 @@ public struct POCardUpdateRequest: Codable, Sendable { /// Preferred scheme defined by the Customer. This gets priority when processing the Transaction. /// Pass `nil` to keep existing value. + @available(*, deprecated, message: "Use $preferredScheme.typed instead.") @POTypedRepresentation public private(set) var preferredScheme: String? diff --git a/Sources/ProcessOut/Sources/Repositories/Cards/Responses/POCard.swift b/Sources/ProcessOut/Sources/Repositories/Cards/Responses/POCard.swift index 595ccca8a..162a79380 100644 --- a/Sources/ProcessOut/Sources/Repositories/Cards/Responses/POCard.swift +++ b/Sources/ProcessOut/Sources/Repositories/Cards/Responses/POCard.swift @@ -18,14 +18,17 @@ public struct POCard: Codable, Hashable, Sendable { public let projectId: String /// Scheme of the card. + @available(*, deprecated, message: "Use $scheme.typed instead.") @POTypedRepresentation public private(set) var scheme: String /// Co-scheme of the card, such as Carte Bancaire. + @available(*, deprecated, message: "Use $coScheme.typed instead.") @POTypedRepresentation public private(set) var coScheme: String? /// Preferred scheme defined by the Customer. + @available(*, deprecated, message: "Use $preferredScheme.typed instead.") @POTypedRepresentation public private(set) var preferredScheme: String? @@ -60,6 +63,7 @@ public struct POCard: Codable, Hashable, Sendable { public let expYear: Int /// CVC check status. + @available(*, deprecated, message: "Use $cvcCheck.typed instead.") @POTypedRepresentation public var cvcCheck: String diff --git a/Sources/ProcessOut/Sources/Repositories/Cards/Responses/POCardIssuerInformation.swift b/Sources/ProcessOut/Sources/Repositories/Cards/Responses/POCardIssuerInformation.swift index ce69c8268..501f7cff4 100644 --- a/Sources/ProcessOut/Sources/Repositories/Cards/Responses/POCardIssuerInformation.swift +++ b/Sources/ProcessOut/Sources/Repositories/Cards/Responses/POCardIssuerInformation.swift @@ -9,10 +9,12 @@ public struct POCardIssuerInformation: Codable, Sendable { /// Scheme of the card. + @available(*, deprecated, message: "Use $scheme.typed instead.") @POTypedRepresentation public private(set) var scheme: String /// Co-scheme of the card, such as Carte Bancaire. + @available(*, deprecated, message: "Use $coScheme.typed instead.") @POTypedRepresentation public private(set) var coScheme: String? diff --git a/Sources/ProcessOut/Sources/Repositories/CustomerTokens/Requests/POAssignCustomerTokenRequest.swift b/Sources/ProcessOut/Sources/Repositories/CustomerTokens/Requests/POAssignCustomerTokenRequest.swift index 6383e8518..125686687 100644 --- a/Sources/ProcessOut/Sources/Repositories/CustomerTokens/Requests/POAssignCustomerTokenRequest.swift +++ b/Sources/ProcessOut/Sources/Repositories/CustomerTokens/Requests/POAssignCustomerTokenRequest.swift @@ -23,6 +23,7 @@ public struct POAssignCustomerTokenRequest: Codable, Sendable { // sourcery: Aut public let source: String /// Card scheme or co-scheme that should get priority if it is available. + @available(*, deprecated, message: "Use $preferredScheme.typed instead.") @POTypedRepresentation public private(set) var preferredScheme: String? diff --git a/Sources/ProcessOut/Sources/Repositories/CustomerTokens/Responses/POCustomerToken.swift b/Sources/ProcessOut/Sources/Repositories/CustomerTokens/Responses/POCustomerToken.swift index 5b1caf0a3..b2aa01cef 100644 --- a/Sources/ProcessOut/Sources/Repositories/CustomerTokens/Responses/POCustomerToken.swift +++ b/Sources/ProcessOut/Sources/Repositories/CustomerTokens/Responses/POCustomerToken.swift @@ -32,6 +32,7 @@ public struct POCustomerToken: Identifiable, Codable, Sendable { public let invoiceId: String? /// Source used to create the token (which will usually be a Card). + @available(*, deprecated, message: "Use $type.typed instead.") @POTypedRepresentation public private(set) var type: String diff --git a/Sources/ProcessOut/Sources/Repositories/Invoices/Requests/POInvoiceAuthorizationRequest.swift b/Sources/ProcessOut/Sources/Repositories/Invoices/Requests/POInvoiceAuthorizationRequest.swift index c333a4a66..080438759 100644 --- a/Sources/ProcessOut/Sources/Repositories/Invoices/Requests/POInvoiceAuthorizationRequest.swift +++ b/Sources/ProcessOut/Sources/Repositories/Invoices/Requests/POInvoiceAuthorizationRequest.swift @@ -30,6 +30,7 @@ public struct POInvoiceAuthorizationRequest: Codable, Sendable { // sourcery: Au public let enableThreeDS2 = true // sourcery:coding: key="enable_three_d_s_2" /// Card scheme or co-scheme that should get priority if it is available. + @available(*, deprecated, message: "Use $preferredScheme.typed instead.") @POTypedRepresentation public private(set) var preferredScheme: String? diff --git a/Sources/ProcessOut/Sources/Services/CustomerActions/Requests/PO3DS2Configuration.swift b/Sources/ProcessOut/Sources/Services/CustomerActions/Requests/PO3DS2Configuration.swift index 5ccb28227..a309932ab 100644 --- a/Sources/ProcessOut/Sources/Services/CustomerActions/Requests/PO3DS2Configuration.swift +++ b/Sources/ProcessOut/Sources/Services/CustomerActions/Requests/PO3DS2Configuration.swift @@ -21,6 +21,7 @@ public struct PO3DS2Configuration: Codable, Hashable, Sendable { public let directoryServerTransactionId: String /// Card scheme from the card used to initiate the payment. + @available(*, deprecated, message: "Use $scheme.typed() instead.") @POTypedRepresentation public private(set) var scheme: PO3DS2ConfigurationCardScheme? diff --git a/Sources/ProcessOut/Sources/Services/CustomerTokens/DefaultCustomerTokensService.swift b/Sources/ProcessOut/Sources/Services/CustomerTokens/DefaultCustomerTokensService.swift index 364624a0c..c30e1c3fd 100644 --- a/Sources/ProcessOut/Sources/Services/CustomerTokens/DefaultCustomerTokensService.swift +++ b/Sources/ProcessOut/Sources/Services/CustomerTokens/DefaultCustomerTokensService.swift @@ -102,7 +102,7 @@ private extension POAssignCustomerTokenRequest { // swiftlint:disable:this no_ex customerId: customerId, tokenId: tokenId, source: newSource ?? source, - preferredScheme: preferredScheme, + preferredScheme: $preferredScheme.typed?.rawValue, verify: verify, invoiceId: invoiceId, thirdPartySdkVersion: newSdkVersion ?? thirdPartySdkVersion, diff --git a/Sources/ProcessOut/Sources/UI/Modules/NativeAlternativePaymentMethod/Interactor/PONativeAlternativePaymentMethodDelegate.swift b/Sources/ProcessOut/Sources/UI/Modules/NativeAlternativePaymentMethod/Interactor/PONativeAlternativePaymentMethodDelegate.swift index bf7e6041f..a5909654d 100644 --- a/Sources/ProcessOut/Sources/UI/Modules/NativeAlternativePaymentMethod/Interactor/PONativeAlternativePaymentMethodDelegate.swift +++ b/Sources/ProcessOut/Sources/UI/Modules/NativeAlternativePaymentMethod/Interactor/PONativeAlternativePaymentMethodDelegate.swift @@ -42,11 +42,17 @@ public protocol PONativeAlternativePaymentMethodDelegate: AnyObject, Sendable { extension PONativeAlternativePaymentMethodDelegate { + #if hasAttribute(diagnose) + @diagnose(DeprecatedDeclaration, as: ignored) + #endif @MainActor public func nativeAlternativePayment(didEmitEvent event: PONativeAlternativePaymentMethodEvent) { nativeAlternativePaymentMethodDidEmitEvent(event) } + #if hasAttribute(diagnose) + @diagnose(DeprecatedDeclaration, as: ignored) + #endif @MainActor public func nativeAlternativePayment( defaultValuesFor parameters: [PONativeAlternativePaymentMethodParameter] diff --git a/Sources/ProcessOutCheckout3DS/Sources/Extensions/Checkout3DS+Sendable.swift b/Sources/ProcessOutCheckout3DS/Sources/Extensions/Checkout3DS+Sendable.swift index fd3091ff1..0e352d867 100644 --- a/Sources/ProcessOutCheckout3DS/Sources/Extensions/Checkout3DS+Sendable.swift +++ b/Sources/ProcessOutCheckout3DS/Sources/Extensions/Checkout3DS+Sendable.swift @@ -21,6 +21,3 @@ extension AuthenticationResult: @retroactive @unchecked Sendable { } /// Marks `ChallengeParameters` as `Sendable` retroactively. extension ChallengeParameters: @retroactive @unchecked Sendable { } - -/// Marks `AuthenticationError` as `Sendable` retroactively. -extension AuthenticationError: @retroactive @unchecked Sendable { } diff --git a/Sources/ProcessOutCheckout3DS/Sources/Service/POCheckout3DSServiceDelegate.swift b/Sources/ProcessOutCheckout3DS/Sources/Service/POCheckout3DSServiceDelegate.swift index 090bd8229..519251c6e 100644 --- a/Sources/ProcessOutCheckout3DS/Sources/Service/POCheckout3DSServiceDelegate.swift +++ b/Sources/ProcessOutCheckout3DS/Sources/Service/POCheckout3DSServiceDelegate.swift @@ -93,6 +93,9 @@ public protocol POCheckout3DSServiceDelegate: AnyObject, Sendable { /// Provides default implementations to ensure backward compatibility. extension POCheckout3DSServiceDelegate { + #if hasAttribute(diagnose) + @diagnose(DeprecatedDeclaration, as: ignored) + #endif @MainActor public func checkout3DSService( _ service: POCheckout3DSService, @@ -101,6 +104,9 @@ extension POCheckout3DSServiceDelegate { willCreateAuthenticationRequest(configuration: configuration) } + #if hasAttribute(diagnose) + @diagnose(DeprecatedDeclaration, as: ignored) + #endif @MainActor public func checkout3DSService( _ service: POCheckout3DSService, @@ -109,6 +115,9 @@ extension POCheckout3DSServiceDelegate { configuration(with: parameters) } + #if hasAttribute(diagnose) + @diagnose(DeprecatedDeclaration, as: ignored) + #endif @MainActor public func checkout3DSService( _ service: POCheckout3DSService, shouldContinueWith warnings: Set @@ -118,6 +127,9 @@ extension POCheckout3DSServiceDelegate { } } + #if hasAttribute(diagnose) + @diagnose(DeprecatedDeclaration, as: ignored) + #endif @MainActor public func checkout3DSService( _ service: POCheckout3DSService, @@ -126,6 +138,9 @@ extension POCheckout3DSServiceDelegate { didCreateAuthenticationRequest(result: result) } + #if hasAttribute(diagnose) + @diagnose(DeprecatedDeclaration, as: ignored) + #endif @MainActor public func checkout3DSService( _ service: POCheckout3DSService, willPerformChallengeWith parameters: PO3DS2ChallengeParameters @@ -133,6 +148,9 @@ extension POCheckout3DSServiceDelegate { willHandle(challenge: parameters) } + #if hasAttribute(diagnose) + @diagnose(DeprecatedDeclaration, as: ignored) + #endif @MainActor public func checkout3DSService( _ service: POCheckout3DSService, didPerformChallenge result: Result diff --git a/Sources/ProcessOutUI/Sources/Modules/CardScanner/Interactor/DefaultCardScannerInteractor.swift b/Sources/ProcessOutUI/Sources/Modules/CardScanner/Interactor/DefaultCardScannerInteractor.swift index a693df98b..b1605db9c 100644 --- a/Sources/ProcessOutUI/Sources/Modules/CardScanner/Interactor/DefaultCardScannerInteractor.swift +++ b/Sources/ProcessOutUI/Sources/Modules/CardScanner/Interactor/DefaultCardScannerInteractor.swift @@ -5,7 +5,7 @@ // Created by Andrii Vysotskyi on 25.11.2024. // -import class UIKit.UIApplication +import UIKit import AVFoundation @_spi(PO) import ProcessOut diff --git a/Sources/ProcessOutUI/Sources/Modules/CardTokenization/Delegate/POCardTokenizationDelegate.swift b/Sources/ProcessOutUI/Sources/Modules/CardTokenization/Delegate/POCardTokenizationDelegate.swift index 28bb25da3..bd1552165 100644 --- a/Sources/ProcessOutUI/Sources/Modules/CardTokenization/Delegate/POCardTokenizationDelegate.swift +++ b/Sources/ProcessOutUI/Sources/Modules/CardTokenization/Delegate/POCardTokenizationDelegate.swift @@ -74,11 +74,17 @@ extension POCardTokenizationDelegate { // Ignored } + #if hasAttribute(diagnose) + @diagnose(DeprecatedDeclaration, as: ignored) + #endif @MainActor public func cardTokenization(preferredSchemeWith issuerInformation: POCardIssuerInformation) -> POCardScheme? { preferredScheme(issuerInformation: issuerInformation).map(POCardScheme.init) } + #if hasAttribute(diagnose) + @diagnose(DeprecatedDeclaration, as: ignored) + #endif @MainActor public func cardTokenization(didTokenizeCard card: POCard, shouldSaveCard: Bool) async throws { try await processTokenizedCard(card: card) @@ -99,7 +105,7 @@ extension POCardTokenizationDelegate { @MainActor public func preferredScheme(issuerInformation: POCardIssuerInformation) -> String? { - issuerInformation.scheme + issuerInformation.$scheme.typed.rawValue } @MainActor diff --git a/Sources/ProcessOutUI/Sources/Modules/CardUpdate/Delegate/POCardUpdateInformation.swift b/Sources/ProcessOutUI/Sources/Modules/CardUpdate/Delegate/POCardUpdateInformation.swift index c52b52dd3..31596a1b1 100644 --- a/Sources/ProcessOutUI/Sources/Modules/CardUpdate/Delegate/POCardUpdateInformation.swift +++ b/Sources/ProcessOutUI/Sources/Modules/CardUpdate/Delegate/POCardUpdateInformation.swift @@ -22,14 +22,17 @@ public struct POCardUpdateInformation: Sendable { public let iin: String? /// Scheme of the card. + @available(*, deprecated, message: "Use $scheme.typed instead.") @POTypedRepresentation public private(set) var scheme: String? /// Co-scheme of the card, such as Carte Bancaire. + @available(*, deprecated, message: "Use $coScheme.typed instead.") @POTypedRepresentation public private(set) var coScheme: String? /// Preferred scheme previously selected by customer if any. + @available(*, deprecated, message: "Use $preferredScheme.typed instead.") @POTypedRepresentation public private(set) var preferredScheme: String? diff --git a/Sources/ProcessOutUI/Sources/Modules/NativeAlternativePayment/Interactor/NativeAlternativePaymentDefaultInteractor.swift b/Sources/ProcessOutUI/Sources/Modules/NativeAlternativePayment/Interactor/NativeAlternativePaymentDefaultInteractor.swift index 50b2d1f12..e137686fb 100644 --- a/Sources/ProcessOutUI/Sources/Modules/NativeAlternativePayment/Interactor/NativeAlternativePaymentDefaultInteractor.swift +++ b/Sources/ProcessOutUI/Sources/Modules/NativeAlternativePayment/Interactor/NativeAlternativePaymentDefaultInteractor.swift @@ -712,6 +712,8 @@ final class NativeAlternativePaymentDefaultInteractor: return .group(try await resolve(group: group)) case .unknown: return nil + @unknown default: + return nil } return nil } @@ -918,6 +920,9 @@ final class NativeAlternativePaymentDefaultInteractor: case .unknown: assertionFailure("Unable to validate unknown parameter.") return nil + @unknown default: + assertionFailure("Unable to validate unknown parameter.") + return nil } validation = .init( name: parameter.specification.key, diff --git a/Tests/ProcessOutTests/Sources/Integration/CardsServiceTests.swift b/Tests/ProcessOutTests/Sources/Integration/CardsServiceTests.swift index 796966c8e..705900c1d 100644 --- a/Tests/ProcessOutTests/Sources/Integration/CardsServiceTests.swift +++ b/Tests/ProcessOutTests/Sources/Integration/CardsServiceTests.swift @@ -110,7 +110,7 @@ struct CardsServiceTests { let card = try await sut.tokenize(request: request) // Then - #expect(card.preferredScheme == request.preferredScheme) + #expect(card.$preferredScheme.typed == request.$preferredScheme.typed) } // MARK: - Private Properties diff --git a/project.yml b/project.yml index bae3e60a9..0c5b0e160 100644 --- a/project.yml +++ b/project.yml @@ -78,7 +78,7 @@ targets: ProcessOutTests: type: bundle.unit-test platform: iOS - deploymentTarget: "16.0" + deploymentTarget: "17.0" settings: TARGET_ROOT: $(PROJECT_DIR)/Tests/ProcessOutTests dependencies: @@ -87,7 +87,7 @@ targets: ProcessOutUITests: type: bundle.unit-test platform: iOS - deploymentTarget: "16.0" + deploymentTarget: "17.0" settings: TARGET_ROOT: $(PROJECT_DIR)/Tests/ProcessOutUITests dependencies: @@ -128,7 +128,7 @@ targets: ProcessOutCheckout3DSTests: type: bundle.unit-test platform: iOS - deploymentTarget: "16.0" + deploymentTarget: "17.0" settings: TARGET_ROOT: $(PROJECT_DIR)/Tests/ProcessOutCheckout3DSTests dependencies: @@ -137,7 +137,7 @@ targets: ProcessOutNetcetera3DSTests: type: bundle.unit-test platform: iOS - deploymentTarget: "16.0" + deploymentTarget: "17.0" settings: TARGET_ROOT: $(PROJECT_DIR)/Tests/ProcessOutNetcetera3DSTests dependencies: