From 6f963fc5c6d0202f5936c99ea2ead493a3f169c2 Mon Sep 17 00:00:00 2001 From: NachoSoto Date: Tue, 9 Aug 2022 08:13:27 -0600 Subject: [PATCH] `SystemInfo.finishTransactions`: made thread-safe This property is publicly exposed through `Purchases`, but it's mutable state. With the move this `Sendable` we need to enforce correctness. --- Sources/Misc/SystemInfo.swift | 9 +++++++-- Sources/Purchasing/Purchases/Purchases.swift | 4 ++-- Sources/Purchasing/Purchases/PurchasesOrchestrator.swift | 4 ++-- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/Sources/Misc/SystemInfo.swift b/Sources/Misc/SystemInfo.swift index 94d1451e58..10741a248f 100644 --- a/Sources/Misc/SystemInfo.swift +++ b/Sources/Misc/SystemInfo.swift @@ -29,14 +29,19 @@ class SystemInfo { static var forceUniversalAppStore: Bool = false let storeKit2Setting: StoreKit2Setting - var finishTransactions: Bool let operationDispatcher: OperationDispatcher let platformFlavor: String let platformFlavorVersion: String? let bundle: Bundle let dangerousSettings: DangerousSettings + var finishTransactions: Bool { + get { return self._finishTransactions.value } + set { self._finishTransactions.value = newValue } + } + private let sandboxEnvironmentDetector: SandboxEnvironmentDetector + private let _finishTransactions: Atomic var isSandbox: Bool { return self.sandboxEnvironmentDetector.isSandbox @@ -106,7 +111,7 @@ class SystemInfo { self.platformFlavorVersion = platformInfo?.version self.bundle = bundle - self.finishTransactions = finishTransactions + self._finishTransactions = .init(finishTransactions) self.operationDispatcher = operationDispatcher self.storeKit2Setting = storeKit2Setting self.dangerousSettings = dangerousSettings ?? DangerousSettings() diff --git a/Sources/Purchasing/Purchases/Purchases.swift b/Sources/Purchasing/Purchases/Purchases.swift index 332bd2065e..24033cb82b 100644 --- a/Sources/Purchasing/Purchases/Purchases.swift +++ b/Sources/Purchasing/Purchases/Purchases.swift @@ -223,8 +223,8 @@ public typealias StartPurchaseBlock = (@escaping PurchaseCompletedBlock) -> Void * More information on finishing transactions manually [is available here](https://rev.cat/finish-transactions). */ @objc public var finishTransactions: Bool { - get { systemInfo.finishTransactions } - set { systemInfo.finishTransactions = newValue } + get { self.systemInfo.finishTransactions } + set { self.systemInfo.finishTransactions = newValue } } private let attributionFetcher: AttributionFetcher diff --git a/Sources/Purchasing/Purchases/PurchasesOrchestrator.swift b/Sources/Purchasing/Purchases/PurchasesOrchestrator.swift index 7b67c1a088..49c947b2ec 100644 --- a/Sources/Purchasing/Purchases/PurchasesOrchestrator.swift +++ b/Sources/Purchasing/Purchases/PurchasesOrchestrator.swift @@ -30,7 +30,7 @@ import StoreKit // swiftlint:disable file_length type_body_length class PurchasesOrchestrator { - var finishTransactions: Bool { systemInfo.finishTransactions } + var finishTransactions: Bool { self.systemInfo.finishTransactions } var allowSharingAppStoreAccount: Bool { get { return _allowSharingAppStoreAccount ?? self.currentUserProvider.currentUserIsAnonymous @@ -619,7 +619,7 @@ extension PurchasesOrchestrator: StoreKit2TransactionListenerDelegate { func transactionsUpdated() async throws { // Need to restore if using observer mode (which is inverse of finishTransactions) - let isRestore = !systemInfo.finishTransactions + let isRestore = !self.systemInfo.finishTransactions _ = try await syncPurchases(receiptRefreshPolicy: .always, isRestore: isRestore) }