From c645f3925403a0369c5bb0d181ef33b4ff853c3d Mon Sep 17 00:00:00 2001 From: Davide De Rosa Date: Sun, 10 Sep 2023 10:27:11 +0200 Subject: [PATCH] Fix SandboxChecker actor (#356) Mac function was still running on main actor. Only constrain to main actor on public API. --- .../App/Managers/ProductManager.swift | 2 +- .../Reusable/SandboxChecker.swift | 43 ++++++++++++++----- 2 files changed, 34 insertions(+), 11 deletions(-) diff --git a/Passepartout/App/Managers/ProductManager.swift b/Passepartout/App/Managers/ProductManager.swift index 1e67a028..7982683a 100644 --- a/Passepartout/App/Managers/ProductManager.swift +++ b/Passepartout/App/Managers/ProductManager.swift @@ -113,7 +113,7 @@ final class ProductManager: NSObject, ObservableObject { SKPaymentQueue.default().add(self) refreshProducts() - sandboxChecker.$isSandbox + sandboxChecker.$isBeta .dropFirst() // ignore initial value .sink { [weak self] in guard let self else { diff --git a/PassepartoutLibrary/Sources/PassepartoutCore/Reusable/SandboxChecker.swift b/PassepartoutLibrary/Sources/PassepartoutCore/Reusable/SandboxChecker.swift index b974ee09..8dbb5e4a 100644 --- a/PassepartoutLibrary/Sources/PassepartoutCore/Reusable/SandboxChecker.swift +++ b/PassepartoutLibrary/Sources/PassepartoutCore/Reusable/SandboxChecker.swift @@ -28,25 +28,52 @@ import Foundation // https://stackoverflow.com/a/32238344/784615 // https://gist.github.com/lukaskubanek/cbfcab29c0c93e0e9e0a16ab09586996 -@MainActor public final class SandboxChecker: ObservableObject { private let bundle: Bundle - @Published public private(set) var isSandbox = false + @Published public private(set) var isBeta = false public init(bundle: Bundle) { self.bundle = bundle } + @MainActor public func check() { Task { - isSandbox = await isSandboxBuild() - pp_log.info("Sandbox build: \(isSandbox)") + isBeta = await isBetaBuild() + pp_log.info("Beta build: \(isBeta)") } } - private func isSandboxBuild() async -> Bool { + // IMPORTANT: check Mac first because os(iOS) holds true for Catalyst + private func isBetaBuild() async -> Bool { #if targetEnvironment(macCatalyst) || os(macOS) + isMacTestFlightBuild + #elseif os(iOS) + isiOSSandboxBuild + #else + false + #endif + } +} + +// MARK: iOS + +#if os(iOS) +private extension SandboxChecker { + var isiOSSandboxBuild: Bool { + bundle.appStoreReceiptURL?.lastPathComponent == "sandboxReceipt" + } +} +#endif + +// MARK: macOS + +#if targetEnvironment(macCatalyst) || os(macOS) +import Security + +private extension SandboxChecker { + var isMacTestFlightBuild: Bool { var status = noErr var code: SecStaticCode? @@ -77,10 +104,6 @@ public final class SandboxChecker: ObservableObject { requirement ) return status == errSecSuccess - #elseif os(iOS) - bundle.appStoreReceiptURL?.lastPathComponent == "sandboxReceipt" - #else - false - #endif } } +#endif