Skip to content

Commit

Permalink
Paywalls: finished iOS 15 support (#3043)
Browse files Browse the repository at this point in the history
  • Loading branch information
NachoSoto committed Aug 22, 2023
1 parent 095c0fd commit 0bbb6cd
Show file tree
Hide file tree
Showing 63 changed files with 120 additions and 47 deletions.
22 changes: 22 additions & 0 deletions RevenueCatUI/Helpers/VersionDetector.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
//
// VersionDetector.swift
//
//
// Created by Nacho Soto on 8/17/23.
//

import Foundation

enum VersionDetector {

static let iOS15: Bool = {
return Self.isAtLeast(version: 15) && !Self.isAtLeast(version: 16)
}()

private static func isAtLeast(version: Int) -> Bool {
return ProcessInfo.processInfo.isOperatingSystemAtLeast(.init(majorVersion: version,
minorVersion: 0,
patchVersion: 0))
}

}
5 changes: 3 additions & 2 deletions RevenueCatUI/Modifiers/CardHidingModifier.swift
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,10 @@ private struct CardHidingModifier: ViewModifier {
.padding(.vertical)

case .condensedCard:
// "Hidden view" so it doesn't contribute to size calculation
Rectangle()
// "Hidden view" so it doesn't contribute to size calculation
.frame(height: 0)
.frame(height: VersionDetector.iOS15 ? 1 : 0) // Note: height "0" breaks iOS 15
.hidden()
.frame(maxWidth: .infinity)
.overlay(alignment: .bottom) {
// Content is displayed as an overlay so it's rendered over user's content
Expand Down
72 changes: 67 additions & 5 deletions RevenueCatUI/Modifiers/ViewExtensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -52,21 +52,69 @@ extension View {

@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *)
@ViewBuilder
func scrollableIfNecessary(_ axes: Axis.Set = .vertical) -> some View {
func scrollableIfNecessary(_ axis: Axis = .vertical) -> some View {
if #available(iOS 16.0, macOS 13.0, tvOS 16.0, watchOS 9.0, *) {
ViewThatFits(in: axes) {
ViewThatFits(in: axis.scrollViewAxis) {
self

ScrollView(axes) {
ScrollView(axis.scrollViewAxis) {
self
}
}
} else {
ScrollView(axes) {
self
self.modifier(ScrollableIfNecessaryModifier(axis: axis))
}
}
}

// MARK: - scrollableIfNecessary

@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *)
private struct ScrollableIfNecessaryModifier: ViewModifier {

var axis: Axis

@State
private var overflowing: Bool = false

func body(content: Content) -> some View {
GeometryReader { geometry in
self.centeredContent(content)
.background(
GeometryReader { contentGeometry in
Color.clear
.onAppear {
switch self.axis {
case .horizontal:
self.overflowing = contentGeometry.size.width > geometry.size.width
case .vertical:
self.overflowing = contentGeometry.size.height > geometry.size.height
}
}
}
)
}
.scrollable(self.axis.scrollViewAxis, if: self.overflowing)
}

@ViewBuilder
private func centeredContent(_ content: Content) -> some View {
switch self.axis {
case .horizontal:
HStack {
Spacer()
content
Spacer()
}
case .vertical:
VStack {
Spacer()
content
Spacer()
}
}
}

}

// MARK: - Size changes
Expand Down Expand Up @@ -176,3 +224,17 @@ private struct ViewSizePreferenceKey: PreferenceKey {
}

}

// MARK: -

@available(iOS 13.0, tvOS 13.0, macOS 10.15, watchOS 6.2, *)
private extension Axis {

var scrollViewAxis: Axis.Set {
switch self {
case .horizontal: return .horizontal
case .vertical: return .vertical
}
}

}
2 changes: 1 addition & 1 deletion RevenueCatUI/PaywallView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import SwiftUI
///
/// ### Related Articles
/// [Documentation](https://rev.cat/paywalls)
@available(iOS 16.0, macOS 13.0, tvOS 16.0, *)
@available(iOS 15.0, macOS 12.0, tvOS 15.0, *)
@available(watchOS, unavailable, message: "RevenueCatUI does not support watchOS yet")
@available(macOS, unavailable, message: "RevenueCatUI does not support macOS yet")
@available(tvOS, unavailable, message: "RevenueCatUI does not support tvOS yet")
Expand Down
2 changes: 2 additions & 0 deletions RevenueCatUI/Templates/Template2View.swift
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ struct Template2View: TemplateViewType {
@ViewBuilder
var content: some View {
VStack(spacing: 10) {
Spacer()

self.scrollableContent
.scrollableIfNecessary()

Expand Down
2 changes: 1 addition & 1 deletion RevenueCatUI/Templates/Template4View.swift
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,8 @@ struct Template4View: TemplateViewType {

private var packagesScrollView: some View {
self.packages
.frame(height: self.packageContentHeight)
.scrollableIfNecessary(.horizontal)
.frame(height: self.packageContentHeight)
.frame(maxWidth: .infinity)
.onSizeChange(.horizontal) {
self.containerWidth = $0
Expand Down
4 changes: 2 additions & 2 deletions RevenueCatUI/UIKit/PaywallViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import UIKit
/// A view controller for displaying `PaywallData` for an `Offering`.
///
/// - Seealso: ``PaywallView`` for `SwiftUI`.
@available(iOS 16.0, macOS 13.0, tvOS 16.0, *)
@available(iOS 15.0, macOS 12.0, tvOS 15.0, *)
@objc(RCPaywallViewController)
public final class PaywallViewController: UIViewController {

Expand Down Expand Up @@ -64,7 +64,7 @@ public final class PaywallViewController: UIViewController {
}

/// Delegate for ``PaywallViewController``.
@available(iOS 16.0, macOS 13.0, tvOS 16.0, *)
@available(iOS 15.0, macOS 12.0, tvOS 15.0, *)
@objc(RCPaywallViewControllerDelegate)
public protocol PaywallViewControllerDelegate: AnyObject {

Expand Down
4 changes: 2 additions & 2 deletions RevenueCatUI/View+PresentPaywall.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
import RevenueCat
import SwiftUI

@available(iOS 16.0, macOS 13.0, tvOS 16.0, *)
@available(iOS 15.0, macOS 12.0, tvOS 15.0, *)
@available(macOS, unavailable, message: "RevenueCatUI does not support macOS yet")
@available(tvOS, unavailable, message: "RevenueCatUI does not support tvOS yet")
extension View {
Expand Down Expand Up @@ -100,7 +100,7 @@ extension View {

}

@available(iOS 16.0, macOS 13.0, tvOS 16.0, *)
@available(iOS 15.0, macOS 12.0, tvOS 15.0, *)
@available(macOS, unavailable)
@available(tvOS, unavailable)
private struct PresentingPaywallModifier: ViewModifier {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import RevenueCat
import RevenueCatUI
import SwiftUI

@available(iOS 16.0, macOS 13.0, tvOS 16.0, *)
@available(iOS 15.0, macOS 12.0, tvOS 15.0, *)
struct App: View {

private var offering: Offering
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,15 @@ import RevenueCat
import RevenueCatUI
import SwiftUI

@available(iOS 16.0, macOS 13.0, tvOS 16.0, *)
@available(iOS 15.0, macOS 12.0, tvOS 15.0, *)
func paywallViewControllerAPI(_ delegate: Delegate, _ offering: Offering?) {
let controller = PaywallViewController()
controller.delegate = delegate

let _: UIViewController = PaywallViewController(offering: offering)
}

@available(iOS 16.0, macOS 13.0, tvOS 16.0, *)
@available(iOS 15.0, macOS 12.0, tvOS 15.0, *)
final class Delegate: PaywallViewControllerDelegate {

func paywallViewController(_ controller: PaywallViewController,
Expand Down
12 changes: 3 additions & 9 deletions Tests/RevenueCatUITests/BaseSnapshotTest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import SnapshotTesting
import SwiftUI
import XCTest

@available(iOS 16.0, macOS 13.0, tvOS 16.0, watchOS 9.0, *)
@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *)
@MainActor
class BaseSnapshotTest: TestCase {

Expand All @@ -20,15 +20,9 @@ class BaseSnapshotTest: TestCase {
// isRecording = true
}

override func setUpWithError() throws {
try super.setUpWithError()

try AvailabilityChecks.iOS16APIAvailableOrSkipTest()
}

}

@available(iOS 16.0, macOS 13.0, tvOS 16.0, watchOS 9.0, *)
@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *)
extension BaseSnapshotTest {

static let eligibleChecker: TrialOrIntroEligibilityChecker = .producing(eligibility: .eligible)
Expand All @@ -41,7 +35,7 @@ extension BaseSnapshotTest {

}

@available(iOS 16.0, macOS 13.0, tvOS 16.0, watchOS 9.0, *)
@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *)
extension View {

/// Adds the receiver to a view hierarchy to be able to test lifetime logic.
Expand Down
8 changes: 1 addition & 7 deletions Tests/RevenueCatUITests/PurchaseCompletedHandlerTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,10 @@ import XCTest

#if !os(macOS)

@available(iOS 16.0, macOS 13.0, tvOS 16.0, watchOS 9.0, *)
@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *)
@MainActor
class PurchaseCompletedHandlerTests: TestCase {

override func setUpWithError() throws {
try super.setUpWithError()

try AvailabilityChecks.iOS16APIAvailableOrSkipTest()
}

func testOnPurchaseCompletedWithCancellation() throws {
let handler: PurchaseHandler = .cancelling()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import SnapshotTesting

#if !os(macOS)

@available(iOS 16.0, macOS 13.0, tvOS 16.0, watchOS 9.0, *)
@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *)
class OtherPaywallViewTests: BaseSnapshotTest {

func testDefaultPaywall() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import RevenueCat
import SnapshotTesting
import SwiftUI

@available(iOS 16.0, macOS 13.0, tvOS 16.0, watchOS 9.0, *)
@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *)
class PaywallViewDynamicTypeTests: BaseSnapshotTest {

func testXSmall() {
Expand Down Expand Up @@ -56,7 +56,7 @@ class PaywallViewDynamicTypeTests: BaseSnapshotTest {

}

@available(iOS 16.0, macOS 13.0, tvOS 16.0, watchOS 9.0, *)
@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *)
private extension PaywallViewDynamicTypeTests {

static func test(_ type: DynamicTypeSize) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import RevenueCat
import SnapshotTesting
import SwiftUI

@available(iOS 16.0, macOS 13.0, tvOS 16.0, watchOS 9.0, *)
@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *)
class PaywallViewLocalizationTests: BaseSnapshotTest {

func testSpanish() {
Expand All @@ -20,7 +20,7 @@ class PaywallViewLocalizationTests: BaseSnapshotTest {

}

@available(iOS 16.0, macOS 13.0, tvOS 16.0, watchOS 9.0, *)
@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *)
private extension PaywallViewLocalizationTests {

static func test(_ locale: Locale) {
Expand Down
2 changes: 1 addition & 1 deletion Tests/RevenueCatUITests/Templates/Template1ViewTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import SwiftUI

#if !os(macOS)

@available(iOS 16.0, macOS 13.0, tvOS 16.0, watchOS 9.0, *)
@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *)
class Template1ViewTests: BaseSnapshotTest {

func testSamplePaywall() {
Expand Down
2 changes: 1 addition & 1 deletion Tests/RevenueCatUITests/Templates/Template2ViewTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import SnapshotTesting

#if !os(macOS)

@available(iOS 16.0, macOS 13.0, tvOS 16.0, watchOS 9.0, *)
@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *)
class Template2ViewTests: BaseSnapshotTest {

func testSamplePaywall() {
Expand Down
2 changes: 1 addition & 1 deletion Tests/RevenueCatUITests/Templates/Template3ViewTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import SnapshotTesting

#if !os(macOS)

@available(iOS 16.0, macOS 13.0, tvOS 16.0, watchOS 9.0, *)
@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *)
class Template3ViewTests: BaseSnapshotTest {

func testSamplePaywall() {
Expand Down
2 changes: 1 addition & 1 deletion Tests/RevenueCatUITests/Templates/Template4ViewTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import SnapshotTesting

#if !os(macOS)

@available(iOS 16.0, macOS 13.0, tvOS 16.0, watchOS 9.0, *)
@available(iOS 15.0, macOS 12.0, tvOS 15.0, watchOS 8.0, *)
class Template4ViewTests: BaseSnapshotTest {

func testSamplePaywall() {
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -382,7 +382,7 @@
"INFOPLIST_KEY_UIStatusBarStyle[sdk=iphonesimulator*]" = UIStatusBarStyleDefault;
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
LD_RUNPATH_SEARCH_PATHS = "@executable_path/Frameworks";
"LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks";
MACOSX_DEPLOYMENT_TARGET = 13.0;
Expand Down Expand Up @@ -426,7 +426,7 @@
"INFOPLIST_KEY_UIStatusBarStyle[sdk=iphonesimulator*]" = UIStatusBarStyleDefault;
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
IPHONEOS_DEPLOYMENT_TARGET = 16.0;
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
LD_RUNPATH_SEARCH_PATHS = "@executable_path/Frameworks";
"LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks";
MACOSX_DEPLOYMENT_TARGET = 13.0;
Expand Down
4 changes: 1 addition & 3 deletions Tests/TestingApps/SimpleApp/SimpleApp/SimpleApp.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,7 @@ struct SimpleApp: App {

var body: some Scene {
WindowGroup {
NavigationView {
AppContentView()
}
AppContentView()
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ struct SamplePaywallsList: View {
self.display = .customFont(template)
} label: {
TemplateLabel(name: "Custom font", icon: "textformat")
.italic()
.font(.body.italic())
}
}
}
Expand Down

0 comments on commit 0bbb6cd

Please sign in to comment.