From b155a2d78c82cc00acceac7bc570fe794109f43b Mon Sep 17 00:00:00 2001 From: Kieran Osgood Date: Wed, 13 May 2026 20:04:15 +0100 Subject: [PATCH] Fix Swift 6 sample concurrency issues --- .../Sources/Lib/KeychainHelper.swift | 3 ++- .../CheckoutKitSwiftDemo/Sources/Lib/Logger.swift | 9 ++++++++- .../EnvironmentVariables.swift | 9 +-------- .../ShopifyAcceleratedCheckoutsApp/Network.swift | 3 ++- 4 files changed, 13 insertions(+), 11 deletions(-) diff --git a/platforms/swift/Samples/CheckoutKitSwiftDemo/CheckoutKitSwiftDemo/Sources/Lib/KeychainHelper.swift b/platforms/swift/Samples/CheckoutKitSwiftDemo/CheckoutKitSwiftDemo/Sources/Lib/KeychainHelper.swift index cfd8707f..d08f2b13 100644 --- a/platforms/swift/Samples/CheckoutKitSwiftDemo/CheckoutKitSwiftDemo/Sources/Lib/KeychainHelper.swift +++ b/platforms/swift/Samples/CheckoutKitSwiftDemo/CheckoutKitSwiftDemo/Sources/Lib/KeychainHelper.swift @@ -28,7 +28,8 @@ struct OAuthTokenResult: Codable { } } -final class KeychainHelper: Sendable { +@MainActor +final class KeychainHelper { static let shared = KeychainHelper() private let logger = OSLogger(prefix: "Keychain", logLevel: ShopifyCheckoutKit.configuration.logLevel) diff --git a/platforms/swift/Samples/CheckoutKitSwiftDemo/CheckoutKitSwiftDemo/Sources/Lib/Logger.swift b/platforms/swift/Samples/CheckoutKitSwiftDemo/CheckoutKitSwiftDemo/Sources/Lib/Logger.swift index 6cb895e1..f90501ef 100644 --- a/platforms/swift/Samples/CheckoutKitSwiftDemo/CheckoutKitSwiftDemo/Sources/Lib/Logger.swift +++ b/platforms/swift/Samples/CheckoutKitSwiftDemo/CheckoutKitSwiftDemo/Sources/Lib/Logger.swift @@ -1,8 +1,9 @@ import Foundation import ShopifyCheckoutKit -final class FileLogger: Logger { +final class FileLogger: Logger, @unchecked Sendable { private let fileHandle: FileHandle? + private let lock = NSLock() let logFileUrl: URL @@ -24,6 +25,9 @@ final class FileLogger: Logger { } public func log(_ message: String) { + lock.lock() + defer { lock.unlock() } + guard let fileHandle else { print("File handle is nil") return @@ -43,6 +47,9 @@ final class FileLogger: Logger { } public func clearLogs() { + lock.lock() + defer { lock.unlock() } + do { try "".write(toFile: logFileUrl.path, atomically: false, encoding: .utf8) } catch let error as NSError { diff --git a/platforms/swift/Samples/ShopifyAcceleratedCheckoutsApp/ShopifyAcceleratedCheckoutsApp/EnvironmentVariables.swift b/platforms/swift/Samples/ShopifyAcceleratedCheckoutsApp/ShopifyAcceleratedCheckoutsApp/EnvironmentVariables.swift index fe5b9a7e..79c91df9 100644 --- a/platforms/swift/Samples/ShopifyAcceleratedCheckoutsApp/ShopifyAcceleratedCheckoutsApp/EnvironmentVariables.swift +++ b/platforms/swift/Samples/ShopifyAcceleratedCheckoutsApp/ShopifyAcceleratedCheckoutsApp/EnvironmentVariables.swift @@ -8,19 +8,12 @@ public enum EnvironmentVariables { } private static func getKey(for key: String) -> String { - guard let value = EnvironmentVariables.infoDictionary[key] as? String else { + guard let value = Bundle.main.infoDictionary?[key] as? String else { fatalError("Environment variable \(key) must be set in the Storefront.xcconfig file") } return value } - private static let infoDictionary: [String: Any] = { - guard let dict = Bundle.main.infoDictionary else { - fatalError("Plist file not found") - } - return dict - }() - public static let storefrontAccessToken: String = getKey(for: Keys.storefrontAccessToken) public static let storefrontDomain: String = getKey(for: Keys.storefrontDomain) diff --git a/platforms/swift/Samples/ShopifyAcceleratedCheckoutsApp/ShopifyAcceleratedCheckoutsApp/Network.swift b/platforms/swift/Samples/ShopifyAcceleratedCheckoutsApp/ShopifyAcceleratedCheckoutsApp/Network.swift index 6a5616ce..ae49f5b9 100644 --- a/platforms/swift/Samples/ShopifyAcceleratedCheckoutsApp/ShopifyAcceleratedCheckoutsApp/Network.swift +++ b/platforms/swift/Samples/ShopifyAcceleratedCheckoutsApp/ShopifyAcceleratedCheckoutsApp/Network.swift @@ -18,7 +18,8 @@ typealias ProductVariants = Storefront.GetProductsQuery.Data.Products.Node.Varia typealias ProductVariant = Storefront.GetProductsQuery.Data.Products.Node.Variants.Node typealias ProductPrice = Storefront.GetProductsQuery.Data.Products.Node.Variants.Node.Price -class Network { +@MainActor +final class Network { static let shared = Network() /// Get the device's language code mapped to Shopify's LanguageCode enum