Skip to content

Commit

Permalink
Paywalls: improved test custom paywall (#3089)
Browse files Browse the repository at this point in the history
Credit to @charliemchapman for the design + implementation:


![simulator_screenshot_B5041028-848B-462E-A270-573A777FC53D](https://github.com/RevenueCat/purchases-ios/assets/685609/f45dd300-579e-4311-89e6-55a1f8a9ea71)
  • Loading branch information
NachoSoto committed Sep 6, 2023
1 parent ee66cf2 commit 40cc7eb
Show file tree
Hide file tree
Showing 7 changed files with 180 additions and 93 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
4F4EE7CD2A572F5400D7EAE1 /* SimpleApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4FC046BC2A572E3700A28BCF /* SimpleApp.swift */; };
4F4EE7CF2A572F5D00D7EAE1 /* DebugView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4FC046C32A572E3700A28BCF /* DebugView.swift */; };
4F4EE7D22A5731E800D7EAE1 /* RevenueCat in Frameworks */ = {isa = PBXBuildFile; productRef = 4F4EE7D12A5731E800D7EAE1 /* RevenueCat */; };
4F6E5A502A660DD500C573C7 /* SampleChart.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4F6E5A4F2A660DD500C573C7 /* SampleChart.swift */; };
4F71CDD22A992292001B9BEF /* CustomPaywallContent.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4F71CDD12A992292001B9BEF /* CustomPaywallContent.swift */; };
4FC6F8B22A7403D3002139B2 /* OfferingsList.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4FC6F8B12A7403D3002139B2 /* OfferingsList.swift */; };
4FC80B202A5DE8E300E95DB0 /* RevenueCatUI in Frameworks */ = {isa = PBXBuildFile; productRef = 4FC80B1F2A5DE8E300E95DB0 /* RevenueCatUI */; };
4FCA01FB2A3A1CBD00B262C0 /* StoreKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4FCA01FA2A3A1CBD00B262C0 /* StoreKit.framework */; };
Expand Down Expand Up @@ -46,7 +46,7 @@
4F4557E52A6FFE6D00160521 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/Localizable.strings; sourceTree = "<group>"; };
4F4EE7D02A5731CF00D7EAE1 /* purchases-ios */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = "purchases-ios"; path = ../../..; sourceTree = "<group>"; };
4F6BED9A2A26A64200CD9322 /* SimpleApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SimpleApp.app; sourceTree = BUILT_PRODUCTS_DIR; };
4F6E5A4F2A660DD500C573C7 /* SampleChart.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SampleChart.swift; sourceTree = "<group>"; };
4F71CDD12A992292001B9BEF /* CustomPaywallContent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomPaywallContent.swift; sourceTree = "<group>"; };
4FC046BC2A572E3700A28BCF /* SimpleApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SimpleApp.swift; sourceTree = "<group>"; };
4FC046BD2A572E3700A28BCF /* SimpleApp.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = SimpleApp.entitlements; sourceTree = "<group>"; };
4FC046BE2A572E3700A28BCF /* Products.storekit */ = {isa = PBXFileReference; lastKnownFileType = text; path = Products.storekit; sourceTree = "<group>"; };
Expand Down Expand Up @@ -80,9 +80,9 @@
4F34FF622A60AD9A00AADF11 /* AppContentView.swift */,
4FC046C32A572E3700A28BCF /* DebugView.swift */,
4FC6F8B12A7403D3002139B2 /* OfferingsList.swift */,
4F6E5A4F2A660DD500C573C7 /* SampleChart.swift */,
4FDF111F2A7270F3004F3680 /* SamplePaywallsList.swift */,
4F102E262A840ECC0059EED6 /* CustomPaywall.swift */,
4F71CDD12A992292001B9BEF /* CustomPaywallContent.swift */,
);
path = Views;
sourceTree = "<group>";
Expand Down Expand Up @@ -225,8 +225,8 @@
buildActionMask = 2147483647;
files = (
4F4EE7CD2A572F5400D7EAE1 /* SimpleApp.swift in Sources */,
4F71CDD22A992292001B9BEF /* CustomPaywallContent.swift in Sources */,
4F4EE7CF2A572F5D00D7EAE1 /* DebugView.swift in Sources */,
4F6E5A502A660DD500C573C7 /* SampleChart.swift in Sources */,
4FDF11222A72714C004F3680 /* SamplePaywalls.swift in Sources */,
4F34FF652A60ADBD00AADF11 /* Configuration.swift in Sources */,
4FC6F8B22A7403D3002139B2 /* OfferingsList.swift in Sources */,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"images" : [
{
"filename" : "Image.png",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
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 @@ -84,9 +84,6 @@ struct AppContentView: View {

Spacer()

BarChartView(data: (0..<10).map { _ in Double.random(in: 0..<100)})
.frame(maxWidth: .infinity)

if let date = info.latestExpirationDate {
Text(verbatim: "Your subscription expires: \(date.formatted())")
.font(.caption)
Expand All @@ -96,6 +93,7 @@ struct AppContentView: View {
}
}
.padding(.horizontal)
.frame(maxWidth: .infinity, maxHeight: .infinity)
.navigationTitle("Simple App")
.task {
for await info in self.customerInfoStream {
Expand Down
28 changes: 2 additions & 26 deletions Tests/TestingApps/SimpleApp/SimpleApp/Views/CustomPaywall.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,45 +19,21 @@ struct CustomPaywall: View {

var body: some View {
self.content
.navigationTitle("Custom paywall")
}

private var content: some View {
VStack {
VStack {
ForEach(Self.colors, id: \.self) { color in
BarChartView(
data: (0..<10).map { _ in Double.random(in: 0..<100)},
color: color
)
}
}
.frame(maxWidth: .infinity)
CustomPaywallContent()
.scrollableIfNecessary(.vertical)
.background(CustomPaywallContent.backgroundColor)
.paywallFooter(offering: self.offering,
customerInfo: self.customerInfo,
condensed: self.condensed,
fonts: DefaultPaywallFontProvider(),
introEligibility: self.introEligibility ?? .default(),
purchaseHandler: self.purchaseHandler ?? .default()
)
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
.background(
Color(white: 0.8)
.edgesIgnoringSafeArea(.all)
)
}

private static let colors: [Color] = [
.red,
.green,
.blue,
.indigo,
.mint,
.teal
].shuffled()

}


Expand Down
161 changes: 161 additions & 0 deletions Tests/TestingApps/SimpleApp/SimpleApp/Views/CustomPaywallContent.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
//
// CustomPaywallContent.swift
// SimpleApp
//
// Created by Nacho Soto on 8/25/23.
//


import SwiftUI

struct CustomPaywallContent: View {

@State private var rotation: Double = 0.0
@State private var starOpacity: Double = 1

var body: some View {
VStack(alignment: .leading, spacing: 8) {
Image("cat-picture")
.resizable()
.aspectRatio(contentMode: .fit)
.mask {
LinearGradient(colors: [.clear, .white, .white, .white, .clear],
startPoint: .top,
endPoint: .bottom)
}
.padding(.top, -60)
.padding(.bottom, -80)

HStack(spacing: 0) {
Text("Pawwall")
.font(.system(.largeTitle, design: .rounded).bold())
.foregroundColor(Marketing.color5)
.padding(.leading)

Text("Pro")
.font(.system(.largeTitle, design: .rounded).bold())

Spacer(minLength: 0)

Image(systemName: "star.fill")
.resizable()
.aspectRatio(contentMode: .fit)
.frame(height: 30)
.rotationEffect(Angle(degrees: self.rotation))
.opacity(self.starOpacity)
.padding(.trailing, 24)
.onAppear {
withAnimation(.linear(duration: 30)
.repeatForever(autoreverses: false)) {
self.rotation = 360.0
}
withAnimation(.easeInOut(duration: 10).repeatForever(autoreverses: true)) {
self.starOpacity = 0.75
}
}
}
.shadow(radius: 10)

Text("Get your paws on all the great premium features of Pawall Pro! 😻")
.padding(.horizontal)

Text("Premium features")
.font(.headline)
.padding(.top, 16)
.padding(.horizontal)
ScrollView(.horizontal, showsIndicators: false) {
HStack {
self.feature(icon: "dollarsign",
name: "Make more money!")
self.feature(icon: "figure.run",
name: "Do it fast!")
self.feature(icon: "bolt.fill",
name: "Zap the competition")
self.feature(icon: "square.fill",
name: "WALLS!")
}
.padding(.horizontal)
}

Text("What others are saying")
.font(.headline)
.padding(.top, 16)
.padding(.horizontal)

self.testimonial(name: "Garfield",
review: "Five stars for this paywall builder app, because let's face it, lasagna isn't free and neither are my naps – it helps me monetize both with style!")
self.testimonial(name: "Tom",
review: "This paywall builder app is a game-changer in my pursuit of Jerry. With its cunning customization, I'm closer than ever to catching that elusive mouse!")
self.testimonial(name: "Tony",
review: "It's grrreat for locking up premium content behind paywalls. A real frosted flakes of a deal!")
}
.foregroundColor(.white)
}

private func feature(icon: String, name: String) -> some View {
VStack(alignment: .center) {
Image(systemName: icon)
.resizable()
.aspectRatio(contentMode: .fit)
.foregroundColor(.white)
.frame(height: 40)
Spacer(minLength: 0)
Text(name)
.font(.subheadline)
.bold()
.multilineTextAlignment(.center)
}
.padding(2)
.frame(width: 90, height: 90)
.padding()
.background(LinearGradient(colors: [Marketing.color2, Marketing.color1],
startPoint: .topLeading,
endPoint: .bottomTrailing))
.foregroundColor(Marketing.color5)
.mask {
RoundedRectangle(cornerSize: .init(width: 10, height: 10), style: .continuous)
}
}

private func testimonial(name: String, review: String) -> some View {
VStack(alignment: .leading, spacing: 8) {
HStack {
Text("⭐️⭐️⭐️⭐️⭐️")
.font(.callout)

Spacer(minLength: 8)

Text(name)
.bold()
}

Text(review)
.font(.callout)

Spacer(minLength: 0)
}
.frame(height: 119)
.padding()
.background(LinearGradient(colors: [Marketing.color5, Marketing.color4.opacity(0.8)],
startPoint: .topLeading, endPoint: .bottomTrailing))
.foregroundColor(Marketing.color1)
.mask {
RoundedRectangle(cornerSize: .init(width: 10, height: 10), style: .continuous)
}
.padding(.horizontal)
}

static let backgroundColor = Marketing.color3

}

private enum Marketing {

static let color1 = Color(red: 0.004, green: 0.067, blue: 0.149)
static let color2 = Color(red: 0.039, green: 0.231, blue: 0.349)
static let color3 = Color(red: 0.318, green: 0.463, blue: 0.549)
static let color4 = Color(red: 0.584, green: 0.686, blue: 0.749)
static let color5 = Color(red: 0.69, green: 0.804, blue: 0.851)

}

60 changes: 0 additions & 60 deletions Tests/TestingApps/SimpleApp/SimpleApp/Views/SampleChart.swift

This file was deleted.

0 comments on commit 40cc7eb

Please sign in to comment.