Merge branch 'drop-single-features'

This commit is contained in:
Davide De Rosa 2021-02-07 15:40:11 +01:00
commit c3c3339878
9 changed files with 72 additions and 75 deletions

View File

@ -67,7 +67,7 @@ extension UIViewController {
func presentPurchaseScreen(forProduct product: Product, delegate: PurchaseViewControllerDelegate? = nil) {
let nav = StoryboardScene.Purchase.initialScene.instantiate()
let vc = nav.topViewController as? PurchaseViewController
vc?.feature = product
// vc?.feature = product
vc?.delegate = delegate
// enforce pre iOS 13 behavior

View File

@ -230,7 +230,7 @@ extension WizardProviderViewController: AccountViewControllerDelegate {
// MARK: -
extension WizardProviderViewController: PurchaseViewControllerDelegate {
func purchaseController(_ purchaseController: PurchaseViewController, didPurchase product: Product) {
func purchaseController(_ purchaseController: PurchaseViewController, didPurchase product: Product?) {
guard let metadata = selectedMetadata else {
return
}

View File

@ -32,13 +32,13 @@ import Convenience
private let log = SwiftyBeaver.self
protocol PurchaseViewControllerDelegate: class {
func purchaseController(_ purchaseController: PurchaseViewController, didPurchase product: Product)
func purchaseController(_ purchaseController: PurchaseViewController, didPurchase product: Product?)
}
class PurchaseViewController: UITableViewController, StrongTableHost {
private var isLoading = true
var feature: Product!
var feature: Product?
weak var delegate: PurchaseViewControllerDelegate?
@ -66,29 +66,27 @@ class PurchaseViewController: UITableViewController, StrongTableHost {
if let skPlatformVersion = pm.product(withIdentifier: .fullVersion_iOS) {
self.skPlatformVersion = skPlatformVersion
rows.append(.platformVersion)
let bullets: [String] = ProductManager.shared.featureProducts(excluding: [.fullVersion, .fullVersion_iOS, .fullVersion_macOS]).map {
return $0.localizedTitle
}.sortedCaseInsensitive()
platformVersionExtra = bullets.joined(separator: "\n")
}
if let skFullVersion = pm.product(withIdentifier: .fullVersion) {
if !pm.hasPurchased(.fullVersion_macOS), let skFullVersion = pm.product(withIdentifier: .fullVersion) {
self.skFullVersion = skFullVersion
rows.append(.fullVersion)
let bullets: [String] = ProductManager.shared.featureProducts(including: [.fullVersion_iOS, .fullVersion_macOS]).map {
return $0.localizedTitle
}.sortedCaseInsensitive()
fullVersionExtra = bullets.joined(separator: "\n")
}
if let skFeature = pm.product(withIdentifier: feature) {
if let feature = feature, let skFeature = pm.product(withIdentifier: feature) {
self.skFeature = skFeature
rows.append(.feature)
}
rows.append(.restore)
model.set(rows, forSection: .products)
let platformBulletsList: [String] = ProductManager.shared.featureProducts(excluding: [.fullVersion, .fullVersion_iOS, .fullVersion_macOS]).map {
return "- \($0.localizedTitle)"
}.sortedCaseInsensitive()
let platformBullets = platformBulletsList.joined(separator: "\n")
platformVersionExtra = "- \(L10n.Core.Purchase.Cells.FullVersion.extraDescription(platformBullets))"
let fullBulletsList: [String] = ProductManager.shared.featureProducts(excluding: [.fullVersion, .fullVersion_iOS]).map {
return "- \($0.localizedTitle)"
}.sortedCaseInsensitive()
let fullBullets = fullBulletsList.joined(separator: "\n")
fullVersionExtra = "- \(L10n.Core.Purchase.Cells.FullVersion.extraDescription(fullBullets))"
}
// MARK: UIViewController
@ -96,10 +94,6 @@ class PurchaseViewController: UITableViewController, StrongTableHost {
override func viewDidLoad() {
super.viewDidLoad()
guard let _ = feature else {
fatalError("No feature set for purchase")
}
title = L10n.Core.Purchase.title
navigationItem.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: .stop, target: self, action: #selector(close))
@ -168,7 +162,7 @@ class PurchaseViewController: UITableViewController, StrongTableHost {
guard let weakSelf = self else {
return
}
let product = weakSelf.feature.matchesStoreKitProduct(skProduct) ? weakSelf.feature! : .fullVersion
let product = Product(rawValue: skProduct.productIdentifier)
weakSelf.delegate?.purchaseController(weakSelf, didPurchase: product)
}
}

View File

@ -93,7 +93,7 @@ extension NSAlert {
extension NSViewController {
func presentPurchaseScreen(forProduct product: Product, delegate: PurchaseViewControllerDelegate? = nil) {
let vc = StoryboardScene.Purchase.initialScene.instantiate()
vc.feature = product
// vc.feature = product
vc.delegate = delegate
presentAsModalWindow(vc)
}

View File

@ -32,7 +32,7 @@ import Convenience
private let log = SwiftyBeaver.self
protocol PurchaseViewControllerDelegate: class {
func purchaseController(_ purchaseController: PurchaseViewController, didPurchase product: Product)
func purchaseController(_ purchaseController: PurchaseViewController, didPurchase product: Product?)
}
class PurchaseViewController: NSViewController {
@ -52,7 +52,7 @@ class PurchaseViewController: NSViewController {
@IBOutlet private weak var buttonRestore: NSButton!
var feature: Product!
var feature: Product?
weak var delegate: PurchaseViewControllerDelegate?
@ -74,27 +74,25 @@ class PurchaseViewController: NSViewController {
if let skPlatformVersion = pm.product(withIdentifier: .fullVersion_macOS) {
self.skPlatformVersion = skPlatformVersion
rows.append(.platformVersion)
let bullets: [String] = ProductManager.shared.featureProducts(excluding: [.fullVersion, .fullVersion_iOS, .fullVersion_macOS, .siriShortcuts]).map {
return $0.localizedTitle
}.sortedCaseInsensitive()
platformVersionExtra = bullets.joined(separator: "\n")
}
if let skFullVersion = pm.product(withIdentifier: .fullVersion) {
if !pm.hasPurchased(.fullVersion_iOS), let skFullVersion = pm.product(withIdentifier: .fullVersion) {
self.skFullVersion = skFullVersion
rows.append(.fullVersion)
let bullets: [String] = ProductManager.shared.featureProducts(including: [.fullVersion_iOS, .fullVersion_macOS]).map {
return $0.localizedTitle
}.sortedCaseInsensitive()
fullVersionExtra = bullets.joined(separator: "\n")
}
if let skFeature = pm.product(withIdentifier: feature) {
if let feature = feature, let skFeature = pm.product(withIdentifier: feature) {
self.skFeature = skFeature
rows.append(.feature)
}
let platformBulletsList: [String] = ProductManager.shared.featureProducts(excluding: [.siriShortcuts, .fullVersion, .fullVersion_iOS, .fullVersion_macOS]).map {
return $0.localizedTitle
}.sortedCaseInsensitive()
let platformBullets = platformBulletsList.joined(separator: "\n")
platformVersionExtra = L10n.Core.Purchase.Cells.FullVersion.extraDescription(platformBullets)
let fullBulletsList: [String] = ProductManager.shared.featureProducts(excluding: [.fullVersion, .fullVersion_macOS]).map {
return $0.localizedTitle
}.sortedCaseInsensitive()
let fullBullets = fullBulletsList.joined(separator: "\n")
fullVersionExtra = L10n.Core.Purchase.Cells.FullVersion.extraDescription(fullBullets)
}
// MARK: NSViewController
@ -108,10 +106,6 @@ class PurchaseViewController: NSViewController {
buttonPurchase.title = L10n.Core.Purchase.title
buttonRestore.title = L10n.Core.Purchase.Cells.Restore.title
guard let _ = feature else {
fatalError("No feature set for purchase")
}
tableView.usesAutomaticRowHeights = true
tableView.reloadData()
}
@ -197,7 +191,7 @@ class PurchaseViewController: NSViewController {
guard let weakSelf = self else {
return
}
let product = weakSelf.feature.matchesStoreKitProduct(skProduct) ? weakSelf.feature! : .fullVersion
let product = Product(rawValue: skProduct.productIdentifier)
weakSelf.delegate?.purchaseController(weakSelf, didPurchase: product)
self?.dismiss(nil)

View File

@ -108,7 +108,7 @@ class TrustedNetworksViewController: NSViewController, ProfileCustomization {
@IBAction private func toggleTrustEthernet(_ sender: Any?) {
do {
try ProductManager.shared.verifyEligibleForTrustedNetworks()
try ProductManager.shared.verifyEligible(forFeature: .trustedNetworks)
} catch {
checkTrustEthernet.state = .off
presentPurchaseScreen(forProduct: .trustedNetworks)
@ -132,7 +132,7 @@ class TrustedNetworksViewController: NSViewController, ProfileCustomization {
override func shouldPerformSegue(withIdentifier identifier: NSStoryboardSegue.Identifier, sender: Any?) -> Bool {
if identifier == StoryboardSegue.Service.trustedNetworkAddSegueIdentifier.rawValue {
do {
try ProductManager.shared.verifyEligibleForTrustedNetworks()
try ProductManager.shared.verifyEligible(forFeature: .trustedNetworks)
} catch {
presentPurchaseScreen(forProduct: .trustedNetworks)
return false

View File

@ -554,7 +554,7 @@ public class ConnectionService: Codable {
var rules: [NEOnDemandRule] = []
do {
try ProductManager.shared.verifyEligibleForTrustedNetworks()
try ProductManager.shared.verifyEligible(forFeature: .trustedNetworks)
#if os(iOS)
if profile.trustedNetworks.includesMobile {
let rule = policyRule(for: profile)

View File

@ -66,6 +66,8 @@ public struct Product: RawRepresentable, Equatable, Hashable {
// MARK: Features
public static let allProviders = Product(featureId: "all_providers")
public static let trustedNetworks = Product(featureId: "trusted_networks")
public static let siriShortcuts = Product(featureId: "siri")
@ -77,6 +79,7 @@ public struct Product: RawRepresentable, Equatable, Hashable {
public static let fullVersion = Product(featureId: "full_multi_version")
public static let allFeatures: [Product] = [
.allProviders,
.trustedNetworks,
.siriShortcuts,
.fullVersion_iOS,

View File

@ -126,6 +126,21 @@ public class ProductManager: NSObject {
return inApp.product(withIdentifier: identifier)
}
public func featureProducts(including: [Product]) -> [SKProduct] {
return inApp.products.filter {
guard let p = Product(rawValue: $0.productIdentifier) else {
return false
}
guard including.contains(p) else {
return false
}
guard p.isFeature else {
return false
}
return true
}
}
public func featureProducts(excluding: [Product]) -> [SKProduct] {
return inApp.products.filter {
guard let p = Product(rawValue: $0.productIdentifier) else {
@ -159,29 +174,30 @@ public class ProductManager: NSObject {
// MARK: In-app eligibility
public func isFullVersion() -> Bool {
private func isCurrentPlatformVersion() -> Bool {
#if os(iOS)
if (isBeta && cfg.isBetaFullVersion) || purchasedFeatures.contains(.fullVersion_iOS) {
return true
}
return purchasedFeatures.contains(.fullVersion_iOS)
#else
if (isBeta && cfg.isBetaFullVersion) || purchasedFeatures.contains(.fullVersion_macOS) {
return purchasedFeatures.contains(.fullVersion_macOS)
#endif
}
private func isFullVersion() -> Bool {
if isBeta && cfg.isBetaFullVersion {
return true
}
if isCurrentPlatformVersion() {
return true
}
#endif
return purchasedFeatures.contains(.fullVersion)
}
private func isEligible(forFeature feature: Product) -> Bool {
#if os(iOS)
return isFullVersion() || purchasedFeatures.contains(feature)
}
private func isEligible(forProvider metadata: Infrastructure.Metadata) -> Bool {
return isFullVersion() || purchasedFeatures.contains(metadata.product)
}
private func isEligibleForTrustedNetworks() -> Bool {
return isFullVersion() || purchasedFeatures.contains(.trustedNetworks)
#else
return isFullVersion()
#endif
}
public func isEligibleForFeedback() -> Bool {
@ -211,23 +227,13 @@ public class ProductManager: NSObject {
throw ProductError.beta
}
}
guard isFullVersion() || purchasedFeatures.contains(metadata.product) else {
guard isEligible(forFeature: metadata.product) else {
throw ProductError.uneligible
}
}
public func verifyEligibleForTrustedNetworks() throws {
if isBeta {
if cfg.isBetaFullVersion {
return
}
guard !cfg.locksBetaFeatures else {
throw ProductError.beta
}
}
guard isEligibleForTrustedNetworks() else {
throw ProductError.uneligible
}
public func hasPurchased(_ product: Product) -> Bool {
return purchasedFeatures.contains(product)
}
public func isCancelledPurchase(_ product: Product) -> Bool {