Look up TestFlight flag asynchronously (#352)
Xcode has been quite obnoxious recently with this issue. Start the app with the most restrictive type (.undefined), relax restrictions after looking up sandbox and app receipt.
This commit is contained in:
parent
33d9e05907
commit
a38e3fed7a
|
@ -50,10 +50,10 @@
|
||||||
0E34AC7827F840890042F2AB /* OrganizerView+Scene.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E34AC7727F840890042F2AB /* OrganizerView+Scene.swift */; };
|
0E34AC7827F840890042F2AB /* OrganizerView+Scene.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E34AC7727F840890042F2AB /* OrganizerView+Scene.swift */; };
|
||||||
0E34AC8227F892C40042F2AB /* OnDemandView+SSID.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E34AC8127F892C40042F2AB /* OnDemandView+SSID.swift */; };
|
0E34AC8227F892C40042F2AB /* OnDemandView+SSID.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E34AC8127F892C40042F2AB /* OnDemandView+SSID.swift */; };
|
||||||
0E35C09A280E95BB0071FA35 /* ProviderProfileAvailability.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E35C099280E95BB0071FA35 /* ProviderProfileAvailability.swift */; };
|
0E35C09A280E95BB0071FA35 /* ProviderProfileAvailability.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E35C099280E95BB0071FA35 /* ProviderProfileAvailability.swift */; };
|
||||||
|
0E3A3C102AA9AA530003A5F6 /* KeyValueStore+CloudKit.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E3A3C0F2AA9AA530003A5F6 /* KeyValueStore+CloudKit.swift */; };
|
||||||
0E3A3C132AAB7C480003A5F6 /* UpgradeManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E3A3C112AAB7C470003A5F6 /* UpgradeManager.swift */; };
|
0E3A3C132AAB7C480003A5F6 /* UpgradeManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E3A3C112AAB7C470003A5F6 /* UpgradeManager.swift */; };
|
||||||
0E3A3C142AAB7C480003A5F6 /* DefaultUpgradeManagerStrategy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E3A3C122AAB7C480003A5F6 /* DefaultUpgradeManagerStrategy.swift */; };
|
0E3A3C142AAB7C480003A5F6 /* DefaultUpgradeManagerStrategy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E3A3C122AAB7C480003A5F6 /* DefaultUpgradeManagerStrategy.swift */; };
|
||||||
0E3A3C162AAB8AB80003A5F6 /* UpgradeManagerStrategy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E3A3C152AAB8AB80003A5F6 /* UpgradeManagerStrategy.swift */; };
|
0E3A3C162AAB8AB80003A5F6 /* UpgradeManagerStrategy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E3A3C152AAB8AB80003A5F6 /* UpgradeManagerStrategy.swift */; };
|
||||||
0E3A3C102AA9AA530003A5F6 /* KeyValueStore+CloudKit.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E3A3C0F2AA9AA530003A5F6 /* KeyValueStore+CloudKit.swift */; };
|
|
||||||
0E3A593C2A50975700B3FE40 /* ErrorHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E3A593B2A50975700B3FE40 /* ErrorHandler.swift */; };
|
0E3A593C2A50975700B3FE40 /* ErrorHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E3A593B2A50975700B3FE40 /* ErrorHandler.swift */; };
|
||||||
0E3B7FCD27E47B3700C66F13 /* AddHostView+Name.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E3B7FCC27E47B3700C66F13 /* AddHostView+Name.swift */; };
|
0E3B7FCD27E47B3700C66F13 /* AddHostView+Name.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E3B7FCC27E47B3700C66F13 /* AddHostView+Name.swift */; };
|
||||||
0E3B7FD627E5173A00C66F13 /* ProfileView+VPN.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E3B7FD527E5173A00C66F13 /* ProfileView+VPN.swift */; };
|
0E3B7FD627E5173A00C66F13 /* ProfileView+VPN.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0E3B7FD527E5173A00C66F13 /* ProfileView+VPN.swift */; };
|
||||||
|
@ -176,7 +176,7 @@
|
||||||
0ED2B36027D3C99100FD8EA9 /* PassepartoutWireGuardTunnel.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 0ED2B34A27D3C77800FD8EA9 /* PassepartoutWireGuardTunnel.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
|
0ED2B36027D3C99100FD8EA9 /* PassepartoutWireGuardTunnel.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = 0ED2B34A27D3C77800FD8EA9 /* PassepartoutWireGuardTunnel.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
|
||||||
0ED2B36727D3C9A300FD8EA9 /* WireGuardAppExtension in Frameworks */ = {isa = PBXBuildFile; productRef = 0ED2B36627D3C9A300FD8EA9 /* WireGuardAppExtension */; };
|
0ED2B36727D3C9A300FD8EA9 /* WireGuardAppExtension in Frameworks */ = {isa = PBXBuildFile; productRef = 0ED2B36627D3C9A300FD8EA9 /* WireGuardAppExtension */; };
|
||||||
0ED30DCC27EA197D0057D8A3 /* RevealingSecureField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ED30DCB27EA197C0057D8A3 /* RevealingSecureField.swift */; };
|
0ED30DCC27EA197D0057D8A3 /* RevealingSecureField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ED30DCB27EA197C0057D8A3 /* RevealingSecureField.swift */; };
|
||||||
0ED30DCF27EA1EF80057D8A3 /* PaywallView+Beta.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ED30DCE27EA1EF80057D8A3 /* PaywallView+Beta.swift */; };
|
0ED30DCF27EA1EF80057D8A3 /* PaywallView+Restricted.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ED30DCE27EA1EF80057D8A3 /* PaywallView+Restricted.swift */; };
|
||||||
0ED30DD227EA1F650057D8A3 /* PaywallView+Purchase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ED30DD127EA1F650057D8A3 /* PaywallView+Purchase.swift */; };
|
0ED30DD227EA1F650057D8A3 /* PaywallView+Purchase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ED30DD127EA1F650057D8A3 /* PaywallView+Purchase.swift */; };
|
||||||
0ED30DDB27EA351C0057D8A3 /* Constants+Tunnel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ED30DDA27EA351C0057D8A3 /* Constants+Tunnel.swift */; };
|
0ED30DDB27EA351C0057D8A3 /* Constants+Tunnel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ED30DDA27EA351C0057D8A3 /* Constants+Tunnel.swift */; };
|
||||||
0ED30DDD27EA35230057D8A3 /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EB17EA127D2263700D473B5 /* Constants.swift */; };
|
0ED30DDD27EA35230057D8A3 /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0EB17EA127D2263700D473B5 /* Constants.swift */; };
|
||||||
|
@ -344,10 +344,10 @@
|
||||||
0E34AC7727F840890042F2AB /* OrganizerView+Scene.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "OrganizerView+Scene.swift"; sourceTree = "<group>"; };
|
0E34AC7727F840890042F2AB /* OrganizerView+Scene.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "OrganizerView+Scene.swift"; sourceTree = "<group>"; };
|
||||||
0E34AC8127F892C40042F2AB /* OnDemandView+SSID.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "OnDemandView+SSID.swift"; sourceTree = "<group>"; };
|
0E34AC8127F892C40042F2AB /* OnDemandView+SSID.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "OnDemandView+SSID.swift"; sourceTree = "<group>"; };
|
||||||
0E35C099280E95BB0071FA35 /* ProviderProfileAvailability.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProviderProfileAvailability.swift; sourceTree = "<group>"; };
|
0E35C099280E95BB0071FA35 /* ProviderProfileAvailability.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProviderProfileAvailability.swift; sourceTree = "<group>"; };
|
||||||
|
0E3A3C0F2AA9AA530003A5F6 /* KeyValueStore+CloudKit.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "KeyValueStore+CloudKit.swift"; sourceTree = "<group>"; };
|
||||||
0E3A3C112AAB7C470003A5F6 /* UpgradeManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UpgradeManager.swift; sourceTree = "<group>"; };
|
0E3A3C112AAB7C470003A5F6 /* UpgradeManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UpgradeManager.swift; sourceTree = "<group>"; };
|
||||||
0E3A3C122AAB7C480003A5F6 /* DefaultUpgradeManagerStrategy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DefaultUpgradeManagerStrategy.swift; sourceTree = "<group>"; };
|
0E3A3C122AAB7C480003A5F6 /* DefaultUpgradeManagerStrategy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DefaultUpgradeManagerStrategy.swift; sourceTree = "<group>"; };
|
||||||
0E3A3C152AAB8AB80003A5F6 /* UpgradeManagerStrategy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UpgradeManagerStrategy.swift; sourceTree = "<group>"; };
|
0E3A3C152AAB8AB80003A5F6 /* UpgradeManagerStrategy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UpgradeManagerStrategy.swift; sourceTree = "<group>"; };
|
||||||
0E3A3C0F2AA9AA530003A5F6 /* KeyValueStore+CloudKit.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "KeyValueStore+CloudKit.swift"; sourceTree = "<group>"; };
|
|
||||||
0E3A593B2A50975700B3FE40 /* ErrorHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ErrorHandler.swift; sourceTree = "<group>"; };
|
0E3A593B2A50975700B3FE40 /* ErrorHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ErrorHandler.swift; sourceTree = "<group>"; };
|
||||||
0E3B7FCC27E47B3700C66F13 /* AddHostView+Name.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AddHostView+Name.swift"; sourceTree = "<group>"; };
|
0E3B7FCC27E47B3700C66F13 /* AddHostView+Name.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AddHostView+Name.swift"; sourceTree = "<group>"; };
|
||||||
0E3B7FD527E5173A00C66F13 /* ProfileView+VPN.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ProfileView+VPN.swift"; sourceTree = "<group>"; };
|
0E3B7FD527E5173A00C66F13 /* ProfileView+VPN.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ProfileView+VPN.swift"; sourceTree = "<group>"; };
|
||||||
|
@ -497,7 +497,7 @@
|
||||||
0ED2B34A27D3C77800FD8EA9 /* PassepartoutWireGuardTunnel.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = PassepartoutWireGuardTunnel.appex; sourceTree = BUILT_PRODUCTS_DIR; };
|
0ED2B34A27D3C77800FD8EA9 /* PassepartoutWireGuardTunnel.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = PassepartoutWireGuardTunnel.appex; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
0ED2B35A27D3C94F00FD8EA9 /* PacketTunnelProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PacketTunnelProvider.swift; sourceTree = "<group>"; };
|
0ED2B35A27D3C94F00FD8EA9 /* PacketTunnelProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PacketTunnelProvider.swift; sourceTree = "<group>"; };
|
||||||
0ED30DCB27EA197C0057D8A3 /* RevealingSecureField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RevealingSecureField.swift; sourceTree = "<group>"; };
|
0ED30DCB27EA197C0057D8A3 /* RevealingSecureField.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RevealingSecureField.swift; sourceTree = "<group>"; };
|
||||||
0ED30DCE27EA1EF80057D8A3 /* PaywallView+Beta.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "PaywallView+Beta.swift"; sourceTree = "<group>"; };
|
0ED30DCE27EA1EF80057D8A3 /* PaywallView+Restricted.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "PaywallView+Restricted.swift"; sourceTree = "<group>"; };
|
||||||
0ED30DD127EA1F650057D8A3 /* PaywallView+Purchase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "PaywallView+Purchase.swift"; sourceTree = "<group>"; };
|
0ED30DD127EA1F650057D8A3 /* PaywallView+Purchase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "PaywallView+Purchase.swift"; sourceTree = "<group>"; };
|
||||||
0ED30DDA27EA351C0057D8A3 /* Constants+Tunnel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Constants+Tunnel.swift"; sourceTree = "<group>"; };
|
0ED30DDA27EA351C0057D8A3 /* Constants+Tunnel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Constants+Tunnel.swift"; sourceTree = "<group>"; };
|
||||||
0ED31C3920CF39510027975F /* NetworkExtension.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = NetworkExtension.framework; path = System/Library/Frameworks/NetworkExtension.framework; sourceTree = SDKROOT; };
|
0ED31C3920CF39510027975F /* NetworkExtension.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = NetworkExtension.framework; path = System/Library/Frameworks/NetworkExtension.framework; sourceTree = SDKROOT; };
|
||||||
|
@ -676,8 +676,8 @@
|
||||||
0EF8C5A728213C510053CE89 /* OrganizerView+Profiles.swift */,
|
0EF8C5A728213C510053CE89 /* OrganizerView+Profiles.swift */,
|
||||||
0E34AC7727F840890042F2AB /* OrganizerView+Scene.swift */,
|
0E34AC7727F840890042F2AB /* OrganizerView+Scene.swift */,
|
||||||
0EF0FAF527DD0211007EB181 /* PaywallView.swift */,
|
0EF0FAF527DD0211007EB181 /* PaywallView.swift */,
|
||||||
0ED30DCE27EA1EF80057D8A3 /* PaywallView+Beta.swift */,
|
|
||||||
0ED30DD127EA1F650057D8A3 /* PaywallView+Purchase.swift */,
|
0ED30DD127EA1F650057D8A3 /* PaywallView+Purchase.swift */,
|
||||||
|
0ED30DCE27EA1EF80057D8A3 /* PaywallView+Restricted.swift */,
|
||||||
0E44689527B051C300A14CE4 /* ProfileView.swift */,
|
0E44689527B051C300A14CE4 /* ProfileView.swift */,
|
||||||
0E92D7C527F103300033CB7B /* ProfileView+Configuration.swift */,
|
0E92D7C527F103300033CB7B /* ProfileView+Configuration.swift */,
|
||||||
0E92D7C827F1042A0033CB7B /* ProfileView+Extra.swift */,
|
0E92D7C827F1042A0033CB7B /* ProfileView+Extra.swift */,
|
||||||
|
@ -1481,7 +1481,7 @@
|
||||||
0E3A3C132AAB7C480003A5F6 /* UpgradeManager.swift in Sources */,
|
0E3A3C132AAB7C480003A5F6 /* UpgradeManager.swift in Sources */,
|
||||||
0E96D3052872010A005EFBCF /* DefaultLightVPNManager.swift in Sources */,
|
0E96D3052872010A005EFBCF /* DefaultLightVPNManager.swift in Sources */,
|
||||||
0EBE880F281B18DE0090D9E6 /* OrganizerView+ProfileRow.swift in Sources */,
|
0EBE880F281B18DE0090D9E6 /* OrganizerView+ProfileRow.swift in Sources */,
|
||||||
0ED30DCF27EA1EF80057D8A3 /* PaywallView+Beta.swift in Sources */,
|
0ED30DCF27EA1EF80057D8A3 /* PaywallView+Restricted.swift in Sources */,
|
||||||
0ECF71EE27B6A99300CDB528 /* AccountView.swift in Sources */,
|
0ECF71EE27B6A99300CDB528 /* AccountView.swift in Sources */,
|
||||||
0E71ACF727C107CA00F85C4B /* DebugLogView.swift in Sources */,
|
0E71ACF727C107CA00F85C4B /* DebugLogView.swift in Sources */,
|
||||||
0EF0FAF927DD212C007EB181 /* IntentActivity.swift in Sources */,
|
0EF0FAF927DD212C007EB181 /* IntentActivity.swift in Sources */,
|
||||||
|
|
|
@ -39,10 +39,6 @@ extension Constants {
|
||||||
static let appStoreId: String = bundleConfig("appstore_id")
|
static let appStoreId: String = bundleConfig("appstore_id")
|
||||||
|
|
||||||
static let appGroupId: String = bundleConfig("group_id")
|
static let appGroupId: String = bundleConfig("group_id")
|
||||||
|
|
||||||
static let isBeta: Bool = {
|
|
||||||
Bundle.main.isTestFlight
|
|
||||||
}()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
enum CloudKit {
|
enum CloudKit {
|
||||||
|
@ -56,7 +52,7 @@ extension Constants {
|
||||||
}
|
}
|
||||||
|
|
||||||
enum InApp {
|
enum InApp {
|
||||||
static var appType: ProductManager.AppType {
|
static var overriddenAppType: ProductManager.AppType? {
|
||||||
if let envString = ProcessInfo.processInfo.environment["APP_TYPE"],
|
if let envString = ProcessInfo.processInfo.environment["APP_TYPE"],
|
||||||
let envValue = Int(envString),
|
let envValue = Int(envString),
|
||||||
let testAppType = ProductManager.AppType(rawValue: envValue) {
|
let testAppType = ProductManager.AppType(rawValue: envValue) {
|
||||||
|
@ -68,7 +64,7 @@ extension Constants {
|
||||||
|
|
||||||
return testAppType
|
return testAppType
|
||||||
}
|
}
|
||||||
return App.isBeta ? .beta : .freemium
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
#if targetEnvironment(macCatalyst)
|
#if targetEnvironment(macCatalyst)
|
||||||
|
|
|
@ -43,7 +43,7 @@ final class AppContext {
|
||||||
self.coreContext = coreContext
|
self.coreContext = coreContext
|
||||||
|
|
||||||
productManager = ProductManager(
|
productManager = ProductManager(
|
||||||
appType: Constants.InApp.appType,
|
overriddenAppType: Constants.InApp.overriddenAppType,
|
||||||
buildProducts: Constants.InApp.buildProducts
|
buildProducts: Constants.InApp.buildProducts
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -29,21 +29,40 @@ import Kvitto
|
||||||
import PassepartoutLibrary
|
import PassepartoutLibrary
|
||||||
import StoreKit
|
import StoreKit
|
||||||
|
|
||||||
|
@MainActor
|
||||||
final class ProductManager: NSObject, ObservableObject {
|
final class ProductManager: NSObject, ObservableObject {
|
||||||
enum AppType: Int {
|
enum AppType: Int {
|
||||||
|
case undefined = -1
|
||||||
|
|
||||||
case freemium = 0
|
case freemium = 0
|
||||||
|
|
||||||
case beta = 1
|
case beta = 1
|
||||||
|
|
||||||
case fullVersion = 2
|
case fullVersion = 2
|
||||||
|
|
||||||
|
var isRestricted: Bool {
|
||||||
|
switch self {
|
||||||
|
case .undefined, .beta:
|
||||||
|
return true
|
||||||
|
|
||||||
|
default:
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let appType: AppType
|
private let overriddenAppType: AppType?
|
||||||
|
|
||||||
|
private let sandboxChecker: SandboxChecker
|
||||||
|
|
||||||
|
private var subscriptions: Set<AnyCancellable>
|
||||||
|
|
||||||
let buildProducts: BuildProducts
|
let buildProducts: BuildProducts
|
||||||
|
|
||||||
let didRefundProducts = PassthroughSubject<Void, Never>()
|
let didRefundProducts = PassthroughSubject<Void, Never>()
|
||||||
|
|
||||||
|
@Published private(set) var appType: AppType
|
||||||
|
|
||||||
@Published private(set) var isRefreshingProducts = false
|
@Published private(set) var isRefreshingProducts = false
|
||||||
|
|
||||||
@Published private(set) var products: [SKProduct]
|
@Published private(set) var products: [SKProduct]
|
||||||
|
@ -73,10 +92,14 @@ final class ProductManager: NSObject, ObservableObject {
|
||||||
|
|
||||||
private var refreshRequest: SKReceiptRefreshRequest?
|
private var refreshRequest: SKReceiptRefreshRequest?
|
||||||
|
|
||||||
init(appType: AppType, buildProducts: BuildProducts) {
|
init(overriddenAppType: AppType?, buildProducts: BuildProducts) {
|
||||||
self.appType = appType
|
self.overriddenAppType = overriddenAppType
|
||||||
self.buildProducts = buildProducts
|
self.buildProducts = buildProducts
|
||||||
|
|
||||||
|
appType = .undefined
|
||||||
|
sandboxChecker = SandboxChecker(bundle: .main)
|
||||||
|
subscriptions = []
|
||||||
|
|
||||||
products = []
|
products = []
|
||||||
inApp = InApp()
|
inApp = InApp()
|
||||||
purchasedAppBuild = nil
|
purchasedAppBuild = nil
|
||||||
|
@ -88,8 +111,20 @@ final class ProductManager: NSObject, ObservableObject {
|
||||||
|
|
||||||
reloadReceipt()
|
reloadReceipt()
|
||||||
SKPaymentQueue.default().add(self)
|
SKPaymentQueue.default().add(self)
|
||||||
|
|
||||||
refreshProducts()
|
refreshProducts()
|
||||||
|
|
||||||
|
sandboxChecker.$isSandbox
|
||||||
|
.dropFirst() // ignore initial value
|
||||||
|
.sink { [weak self] in
|
||||||
|
guard let self else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
self.appType = overriddenAppType ?? ($0 ? .beta : .freemium)
|
||||||
|
pp_log.info("App type: \(self.appType)")
|
||||||
|
self.reloadReceipt()
|
||||||
|
}.store(in: &subscriptions)
|
||||||
|
|
||||||
|
sandboxChecker.check()
|
||||||
}
|
}
|
||||||
|
|
||||||
deinit {
|
deinit {
|
||||||
|
@ -294,7 +329,7 @@ private extension ProductManager {
|
||||||
let receipt = Receipt(contentsOfURL: url)
|
let receipt = Receipt(contentsOfURL: url)
|
||||||
|
|
||||||
// in TestFlight, attempt fallback to existing release receipt
|
// in TestFlight, attempt fallback to existing release receipt
|
||||||
if Bundle.main.isTestFlight {
|
if appType == .beta {
|
||||||
guard let receipt else {
|
guard let receipt else {
|
||||||
let releaseUrl = url.deletingLastPathComponent().appendingPathComponent("receipt")
|
let releaseUrl = url.deletingLastPathComponent().appendingPathComponent("receipt")
|
||||||
guard releaseUrl != url else {
|
guard releaseUrl != url else {
|
||||||
|
|
|
@ -47,6 +47,8 @@ struct PassepartoutApp: App {
|
||||||
}
|
}
|
||||||
|
|
||||||
private extension View {
|
private extension View {
|
||||||
|
|
||||||
|
@MainActor
|
||||||
func onIntentActivity(_ activity: IntentActivity<VPNManager>) -> some View {
|
func onIntentActivity(_ activity: IntentActivity<VPNManager>) -> some View {
|
||||||
onContinueUserActivity(activity.name) { userActivity in
|
onContinueUserActivity(activity.name) { userActivity in
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
//
|
//
|
||||||
// PaywallView+Beta.swift
|
// PaywallView+Restricted.swift
|
||||||
// Passepartout
|
// Passepartout
|
||||||
//
|
//
|
||||||
// Created by Davide De Rosa on 3/22/22.
|
// Created by Davide De Rosa on 3/22/22.
|
||||||
|
@ -26,11 +26,12 @@
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
extension PaywallView {
|
extension PaywallView {
|
||||||
struct BetaView: View {
|
struct RestrictedView: View {
|
||||||
var body: some View {
|
var body: some View {
|
||||||
Text("The requested feature in unavailable in beta.")
|
Text("The requested feature in unavailable in this build.")
|
||||||
.navigationTitle("Beta")
|
.multilineTextAlignment(.center)
|
||||||
.padding()
|
.padding()
|
||||||
|
.navigationTitle("Restricted")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -51,8 +51,8 @@ struct PaywallView: View {
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
Group {
|
Group {
|
||||||
if productManager.appType == .beta {
|
if productManager.appType.isRestricted {
|
||||||
BetaView()
|
RestrictedView()
|
||||||
} else {
|
} else {
|
||||||
PurchaseView(
|
PurchaseView(
|
||||||
isPresented: $isPresented,
|
isPresented: $isPresented,
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
//
|
//
|
||||||
// Utils+TestFlight.swift
|
// SandboxChecker.swift
|
||||||
// Passepartout
|
// Passepartout
|
||||||
//
|
//
|
||||||
// Created by Davide De Rosa on 5/18/22.
|
// Created by Davide De Rosa on 5/18/22.
|
||||||
|
@ -28,19 +28,35 @@ import Foundation
|
||||||
// https://stackoverflow.com/a/32238344/784615
|
// https://stackoverflow.com/a/32238344/784615
|
||||||
// https://gist.github.com/lukaskubanek/cbfcab29c0c93e0e9e0a16ab09586996
|
// https://gist.github.com/lukaskubanek/cbfcab29c0c93e0e9e0a16ab09586996
|
||||||
|
|
||||||
extension Bundle {
|
@MainActor
|
||||||
public var isTestFlight: Bool {
|
public final class SandboxChecker: ObservableObject {
|
||||||
#if targetEnvironment(simulator)
|
private let bundle: Bundle
|
||||||
true
|
|
||||||
|
@Published public private(set) var isSandbox = false
|
||||||
|
|
||||||
|
public init(bundle: Bundle) {
|
||||||
|
self.bundle = bundle
|
||||||
|
}
|
||||||
|
|
||||||
|
public func check() {
|
||||||
|
Task {
|
||||||
|
isSandbox = await isSandboxBuild()
|
||||||
|
pp_log.info("Sandbox build: \(isSandbox)")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func isSandboxBuild() async -> Bool {
|
||||||
|
#if os(iOS)
|
||||||
|
bundle.appStoreReceiptURL?.lastPathComponent == "sandboxReceipt"
|
||||||
#elseif targetEnvironment(macCatalyst) || os(macOS)
|
#elseif targetEnvironment(macCatalyst) || os(macOS)
|
||||||
var status = noErr
|
var status = noErr
|
||||||
|
|
||||||
var code: SecStaticCode?
|
var code: SecStaticCode?
|
||||||
status = SecStaticCodeCreateWithPath(bundleURL as CFURL, [], &code)
|
status = SecStaticCodeCreateWithPath(bundle.bundleURL as CFURL, [], &code)
|
||||||
guard status == noErr else {
|
guard status == noErr else {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
guard let code = code else {
|
guard let code else {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,7 +69,7 @@ extension Bundle {
|
||||||
guard status == noErr else {
|
guard status == noErr else {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
guard let requirement = requirement else {
|
guard let requirement else {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,8 +79,6 @@ extension Bundle {
|
||||||
requirement
|
requirement
|
||||||
)
|
)
|
||||||
return status == errSecSuccess
|
return status == errSecSuccess
|
||||||
#elseif os(iOS)
|
|
||||||
appStoreReceiptURL?.lastPathComponent == "sandboxReceipt"
|
|
||||||
#else
|
#else
|
||||||
false
|
false
|
||||||
#endif
|
#endif
|
Loading…
Reference in New Issue