Skip to content

Commit

Permalink
Remove PackageGroup (#4413)
Browse files Browse the repository at this point in the history
* Improved JSON format for ButtonComponent codables

* Started to remove PackageGroup

* Removed PackageGroup and added Template 5 SwiftUI preview

* Remove PackageGroup

* Fixed some thread, lint, and selection stuff

* Made renames and some code improvements
  • Loading branch information
joshdholtz authored Oct 31, 2024
1 parent 3dfd43e commit ee3fb18
Show file tree
Hide file tree
Showing 20 changed files with 476 additions and 378 deletions.
28 changes: 8 additions & 20 deletions RevenueCat.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -20,19 +20,18 @@
2C0B98CD2797070B00C5874F /* PromotionalOffer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C0B98CC2797070B00C5874F /* PromotionalOffer.swift */; };
2C2AEB0F2CA64E0E00A50F38 /* Template1Preview.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C2AEB0E2CA64E0E00A50F38 /* Template1Preview.swift */; };
2C2AEB3B2CA7209F00A50F38 /* PaywallPackageComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C2AEB3A2CA7209F00A50F38 /* PaywallPackageComponent.swift */; };
2C2AEB3D2CA720B700A50F38 /* PaywallPackageGroupComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C2AEB3C2CA720B700A50F38 /* PaywallPackageGroupComponent.swift */; };
2C2AEB3F2CA7235300A50F38 /* PaywallPurchaseButtonComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C2AEB3E2CA7235300A50F38 /* PaywallPurchaseButtonComponent.swift */; };
2C4C36132C6FBA8B00AE959B /* CompatibilityTopBarTrailing.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C4C36122C6FBA8B00AE959B /* CompatibilityTopBarTrailing.swift */; };
2C6CC1162B8D2B6900432E4D /* PurchasesSyncAttributesAndOfferingsIfNeededTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C6CC1152B8D2B6800432E4D /* PurchasesSyncAttributesAndOfferingsIfNeededTests.swift */; };
2C7F0AD32B8EEB4600381179 /* RateLimiter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C7F0AD22B8EEB4600381179 /* RateLimiter.swift */; };
2C7F0AD62B8EEF7B00381179 /* RateLimiterRests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C7F0AD42B8EEF0B00381179 /* RateLimiterRests.swift */; };
2C8EC6AF2CCBD34100D6CCF8 /* ButtonComponent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C8EC6AE2CCBD33E00D6CCF8 /* ButtonComponent.swift */; };
2C8EC6DB2CCC23B700D6CCF8 /* Template5Preview.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C8EC6DA2CCC23B700D6CCF8 /* Template5Preview.swift */; };
2C8EC6DD2CCC7C5B00D6CCF8 /* PackageValidator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2C8EC6DC2CCC7C5500D6CCF8 /* PackageValidator.swift */; };
2CAB87F72CAAB13200247013 /* CornerBorder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2CAB87F62CAAB13200247013 /* CornerBorder.swift */; };
2CB8CF9327BF538F00C34DE3 /* PlatformInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2CB8CF9227BF538F00C34DE3 /* PlatformInfo.swift */; };
2CC791552CC0452100FBE120 /* PurchaseButtonComponentViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2CC791522CC0452100FBE120 /* PurchaseButtonComponentViewModel.swift */; };
2CC791562CC0452100FBE120 /* PackageComponentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2CC7914B2CC0452100FBE120 /* PackageComponentView.swift */; };
2CC791572CC0452100FBE120 /* PackageGroupComponentViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2CC7914F2CC0452100FBE120 /* PackageGroupComponentViewModel.swift */; };
2CC791582CC0452100FBE120 /* PackageGroupComponentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2CC7914E2CC0452100FBE120 /* PackageGroupComponentView.swift */; };
2CC791592CC0452100FBE120 /* PurchaseButtonComponentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2CC791512CC0452100FBE120 /* PurchaseButtonComponentView.swift */; };
2CC7915A2CC0452100FBE120 /* PackageComponentViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2CC7914C2CC0452100FBE120 /* PackageComponentViewModel.swift */; };
2CC791622CC0493600FBE120 /* PaywallComponentPropertyTypes.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2CC7915F2CC0493600FBE120 /* PaywallComponentPropertyTypes.swift */; };
Expand Down Expand Up @@ -1177,7 +1176,6 @@
2C0B98CC2797070B00C5874F /* PromotionalOffer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PromotionalOffer.swift; sourceTree = "<group>"; };
2C2AEB0E2CA64E0E00A50F38 /* Template1Preview.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Template1Preview.swift; sourceTree = "<group>"; };
2C2AEB3A2CA7209F00A50F38 /* PaywallPackageComponent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaywallPackageComponent.swift; sourceTree = "<group>"; };
2C2AEB3C2CA720B700A50F38 /* PaywallPackageGroupComponent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PaywallPackageGroupComponent.swift; sourceTree = "<group>"; };
2C2AEB3E2CA7235300A50F38 /* PaywallPurchaseButtonComponent.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PaywallPurchaseButtonComponent.swift; sourceTree = "<group>"; };
2C4C36122C6FBA8B00AE959B /* CompatibilityTopBarTrailing.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CompatibilityTopBarTrailing.swift; sourceTree = "<group>"; };
2C5F71F52C3D6C2600B0FE4B /* header.heic */ = {isa = PBXFileReference; lastKnownFileType = file; path = header.heic; sourceTree = "<group>"; };
Expand All @@ -1187,12 +1185,12 @@
2C7F0AD22B8EEB4600381179 /* RateLimiter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RateLimiter.swift; sourceTree = "<group>"; };
2C7F0AD42B8EEF0B00381179 /* RateLimiterRests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RateLimiterRests.swift; sourceTree = "<group>"; };
2C8EC6AE2CCBD33E00D6CCF8 /* ButtonComponent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ButtonComponent.swift; sourceTree = "<group>"; };
2C8EC6DA2CCC23B700D6CCF8 /* Template5Preview.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Template5Preview.swift; sourceTree = "<group>"; };
2C8EC6DC2CCC7C5500D6CCF8 /* PackageValidator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PackageValidator.swift; sourceTree = "<group>"; };
2CAB87F62CAAB13200247013 /* CornerBorder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CornerBorder.swift; sourceTree = "<group>"; };
2CB8CF9227BF538F00C34DE3 /* PlatformInfo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlatformInfo.swift; sourceTree = "<group>"; };
2CC7914B2CC0452100FBE120 /* PackageComponentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PackageComponentView.swift; sourceTree = "<group>"; };
2CC7914C2CC0452100FBE120 /* PackageComponentViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PackageComponentViewModel.swift; sourceTree = "<group>"; };
2CC7914E2CC0452100FBE120 /* PackageGroupComponentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PackageGroupComponentView.swift; sourceTree = "<group>"; };
2CC7914F2CC0452100FBE120 /* PackageGroupComponentViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PackageGroupComponentViewModel.swift; sourceTree = "<group>"; };
2CC791512CC0452100FBE120 /* PurchaseButtonComponentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PurchaseButtonComponentView.swift; sourceTree = "<group>"; };
2CC791522CC0452100FBE120 /* PurchaseButtonComponentViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PurchaseButtonComponentViewModel.swift; sourceTree = "<group>"; };
2CC7915B2CC0493600FBE120 /* Border.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Border.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -2305,6 +2303,7 @@
isa = PBXGroup;
children = (
2C2AEB0E2CA64E0E00A50F38 /* Template1Preview.swift */,
2C8EC6DA2CCC23B700D6CCF8 /* Template5Preview.swift */,
);
path = TemplateComponentsViewPreviews;
sourceTree = "<group>";
Expand Down Expand Up @@ -2333,15 +2332,6 @@
path = Package;
sourceTree = "<group>";
};
2CC791502CC0452100FBE120 /* PackageGroup */ = {
isa = PBXGroup;
children = (
2CC7914E2CC0452100FBE120 /* PackageGroupComponentView.swift */,
2CC7914F2CC0452100FBE120 /* PackageGroupComponentViewModel.swift */,
);
path = PackageGroup;
sourceTree = "<group>";
};
2CC791532CC0452100FBE120 /* PurchaseButton */ = {
isa = PBXGroup;
children = (
Expand All @@ -2355,7 +2345,6 @@
isa = PBXGroup;
children = (
2CC7914D2CC0452100FBE120 /* Package */,
2CC791502CC0452100FBE120 /* PackageGroup */,
2CC791532CC0452100FBE120 /* PurchaseButton */,
);
path = Packages;
Expand Down Expand Up @@ -4423,7 +4412,6 @@
8893C9B42C7D1F090060B030 /* PaywallLinkButtonComponent.swift */,
88AD01072C740CF400AA1F2B /* PaywallTextComponent.swift */,
2C2AEB3A2CA7209F00A50F38 /* PaywallPackageComponent.swift */,
2C2AEB3C2CA720B700A50F38 /* PaywallPackageGroupComponent.swift */,
2C2AEB3E2CA7235300A50F38 /* PaywallPurchaseButtonComponent.swift */,
7783606C2CCA7E14000785B8 /* PaywallStickyFooterComponent.swift */,
);
Expand All @@ -4433,6 +4421,7 @@
88AD01352C74196600AA1F2B /* Components */ = {
isa = PBXGroup;
children = (
2C8EC6DC2CCC7C5500D6CCF8 /* PackageValidator.swift */,
778360772CCA85D1000785B8 /* StickyFooter */,
778360742CCA84FA000785B8 /* Root */,
88B1BAE72C813A3C001B7EE5 /* PaywallComponentTypeTransformers.swift */,
Expand Down Expand Up @@ -5588,7 +5577,6 @@
B35F9E0926B4BEED00095C3F /* String+Extensions.swift in Sources */,
574A2EE7282C3F0800150D40 /* AnyDecodable.swift in Sources */,
2C2AEB3F2CA7235300A50F38 /* PaywallPurchaseButtonComponent.swift in Sources */,
2C2AEB3D2CA720B700A50F38 /* PaywallPackageGroupComponent.swift in Sources */,
4FC883812AA7A2BD00A3DE03 /* ProcessInfo+Extensions.swift in Sources */,
57488B7F29CB70E50000EE7E /* ProductEntitlementMapping.swift in Sources */,
B34605CF279A6E380031CA74 /* GetOfferingsOperation.swift in Sources */,
Expand Down Expand Up @@ -6152,6 +6140,7 @@
887A606A2C1D037000E1A461 /* TrialOrIntroEligibilityChecker.swift in Sources */,
88B1BAEE2C813A3C001B7EE5 /* TextComponentView.swift in Sources */,
3546355F2C391F4D001D7E85 /* PromotionalOfferView.swift in Sources */,
2C8EC6DD2CCC7C5B00D6CCF8 /* PackageValidator.swift in Sources */,
778360792CCA85E4000785B8 /* StickyFooterComponentViewModel.swift in Sources */,
353756722C382C2800A1B8D6 /* URLUtilities.swift in Sources */,
353FDC0F2CA446FA0055F328 /* StoreProductDiscount+Extensions.swift in Sources */,
Expand Down Expand Up @@ -6220,6 +6209,7 @@
887A60832C1D037000E1A461 /* VersionDetector.swift in Sources */,
88B1BAFC2C813A3C001B7EE5 /* ImageComponentView.swift in Sources */,
887A60872C1D037000E1A461 /* ViewExtensions.swift in Sources */,
2C8EC6DB2CCC23B700D6CCF8 /* Template5Preview.swift in Sources */,
88B1BB022C813A3C001B7EE5 /* StackComponentView.swift in Sources */,
353756712C382C2800A1B8D6 /* ManageSubscriptionsPurchaseType.swift in Sources */,
35C200AF2C39252D00B9778B /* FeedbackSurveyData.swift in Sources */,
Expand All @@ -6237,8 +6227,6 @@
887A60BF2C1D037000E1A461 /* PaywallViewController.swift in Sources */,
2CC791552CC0452100FBE120 /* PurchaseButtonComponentViewModel.swift in Sources */,
2CC791562CC0452100FBE120 /* PackageComponentView.swift in Sources */,
2CC791572CC0452100FBE120 /* PackageGroupComponentViewModel.swift in Sources */,
2CC791582CC0452100FBE120 /* PackageGroupComponentView.swift in Sources */,
2CC791592CC0452100FBE120 /* PurchaseButtonComponentView.swift in Sources */,
2CC7915A2CC0452100FBE120 /* PackageComponentViewModel.swift in Sources */,
887A60772C1D037000E1A461 /* TemplateViewConfiguration+Images.swift in Sources */,
Expand Down
6 changes: 3 additions & 3 deletions RevenueCatUI/Data/Strings.swift
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ enum Strings {
case paywall_contains_no_localization_data
case paywall_could_not_find_localization(String)
case paywall_could_not_find_package(String)
case paywall_could_not_find_default_package(String)
case paywall_could_not_find_default_package
case paywall_could_not_find_any_packages
case paywall_invalid_url(String)
case no_in_app_browser_tvos
Expand Down Expand Up @@ -175,8 +175,8 @@ extension Strings: CustomStringConvertible {
"This could be caused by a package that doesn't have a product on this platform or the product might not " +
" be available for this region."

case .paywall_could_not_find_default_package(let identifier):
return "Could not find default package \(identifier) for paywall. Using first package instead. " +
case .paywall_could_not_find_default_package:
return "Could not find default package for paywall. Using first package instead. " +
"This package will not show in the paywall. This could be caused by a package that doesn't have a " +
"product on this platform or the product might not be available for this region."

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ struct ButtonComponentView_Previews: PreviewProvider {
ButtonComponentView(
// swiftlint:disable:next force_try
viewModel: try! .init(
packageValidator: PackageValidator(),
component: .init(
action: .navigateBack,
stack: .init(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,15 @@ public class ButtonComponentViewModel {
let stackViewModel: StackComponentViewModel

init(
packageValidator: PackageValidator,
component: PaywallComponent.ButtonComponent,
localizedStrings: PaywallComponent.LocalizationDictionary,
offering: Offering
) throws {
self.component = component
self.localizedStrings = localizedStrings
self.stackViewModel = try StackComponentViewModel(
packageValidator: packageValidator,
component: component.stack,
localizedStrings: localizedStrings,
offering: offering
Expand Down
50 changes: 50 additions & 0 deletions RevenueCatUI/Templates/Components/PackageValidator.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
//
// Copyright RevenueCat Inc. All Rights Reserved.
//
// Licensed under the MIT License (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://opensource.org/licenses/MIT
//
// PackageValidator.swift
//
// Created by Josh Holtz on 10/25/24.

import Foundation
import RevenueCat

#if PAYWALL_COMPONENTS

@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *)
class PackageValidator {

typealias PackageInfo = (package: Package, isSelectedByDefault: Bool)

private var packageInfos: [PackageInfo] = []

func add(_ package: Package, isSelectedByDefault: Bool) {
self.packageInfos.append((package, isSelectedByDefault))
}

var isValid: Bool {
!packageInfos.isEmpty
}

var defaultSelectedPackage: Package? {
let defaultSelectedPackage = packageInfos.first(where: { pkg in
return pkg.isSelectedByDefault
})

// Set selected package
if let defaultSelectedPackage {
return defaultSelectedPackage.package
}

Logger.warning(Strings.paywall_could_not_find_default_package)
return packageInfos.first?.package
}

}

#endif
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,18 @@ struct PackageComponentView: View {
let onDismiss: () -> Void

var body: some View {
// WIP: Do something with package id and selection
StackComponentView(viewModel: self.viewModel.stackViewModel,
onDismiss: self.onDismiss)
if let package = self.viewModel.package {
Button {
self.paywallState.select(package: package)
} label: {
StackComponentView(
viewModel: self.viewModel.stackViewModel,
onDismiss: self.onDismiss
)
}
} else {
EmptyView()
}
}

}
Expand Down Expand Up @@ -78,18 +87,19 @@ struct PackageComponentView_Previews: PreviewProvider {
PackageComponentView(
// swiftlint:disable:next force_try
viewModel: try! .init(
packageValidator: PackageValidator(),
localizedStrings: [
"name": .string("Weekly"),
"detail": .string("Get for $39.99/wk")
],
component: .init(
packageID: "weekly",
isSelectedByDefault: false,
stack: stack
),
offering: .init(identifier: "default",
serverDescription: "",
availablePackages: [package]),
package: package
availablePackages: [package])
), onDismiss: {}
)
.previewLayout(.sizeThatFits)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,19 +23,26 @@ class PackageComponentViewModel {
private let component: PaywallComponent.PackageComponent
private let offering: Offering

let package: Package
let isSelectedByDefault: Bool
let package: Package?
let stackViewModel: StackComponentViewModel

init(localizedStrings: PaywallComponent.LocalizationDictionary,
init(packageValidator: PackageValidator,
localizedStrings: PaywallComponent.LocalizationDictionary,
component: PaywallComponent.PackageComponent,
offering: Offering,
package: Package) throws {
offering: Offering) throws {
self.localizedStrings = localizedStrings
self.component = component
self.offering = offering
self.package = package

self.isSelectedByDefault = component.isSelectedByDefault
self.package = offering.package(identifier: component.packageID)
if package == nil {
Logger.warning(Strings.paywall_could_not_find_package(component.packageID))
}

self.stackViewModel = try StackComponentViewModel(
packageValidator: packageValidator,
component: component.stack,
localizedStrings: localizedStrings,
offering: offering
Expand Down
Loading

0 comments on commit ee3fb18

Please sign in to comment.