Skip to content

Commit

Permalink
update demo app for Adapty
Browse files Browse the repository at this point in the history
  • Loading branch information
x401om committed Aug 15, 2024
1 parent 4658ea0 commit e374d65
Show file tree
Hide file tree
Showing 4 changed files with 166 additions and 53 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
745BF76E2C6A853C001781E4 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 745BF7602C6A853C001781E4 /* Preview Assets.xcassets */; };
745BF76F2C6A853C001781E4 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 745BF7622C6A853C001781E4 /* Assets.xcassets */; };
745BF7702C6A853C001781E4 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 745BF7632C6A853C001781E4 /* LaunchScreen.storyboard */; };
745BF7712C6A853C001781E4 /* ApplicationContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 745BF7662C6A853C001781E4 /* ApplicationContentView.swift */; };
745BF7722C6A853C001781E4 /* ApplicationMainView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 745BF7672C6A853C001781E4 /* ApplicationMainView.swift */; };
745BF7732C6A853C001781E4 /* ApplicationSplashView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 745BF7682C6A853C001781E4 /* ApplicationSplashView.swift */; };
745BF7742C6A853C001781E4 /* OnboardingsDemoApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 745BF76A2C6A853C001781E4 /* OnboardingsDemoApp.swift */; };
Expand All @@ -29,7 +28,6 @@
745BF7622C6A853C001781E4 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
745BF7632C6A853C001781E4 /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = LaunchScreen.storyboard; sourceTree = "<group>"; };
745BF7642C6A853C001781E4 /* OnboardingsDemo_SwiftUI.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = OnboardingsDemo_SwiftUI.entitlements; sourceTree = "<group>"; };
745BF7662C6A853C001781E4 /* ApplicationContentView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ApplicationContentView.swift; sourceTree = "<group>"; };
745BF7672C6A853C001781E4 /* ApplicationMainView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ApplicationMainView.swift; sourceTree = "<group>"; };
745BF7682C6A853C001781E4 /* ApplicationSplashView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ApplicationSplashView.swift; sourceTree = "<group>"; };
745BF76A2C6A853C001781E4 /* OnboardingsDemoApp.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OnboardingsDemoApp.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -95,7 +93,6 @@
745BF7692C6A853C001781E4 /* UI */ = {
isa = PBXGroup;
children = (
745BF7662C6A853C001781E4 /* ApplicationContentView.swift */,
745BF7672C6A853C001781E4 /* ApplicationMainView.swift */,
745BF7682C6A853C001781E4 /* ApplicationSplashView.swift */,
);
Expand Down Expand Up @@ -199,7 +196,6 @@
745BF76D2C6A853C001781E4 /* ViewModel.swift in Sources */,
745BF7742C6A853C001781E4 /* OnboardingsDemoApp.swift in Sources */,
745BF76C2C6A853C001781E4 /* IdentifiableErrorWrapper.swift in Sources */,
745BF7712C6A853C001781E4 /* ApplicationContentView.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down Expand Up @@ -344,7 +340,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 = 14.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 = 14.5;
Expand Down Expand Up @@ -384,7 +380,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 = 14.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 = 14.5;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,45 @@
//

import Adapty
import AdaptyUI
import Foundation
import Onboardings

enum AppConstants {
enum Adapty {
static let apiKey = "public_live_3MTW3h2c.eEnwTeoRyjgb9JbDcyEC"
static let mainPlacementId = "paywall_onboarding_placement"
static let onboardingPlacementId = "onboarding_placement"
static let onboardingRemoteConfigKey = "octobuildy_id"
}

enum Onboardings {
static let apiKey = "public_live_lzjhlp9e"
static let onboardingId = "onboarding-fitness-app-small"
}
}

class ViewModel: ObservableObject {
@Published var onboardingIdLoading = true
@Published var onboardingId: String?


@Published var adaptyPaywall: AdaptyPaywall?
@Published var adaptyViewConfiguration: AdaptyUI.LocalizedViewConfiguration?

var onError: ((Error) -> Void)?

@MainActor
func initialize() {
Adapty.activate("public_live_QzY2YBrm.j0U3MNaKe2HAgeK4XV13")
Adapty.logLevel = .verbose
Adapty.activate(AppConstants.Adapty.apiKey)
AdaptyUI.activate()

loadOnboardingId()

do {
let configuration = OnboardingsConfiguration
.builder(withAPIKey: "YOUR_API_KEY")
.builder(withAPIKey: AppConstants.Onboardings.apiKey)
.with(loglevel: .verbose)
.with(alternativeBaseUrl: URL(string: "https://1a.fnlfx.dev/"))

try Onboardings.activate(with: configuration)
} catch {
Expand All @@ -34,11 +55,9 @@ class ViewModel: ObservableObject {
func loadOnboardingId() {
Task { @MainActor in
do {
let paywall = try await Adapty.getPaywall(placementId: "onboarding-id")

if let onboardingId = paywall.remoteConfig?.dictionary?["onboarding-id"] as? String {
self.onboardingId = onboardingId
}
let paywall = try await Adapty.getPaywall(placementId: AppConstants.Adapty.onboardingPlacementId)
onboardingId = paywall.onboardingId
onboardingIdLoading = false
} catch {
onError?(error)
}
Expand All @@ -48,4 +67,84 @@ class ViewModel: ObservableObject {
func setOnboardingFinished() {
onboardingId = nil
}

func loadOnboardingPaywall() {
Task { @MainActor in
do {
let paywall = try await Adapty.getPaywall(placementId: AppConstants.Adapty.mainPlacementId)
let viewConfig = try await AdaptyUI.getViewConfiguration(forPaywall: paywall)

adaptyPaywall = paywall
adaptyViewConfiguration = viewConfig
} catch {
onError?(error)
}
}
}

func handleOnboardingStateUpdatedAction(_ action: OnboardingsStateUpdatedAction) {
guard let params = try? AdaptyProfileParameters.Builder()
.with(stateUpdatedAction: action)
.build() else { return }

Adapty.updateProfile(params: params)
}

func handleOnboardingAnalyticsEvent(_ event: OnboardingsAnalyticsEvent) {
switch event {
case let .screenPresented(meta):
Adapty.logShowOnboarding(
name: meta.onboardingId,
screenName: meta.screenClientId,
screenOrder: UInt(meta.screenIndex)
)

if meta.screenClientId == "creating-your-plan" {
loadOnboardingPaywall()
}
default:
break
}
}
}

extension AdaptyPaywall {
var onboardingId: String? {
remoteConfig?.dictionary?[AppConstants.Adapty.onboardingRemoteConfigKey] as? String
}
}

public extension AdaptyProfileParameters.Builder {
@discardableResult
func with(stateUpdatedAction action: OnboardingsStateUpdatedAction) throws -> Self {
switch action.params {
case let .select(params):
try with(customAttribute: params.value, forKey: action.elementId)
case let .multiSelect(params):
try with(customAttribute: params.stringValue, forKey: action.elementId)
case let .input(params):
switch params {
case let .text(stringValue):
try with(customAttribute: stringValue, forKey: action.elementId)
case let .email(stringValue):
try with(customAttribute: stringValue, forKey: action.elementId)
case let .number(doubleValue):
try with(customAttribute: doubleValue, forKey: action.elementId)
}
case let .datePicker(params):
try with(customAttribute: params.stringValue, forKey: action.elementId)
}
}
}

extension [OnboardingsSelectParams] {
var stringValue: String {
map { $0.value }.joined(separator: ",")
}
}

extension OnboardingsDatePickerParams {
var stringValue: String {
"\(year)-\(String(format: "%.2d", month))-\(String(format: "%.2d", day))"
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,64 @@
// Created by Aleksey Goncharov on 12.08.2024.
//

import AdaptyUI
import Onboardings
import SwiftUI

struct ApplicationMainView: View {
@EnvironmentObject var viewModel: ViewModel

@State var showOnboarding: Bool = true
@State var showPaywall: Bool = false
@State var errorAlert: IdentifiableErrorWrapper?

@ViewBuilder
private var applicationView: some View {
NavigationView {
List {
Section {
Button {
withAnimation {
showOnboarding = true
showPaywall = false
errorAlert = nil
}
} label: {
Text("Logout")
.foregroundColor(.red)
}
}
}
.navigationTitle("Welcome to Onboardings SDK!")
.navigationBarTitleDisplayMode(.inline)
}
}

var body: some View {
ZStack {
NavigationView {
ApplicationContentView()
if showPaywall, let paywall = viewModel.adaptyPaywall,
let viewConfig = viewModel.adaptyViewConfiguration
{
applicationView
.zIndex(0)
.paywall(
isPresented: $showPaywall,
paywall: paywall,
viewConfiguration: viewConfig,
didFailPurchase: { _, _ in },
didFinishRestore: { _ in },
didFailRestore: { _ in },
didFailRendering: { _ in }
)
.onAppear {
showOnboarding = false
}
} else {
applicationView
.zIndex(0)
}
.zIndex(0)

if let onboardingId = viewModel.onboardingId {
if showOnboarding, let onboardingId = viewModel.onboardingId {
Onboardings.swiftuiView(
id: onboardingId,
splashViewBuilder: {
Expand All @@ -31,6 +73,15 @@ struct ApplicationMainView: View {
viewModel.setOnboardingFinished()
}
},
onOpenPaywallAction: { _ in
showPaywall = true
},
onStateUpdatedAction: { action in
viewModel.handleOnboardingStateUpdatedAction(action)
},
onAnalyticsEvent: { event in
viewModel.handleOnboardingAnalyticsEvent(event)
},
onError: { error in
errorAlert = .init(value: error)
}
Expand All @@ -39,6 +90,7 @@ struct ApplicationMainView: View {
.zIndex(1)
} else if viewModel.onboardingIdLoading {
ApplicationSplashView()
.zIndex(1)
}
}
.onAppear {
Expand Down

0 comments on commit e374d65

Please sign in to comment.