From 8f3a8cfd3a2d59373ae5ab12e4b06b2f01db8011 Mon Sep 17 00:00:00 2001 From: Kieran Osgood Date: Wed, 10 Jun 2026 13:05:27 +0100 Subject: [PATCH 1/4] Raise Swift iOS deployment target to 15 --- Package.swift | 2 +- ShopifyCheckoutKit.podspec | 2 +- platforms/react-native/README.md | 6 +++--- .../checkout-kit-react-native/RNShopifyCheckoutKit.podspec | 2 +- platforms/swift/README.md | 2 +- .../Sources/CheckoutProtocolClient.swift | 6 +----- .../CheckoutKitSwiftDemo/Sources/Scenes/Logs/LogsView.swift | 1 - platforms/swift/Scripts/api | 2 +- .../swift/Sources/ShopifyCheckoutKit/CheckoutWebView.swift | 4 +--- 9 files changed, 10 insertions(+), 17 deletions(-) diff --git a/Package.swift b/Package.swift index 53a6abf6..7e958664 100644 --- a/Package.swift +++ b/Package.swift @@ -6,7 +6,7 @@ import PackageDescription let package = Package( name: "ShopifyCheckoutKit", platforms: [ - .iOS(.v13) + .iOS(.v15) ], products: [ // Products define the executables and libraries a package produces, and make them visible to other packages. diff --git a/ShopifyCheckoutKit.podspec b/ShopifyCheckoutKit.podspec index bc4701ed..89c8babd 100644 --- a/ShopifyCheckoutKit.podspec +++ b/ShopifyCheckoutKit.podspec @@ -16,7 +16,7 @@ Pod::Spec.new do |s| s.swift_version = "5.0" - s.ios.deployment_target = "13.0" + s.ios.deployment_target = "15.0" s.pod_target_xcconfig = { 'OTHER_SWIFT_FLAGS' => '-package-name ShopifyCheckoutKit -DCOCOAPODS' diff --git a/platforms/react-native/README.md b/platforms/react-native/README.md index a07917f3..e1e4751a 100644 --- a/platforms/react-native/README.md +++ b/platforms/react-native/README.md @@ -67,7 +67,7 @@ experiences. ## Platform Requirements - **React Native** - Minimum version `0.77` (v4+) / `0.70` (v3 and earlier) -- **iOS** - Minimum version iOS 13 +- **iOS** - Minimum version iOS 15 - **Android** - Minimum Java 11, Android SDK version `24`, and Kotlin `2.0+` ## Version Compatibility @@ -133,12 +133,12 @@ buildscript { ### 3. Minimum iOS requirements Check the `platform :ios` property of your `ios/Podfile` to ensure that the -minimum version number is at least `13`. +minimum version number is at least `15`. ```diff # ios/Podfile - platform :ios, min_ios_version_supported -+ platform :ios, 13 ++ platform :ios, 15 ``` ## Basic Usage diff --git a/platforms/react-native/modules/@shopify/checkout-kit-react-native/RNShopifyCheckoutKit.podspec b/platforms/react-native/modules/@shopify/checkout-kit-react-native/RNShopifyCheckoutKit.podspec index 939af1f0..c0ed73fd 100644 --- a/platforms/react-native/modules/@shopify/checkout-kit-react-native/RNShopifyCheckoutKit.podspec +++ b/platforms/react-native/modules/@shopify/checkout-kit-react-native/RNShopifyCheckoutKit.podspec @@ -13,7 +13,7 @@ Pod::Spec.new do |s| s.license = package["license"] s.authors = package["author"] - s.platforms = { :ios => "13.0" } + s.platforms = { :ios => "15.0" } s.source = { :git => "https://github.com/Shopify/checkout-kit.git", :tag => "react-native/#{s.version}" } s.source_files = "ios/*.{h,m,mm,swift}" diff --git a/platforms/swift/README.md b/platforms/swift/README.md index 7e582d7b..fe0378c5 100644 --- a/platforms/swift/README.md +++ b/platforms/swift/README.md @@ -39,7 +39,7 @@ ## Requirements - Swift Package Manager with Swift tools 5.9+ -- iOS 13.0+ for `ShopifyCheckoutKit` +- iOS 15.0+ for `ShopifyCheckoutKit` - iOS 16.0+ for `ShopifyAcceleratedCheckouts` - A checkout URL from `cart.checkoutUrl` or a cart permalink diff --git a/platforms/swift/Samples/CheckoutKitSwiftDemo/CheckoutKitSwiftDemo/Sources/CheckoutProtocolClient.swift b/platforms/swift/Samples/CheckoutKitSwiftDemo/CheckoutKitSwiftDemo/Sources/CheckoutProtocolClient.swift index 022548bf..ca311f05 100644 --- a/platforms/swift/Samples/CheckoutKitSwiftDemo/CheckoutKitSwiftDemo/Sources/CheckoutProtocolClient.swift +++ b/platforms/swift/Samples/CheckoutKitSwiftDemo/CheckoutKitSwiftDemo/Sources/CheckoutProtocolClient.swift @@ -64,10 +64,6 @@ extension UIApplication { .compactMap { $0 as? UIWindowScene } .filter { $0.activationState == .foregroundActive } - if #available(iOS 15.0, *) { - return activeScenes.compactMap(\.keyWindow).first - } else { - return activeScenes.flatMap(\.windows).first { $0.isKeyWindow } - } + return activeScenes.compactMap(\.keyWindow).first } } diff --git a/platforms/swift/Samples/CheckoutKitSwiftDemo/CheckoutKitSwiftDemo/Sources/Scenes/Logs/LogsView.swift b/platforms/swift/Samples/CheckoutKitSwiftDemo/CheckoutKitSwiftDemo/Sources/Scenes/Logs/LogsView.swift index 8e684de3..a755f01e 100644 --- a/platforms/swift/Samples/CheckoutKitSwiftDemo/CheckoutKitSwiftDemo/Sources/Scenes/Logs/LogsView.swift +++ b/platforms/swift/Samples/CheckoutKitSwiftDemo/CheckoutKitSwiftDemo/Sources/Scenes/Logs/LogsView.swift @@ -1,7 +1,6 @@ @preconcurrency import ShopifyCheckoutKit import SwiftUI -@available(iOS 15.0, *) struct LogsView: View { @State private var logs: [String?] = LogReader.shared.readLogs(limit: 100) ?? [] diff --git a/platforms/swift/Scripts/api b/platforms/swift/Scripts/api index 9a370018..8cf223ff 100755 --- a/platforms/swift/Scripts/api +++ b/platforms/swift/Scripts/api @@ -18,7 +18,7 @@ SWIFT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)" PACKAGE_ROOT="$(cd "$SWIFT_ROOT/../.." && pwd)" BASELINE_DIR="$SWIFT_ROOT/api" MODULES=(ShopifyCheckoutProtocol ShopifyCheckoutKit ShopifyAcceleratedCheckouts) -TARGET="arm64-apple-ios13.0-simulator" +TARGET="arm64-apple-ios15.0-simulator" if [[ ! -f "$PACKAGE_ROOT/Package.swift" ]]; then echo "Error: Package.swift not found at $PACKAGE_ROOT" >&2 diff --git a/platforms/swift/Sources/ShopifyCheckoutKit/CheckoutWebView.swift b/platforms/swift/Sources/ShopifyCheckoutKit/CheckoutWebView.swift index 6317c1c4..08140113 100644 --- a/platforms/swift/Sources/ShopifyCheckoutKit/CheckoutWebView.swift +++ b/platforms/swift/Sources/ShopifyCheckoutKit/CheckoutWebView.swift @@ -121,9 +121,7 @@ class CheckoutWebView: WKWebView { isOpaque = false backgroundColor = ShopifyCheckoutKit.configuration.backgroundColor - if #available(iOS 15.0, *) { - underPageBackgroundColor = ShopifyCheckoutKit.configuration.backgroundColor - } + underPageBackgroundColor = ShopifyCheckoutKit.configuration.backgroundColor } // MARK: - From 2b47dd9472020b44dccb685869babc889a36e886 Mon Sep 17 00:00:00 2001 From: Kieran Osgood Date: Wed, 10 Jun 2026 17:09:24 +0100 Subject: [PATCH 2/4] Update React Native iOS Podfile lock --- platforms/react-native/sample/ios/Podfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platforms/react-native/sample/ios/Podfile.lock b/platforms/react-native/sample/ios/Podfile.lock index 3bbaefdd..39573ff4 100644 --- a/platforms/react-native/sample/ios/Podfile.lock +++ b/platforms/react-native/sample/ios/Podfile.lock @@ -2996,7 +2996,7 @@ SPEC CHECKSUMS: RNGestureHandler: eeb622199ef1fb3a076243131095df1c797072f0 RNReanimated: 237d420b7bb4378ef1dacc7d7a5c674fddb4b5d2 RNScreens: 3fc29af06302e1f1c18a7829fe57cbc2c0259912 - RNShopifyCheckoutKit: e19eba6efb68ed31936d7e7b413a02fdb104a053 + RNShopifyCheckoutKit: 8e021434b6a080b78cd6c4123eb7b0c1659d641f RNVectorIcons: be4d047a76ad307ffe54732208fb0498fcb8477f ShopifyCheckoutKit: ffd719db529ac48907536d855182d7c57c85659f SocketRocket: d4aabe649be1e368d1318fdf28a022d714d65748 From 1dd67b9417efd70de40a0361455b50bfb7978528 Mon Sep 17 00:00:00 2001 From: Kieran Osgood Date: Mon, 15 Jun 2026 12:17:38 +0100 Subject: [PATCH 3/4] Align React Native SwiftPM iOS target --- .../@shopify/checkout-kit-react-native/ios/Package.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platforms/react-native/modules/@shopify/checkout-kit-react-native/ios/Package.swift b/platforms/react-native/modules/@shopify/checkout-kit-react-native/ios/Package.swift index 4a65cb79..8cafc679 100644 --- a/platforms/react-native/modules/@shopify/checkout-kit-react-native/ios/Package.swift +++ b/platforms/react-native/modules/@shopify/checkout-kit-react-native/ios/Package.swift @@ -3,7 +3,7 @@ import PackageDescription let package = Package( name: "RNShopifyCheckoutKitProtocolRelay", - platforms: [.iOS(.v13), .macOS(.v10_15)], + platforms: [.iOS(.v15), .macOS(.v10_15)], products: [ .library(name: "RNShopifyCheckoutKitProtocolRelay", targets: ["RNShopifyCheckoutKitProtocolRelay"]) ], From c6405d86805afd5a8add0a088d653f4c06b4d899 Mon Sep 17 00:00:00 2001 From: Kieran Osgood Date: Mon, 15 Jun 2026 12:20:04 +0100 Subject: [PATCH 4/4] Raise protocol Swift iOS target to 15 --- .github/workflows/ci.yml | 10 +++ .../project.pbxproj | 20 +++--- .../Sources/Api/Network.swift | 70 +++++++++++++------ .../Sources/Scenes/Cart/CartView.swift | 39 ++++++----- .../Sources/Scenes/ProductView.swift | 39 ++++++----- .../Sources/Scenes/SettingsView.swift | 1 + .../swift/Scripts/check_sample_package_paths | 31 ++++++++ platforms/swift/Scripts/lint | 5 ++ protocol/languages/swift/Package.swift | 2 +- protocol/languages/swift/README.md | 2 +- 10 files changed, 149 insertions(+), 70 deletions(-) create mode 100755 platforms/swift/Scripts/check_sample_package_paths diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bbbdf6e6..0af48810 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -103,6 +103,15 @@ jobs: if: needs.changes.outputs.swift == 'true' uses: ./.github/workflows/swift-lint.yml + swift-sample-package-paths: + name: Swift Sample Package Paths + needs: changes + if: needs.changes.outputs.swift == 'true' + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - run: platforms/swift/Scripts/check_sample_package_paths + rn-test: name: React Native needs: changes @@ -182,6 +191,7 @@ jobs: - swift-test-package - swift-build-samples - swift-lint + - swift-sample-package-paths - rn-test - rn-test-android - rn-test-ios diff --git a/platforms/swift/Samples/CheckoutKitSwiftDemo/CheckoutKitSwiftDemo.xcodeproj/project.pbxproj b/platforms/swift/Samples/CheckoutKitSwiftDemo/CheckoutKitSwiftDemo.xcodeproj/project.pbxproj index f030bc6c..450c2228 100644 --- a/platforms/swift/Samples/CheckoutKitSwiftDemo/CheckoutKitSwiftDemo.xcodeproj/project.pbxproj +++ b/platforms/swift/Samples/CheckoutKitSwiftDemo/CheckoutKitSwiftDemo.xcodeproj/project.pbxproj @@ -159,7 +159,7 @@ mainGroup = 4EBBA75E2A5F0CE200193E19; packageReferences = ( CB00000012345678 /* XCRemoteSwiftPackageReference "apollo-ios" */, - CB2370002FB21BF100F0D914 /* XCLocalSwiftPackageReference "../../../../../checkout-kit" */, + CB2370002FB21BF100F0D914 /* XCLocalSwiftPackageReference "../../../.." */, ); productRefGroup = 4EBBA7682A5F0CE200193E19 /* Products */; projectDirPath = ""; @@ -279,7 +279,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 17.0; + IPHONEOS_DEPLOYMENT_TARGET = 15.6; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; ONLY_ACTIVE_ARCH = YES; @@ -337,7 +337,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 17.0; + IPHONEOS_DEPLOYMENT_TARGET = 15.6; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; SDKROOT = iphoneos; @@ -367,7 +367,7 @@ INFOPLIST_KEY_UIStatusBarHidden = NO; INFOPLIST_KEY_UISupportedInterfaceOrientations = UIInterfaceOrientationPortrait; INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown"; - IPHONEOS_DEPLOYMENT_TARGET = 16.6; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -402,7 +402,7 @@ INFOPLIST_KEY_UIStatusBarHidden = NO; INFOPLIST_KEY_UISupportedInterfaceOrientations = UIInterfaceOrientationPortrait; INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown"; - IPHONEOS_DEPLOYMENT_TARGET = 16.6; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", @@ -443,9 +443,9 @@ /* End XCConfigurationList section */ /* Begin XCLocalSwiftPackageReference section */ - CB2370002FB21BF100F0D914 /* XCLocalSwiftPackageReference "../../../../../checkout-kit" */ = { + CB2370002FB21BF100F0D914 /* XCLocalSwiftPackageReference "../../../.." */ = { isa = XCLocalSwiftPackageReference; - relativePath = "../../../../../checkout-kit"; + relativePath = ../../../..; }; /* End XCLocalSwiftPackageReference section */ @@ -473,17 +473,17 @@ }; CB001E302F3CDA0300286F69 /* ShopifyCheckoutProtocol */ = { isa = XCSwiftPackageProductDependency; - package = CB2370002FB21BF100F0D914 /* XCLocalSwiftPackageReference "../../../../../checkout-kit" */; + package = CB2370002FB21BF100F0D914 /* XCLocalSwiftPackageReference "../../../.." */; productName = ShopifyCheckoutProtocol; }; CB1B10B42E4CDDB0001713F8 /* ShopifyCheckoutKit */ = { isa = XCSwiftPackageProductDependency; - package = CB2370002FB21BF100F0D914 /* XCLocalSwiftPackageReference "../../../../../checkout-kit" */; + package = CB2370002FB21BF100F0D914 /* XCLocalSwiftPackageReference "../../../.." */; productName = ShopifyCheckoutKit; }; CBED2D4E2F3F5D1B00EC866A /* ShopifyAcceleratedCheckouts */ = { isa = XCSwiftPackageProductDependency; - package = CB2370002FB21BF100F0D914 /* XCLocalSwiftPackageReference "../../../../../checkout-kit" */; + package = CB2370002FB21BF100F0D914 /* XCLocalSwiftPackageReference "../../../.." */; productName = ShopifyAcceleratedCheckouts; }; /* End XCSwiftPackageProductDependency section */ diff --git a/platforms/swift/Samples/CheckoutKitSwiftDemo/CheckoutKitSwiftDemo/Sources/Api/Network.swift b/platforms/swift/Samples/CheckoutKitSwiftDemo/CheckoutKitSwiftDemo/Sources/Api/Network.swift index 8f23ed15..975742f4 100644 --- a/platforms/swift/Samples/CheckoutKitSwiftDemo/CheckoutKitSwiftDemo/Sources/Api/Network.swift +++ b/platforms/swift/Samples/CheckoutKitSwiftDemo/CheckoutKitSwiftDemo/Sources/Api/Network.swift @@ -5,35 +5,61 @@ import Foundation final class Network: Sendable { static let shared = Network() + private static var currentLanguageCode: String? { + if #available(iOS 16.0, *) { + return Locale.current.language.languageCode?.identifier + } else { + return Locale.current.languageCode + } + } + + private static var currentScriptCode: String? { + if #available(iOS 16.0, *) { + return Locale.current.language.script?.identifier + } else { + return Locale.current.scriptCode + } + } + + private static var currentRegionCode: String? { + if #available(iOS 16.0, *) { + return Locale.current.region?.identifier + } else { + return Locale.current.regionCode + } + } + private static func getLanguageCode() -> GraphQLEnum { - if let languageCode = Locale.current.language.languageCode?.identifier { - let code = languageCode.uppercased() - switch code { - case "ZH": - if let scriptCode = Locale.current.language.script?.identifier { - return GraphQLEnum(scriptCode == "Hans" ? Storefront.LanguageCode.zhCn : Storefront.LanguageCode.zhTw) - } - return GraphQLEnum(Storefront.LanguageCode.zhCn) - case "PT": - if let regionCode = Locale.current.language.region?.identifier { - return GraphQLEnum(regionCode == "BR" ? Storefront.LanguageCode.ptBr : Storefront.LanguageCode.ptPt) - } - return GraphQLEnum(Storefront.LanguageCode.pt) - default: - if let mappedCode = Storefront.LanguageCode(rawValue: code) { - return GraphQLEnum(mappedCode) - } - let baseLanguage = String(code.prefix(2)) - if let mappedCode = Storefront.LanguageCode(rawValue: baseLanguage) { - return GraphQLEnum(mappedCode) - } + guard let languageCode = currentLanguageCode?.uppercased() else { + return GraphQLEnum(Storefront.LanguageCode.en) + } + + switch languageCode { + case "ZH": + if let scriptCode = currentScriptCode { + return GraphQLEnum(scriptCode == "Hans" ? Storefront.LanguageCode.zhCn : Storefront.LanguageCode.zhTw) + } + return GraphQLEnum(Storefront.LanguageCode.zhCn) + case "PT": + if let regionCode = currentRegionCode?.uppercased() { + return GraphQLEnum(regionCode == "BR" ? Storefront.LanguageCode.ptBr : Storefront.LanguageCode.ptPt) + } + return GraphQLEnum(Storefront.LanguageCode.pt) + default: + if let mappedCode = Storefront.LanguageCode(rawValue: languageCode) { + return GraphQLEnum(mappedCode) + } + let baseLanguage = String(languageCode.prefix(2)) + if let mappedCode = Storefront.LanguageCode(rawValue: baseLanguage) { + return GraphQLEnum(mappedCode) } } + return GraphQLEnum(Storefront.LanguageCode.en) } var countryCode: GraphQLEnum { - GraphQLEnum(Storefront.CountryCode(rawValue: Locale.current.region?.identifier ?? "US") ?? .us) + GraphQLEnum(Storefront.CountryCode(rawValue: Network.currentRegionCode ?? "US") ?? .us) } var languageCode: GraphQLEnum { diff --git a/platforms/swift/Samples/CheckoutKitSwiftDemo/CheckoutKitSwiftDemo/Sources/Scenes/Cart/CartView.swift b/platforms/swift/Samples/CheckoutKitSwiftDemo/CheckoutKitSwiftDemo/Sources/Scenes/Cart/CartView.swift index 65b5e40c..56fafe57 100644 --- a/platforms/swift/Samples/CheckoutKitSwiftDemo/CheckoutKitSwiftDemo/Sources/Scenes/Cart/CartView.swift +++ b/platforms/swift/Samples/CheckoutKitSwiftDemo/CheckoutKitSwiftDemo/Sources/Scenes/Cart/CartView.swift @@ -36,26 +36,29 @@ struct CartView: View { VStack(spacing: DesignSystem.buttonSpacing) { if let cartID = cartManager.cart?.id { - AcceleratedCheckoutButtons(cartID: cartID) - .onFail { error in - print("[AcceleratedCheckout] Failed: \(error)") - } - .onCancel { - print("[AcceleratedCheckout] Cancelled") - } - .connect(client) - .environmentObject( - ShopifyAcceleratedCheckouts.Configuration( - storefrontDomain: InfoDictionary.shared.domain, - storefrontAccessToken: InfoDictionary.shared.accessToken + if #available(iOS 16, *) { + AcceleratedCheckoutButtons(cartID: cartID) + .applePayStyle(applePayStyle.style) + .onFail { error in + print("[AcceleratedCheckout] Failed: \(error)") + } + .onCancel { + print("[AcceleratedCheckout] Cancelled") + } + .connect(client) + .environmentObject( + ShopifyAcceleratedCheckouts.Configuration( + storefrontDomain: InfoDictionary.shared.domain, + storefrontAccessToken: InfoDictionary.shared.accessToken + ) ) - ) - .environmentObject( - ShopifyAcceleratedCheckouts.ApplePayConfiguration( - merchantIdentifier: InfoDictionary.shared.merchantIdentifier, - contactFields: [.email, .phone] + .environmentObject( + ShopifyAcceleratedCheckouts.ApplePayConfiguration( + merchantIdentifier: InfoDictionary.shared.merchantIdentifier, + contactFields: [.email, .phone] + ) ) - ) + } } Button( diff --git a/platforms/swift/Samples/CheckoutKitSwiftDemo/CheckoutKitSwiftDemo/Sources/Scenes/ProductView.swift b/platforms/swift/Samples/CheckoutKitSwiftDemo/CheckoutKitSwiftDemo/Sources/Scenes/ProductView.swift index bf8edd19..1c35fee9 100644 --- a/platforms/swift/Samples/CheckoutKitSwiftDemo/CheckoutKitSwiftDemo/Sources/Scenes/ProductView.swift +++ b/platforms/swift/Samples/CheckoutKitSwiftDemo/CheckoutKitSwiftDemo/Sources/Scenes/ProductView.swift @@ -113,26 +113,29 @@ struct ProductView: View { .disabled(!variant.availableForSale || loading) if variant.availableForSale { - AcceleratedCheckoutButtons(variantID: variant.id, quantity: 1) - .wallets([.applePay]) - .onFail { error in - print("[AcceleratedCheckout] Failed: \(error)") - } - .onCancel { - print("[AcceleratedCheckout] Cancelled") - } - .environmentObject( - ShopifyAcceleratedCheckouts.Configuration( - storefrontDomain: InfoDictionary.shared.domain, - storefrontAccessToken: InfoDictionary.shared.accessToken + if #available(iOS 16, *) { + AcceleratedCheckoutButtons(variantID: variant.id, quantity: 1) + .wallets([.applePay]) + .applePayStyle(applePayStyle.style) + .onFail { error in + print("[AcceleratedCheckout] Failed: \(error)") + } + .onCancel { + print("[AcceleratedCheckout] Cancelled") + } + .environmentObject( + ShopifyAcceleratedCheckouts.Configuration( + storefrontDomain: InfoDictionary.shared.domain, + storefrontAccessToken: InfoDictionary.shared.accessToken + ) ) - ) - .environmentObject( - ShopifyAcceleratedCheckouts.ApplePayConfiguration( - merchantIdentifier: InfoDictionary.shared.merchantIdentifier, - contactFields: [.email, .phone] + .environmentObject( + ShopifyAcceleratedCheckouts.ApplePayConfiguration( + merchantIdentifier: InfoDictionary.shared.merchantIdentifier, + contactFields: [.email, .phone] + ) ) - ) + } } }.padding([.leading, .trailing], 15) } diff --git a/platforms/swift/Samples/CheckoutKitSwiftDemo/CheckoutKitSwiftDemo/Sources/Scenes/SettingsView.swift b/platforms/swift/Samples/CheckoutKitSwiftDemo/CheckoutKitSwiftDemo/Sources/Scenes/SettingsView.swift index 01b99d32..c3f98b82 100644 --- a/platforms/swift/Samples/CheckoutKitSwiftDemo/CheckoutKitSwiftDemo/Sources/Scenes/SettingsView.swift +++ b/platforms/swift/Samples/CheckoutKitSwiftDemo/CheckoutKitSwiftDemo/Sources/Scenes/SettingsView.swift @@ -315,6 +315,7 @@ enum ApplePayStyleOption: String, CaseIterable { } } + @available(iOS 16.0, *) var style: PayWithApplePayButtonStyle { switch self { case .automatic: return .automatic diff --git a/platforms/swift/Scripts/check_sample_package_paths b/platforms/swift/Scripts/check_sample_package_paths new file mode 100755 index 00000000..ba58d2af --- /dev/null +++ b/platforms/swift/Scripts/check_sample_package_paths @@ -0,0 +1,31 @@ +#!/usr/bin/env bash + +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +SWIFT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)" +SAMPLES_DIR="$SWIFT_DIR/Samples" +EXPECTED_RELATIVE_PATH="../../../.." + +status=0 + +while IFS= read -r -d '' project_file; do + while IFS= read -r line; do + relative_path="${line#*relativePath = }" + relative_path="${relative_path%;}" + relative_path="${relative_path%\"}" + relative_path="${relative_path#\"}" + + if [[ "$relative_path" != "$EXPECTED_RELATIVE_PATH" ]]; then + echo "❌ $project_file uses local Swift package path '$relative_path'." + echo " Use '$EXPECTED_RELATIVE_PATH' so sample projects resolve the repo-root package from any worktree directory." + status=1 + fi + done < <(grep -E '^[[:space:]]*relativePath = ' "$project_file" || true) +done < <(find "$SAMPLES_DIR" -path '*/project.pbxproj' -print0) + +if [[ $status -ne 0 ]]; then + exit $status +fi + +echo "✅ Swift sample package paths are worktree-safe." diff --git a/platforms/swift/Scripts/lint b/platforms/swift/Scripts/lint index 41e38bc5..62c457b6 100755 --- a/platforms/swift/Scripts/lint +++ b/platforms/swift/Scripts/lint @@ -23,6 +23,11 @@ if [[ "$MODE" != "check" && "$MODE" != "fix" ]]; then exit 1 fi +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +if ! "$SCRIPT_DIR/check_sample_package_paths"; then + exit 1 +fi + print_install_instructions() { echo "🔧 FIX:" echo " Shopify employee? Run 'dev up'" diff --git a/protocol/languages/swift/Package.swift b/protocol/languages/swift/Package.swift index 8c953f0b..416ffde0 100644 --- a/protocol/languages/swift/Package.swift +++ b/protocol/languages/swift/Package.swift @@ -5,7 +5,7 @@ import PackageDescription let package = Package( name: "ShopifyCheckoutProtocol", platforms: [ - .iOS(.v13), + .iOS(.v15), .macOS(.v10_15), ], products: [ diff --git a/protocol/languages/swift/README.md b/protocol/languages/swift/README.md index 2847772b..c9df3f6c 100644 --- a/protocol/languages/swift/README.md +++ b/protocol/languages/swift/README.md @@ -9,7 +9,7 @@ Most apps consume this product through the root Checkout Kit Swift package. ## Requirements - Swift Package Manager with Swift tools 5.9+ -- iOS 13.0+ or macOS 10.15+ +- iOS 15.0+ or macOS 10.15+ ## Install