Skip to content

Commit

Permalink
Improvements on the app state management, CMP management and updated …
Browse files Browse the repository at this point in the history
…README file.
  • Loading branch information
fabiotorre committed Oct 24, 2024
1 parent fc6a634 commit 2e1162d
Show file tree
Hide file tree
Showing 11 changed files with 600 additions and 383 deletions.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1600"
version = "1.7">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES"
buildArchitectures = "Automatic">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "594425792CC921E0001D1232"
BuildableName = "CMPSDKv2DemoApp.app"
BlueprintName = "CMPSDKv2DemoApp"
ReferencedContainer = "container:CMPSDKv2DemoApp.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
shouldAutocreateTestPlan = "YES">
</TestAction>
<LaunchAction
buildConfiguration = "Release"
selectedDebuggerIdentifier = ""
selectedLauncherIdentifier = "Xcode.IDEFoundation.Launcher.PosixSpawn"
enableAddressSanitizer = "YES"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "594425792CC921E0001D1232"
BuildableName = "CMPSDKv2DemoApp.app"
BlueprintName = "CMPSDKv2DemoApp"
ReferencedContainer = "container:CMPSDKv2DemoApp.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<AdditionalOptions>
<AdditionalOption
key = "NSZombieEnabled"
value = "YES"
isEnabled = "YES">
</AdditionalOption>
<AdditionalOption
key = "MallocScribble"
value = ""
isEnabled = "YES">
</AdditionalOption>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "594425792CC921E0001D1232"
BuildableName = "CMPSDKv2DemoApp.app"
BlueprintName = "CMPSDKv2DemoApp"
ReferencedContainer = "container:CMPSDKv2DemoApp.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,13 @@
<integer>0</integer>
</dict>
</dict>
<key>SuppressBuildableAutocreation</key>
<dict>
<key>594425792CC921E0001D1232</key>
<dict>
<key>primary</key>
<true/>
</dict>
</dict>
</dict>
</plist>
74 changes: 74 additions & 0 deletions CMPSDKv2DemoApp/CMPSDKv2DemoApp/CMPManager.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
//
// CMPManager.swift
// CMPSDKv2DemoApp
//
// Created by Fabio Torre on 24/10/24.
//

import Foundation
import CmpSdk

class CMPManager {
static let shared = CMPManager()

private(set) var cmpManager: CMPConsentTool?
private var isInitialized = false
@Published private(set) var isConsentLayerVisible = false

private init() {}

func initialize() {

guard cmpManager == nil else { return }

let cmpConfig: CmpConfig = CmpConfig.shared.setup(
withId: "Your Code-ID here (13 characters)",
domain: "delivery.consentmanager.net",
appName: "CMPSDKv2DemoApp",
language: "DE")

cmpConfig.logLevel = CmpLogLevel.verbose
cmpConfig.isAutomaticATTRequest = true

let manager = CMPConsentTool(cmpConfig: cmpConfig)
.withErrorListener(handleError)
.withCloseListener(handleClose)
.withOpenListener(handleOpen)
.withOnCMPNotOpenedListener(handleNotOpened)
.withOnCmpButtonClickedCallback(handleButtonClick)

cmpManager = manager
manager?.initialize()
isInitialized = true
}

// MARK: - Event Handlers
private func handleError(type: CmpErrorType, message: String?) {
print("CMP Error: \(type) - \(message ?? "No message")")
isConsentLayerVisible = false
}

private func handleClose() {
isConsentLayerVisible = false
NotificationCenter.default.post(name: .cmpClosed, object: nil)
}

private func handleOpen() {
isConsentLayerVisible = true
print("CMP Opened")
}

private func handleNotOpened() {
isConsentLayerVisible = false
print("CMP Not Opened")
}

private func handleButtonClick(event: CmpButtonEvent) {
print("Button clicked: \(event)")
}
}

// Notification extension
extension Notification.Name {
static let cmpClosed = Notification.Name("CMPClosedNotification")
}
190 changes: 190 additions & 0 deletions CMPSDKv2DemoApp/CMPSDKv2DemoApp/ConsentControlsView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
//
// ConsentControlsView.swift
// CMPSDKv2DemoApp
//
// Created by Fabio Torre on 24/10/24.
//

import Foundation
import SwiftUI

struct ConsentControlsView: View {
@State private var toastMessage: String?

var body: some View {
ZStack { // Changed from ScrollView to ZStack
ScrollView {
VStack(spacing: 20) {
Text("CM Swift DemoApp")
.font(.largeTitle)
.bold()

ConsentButtons(showToast: showToast)
}
.padding()
}

ToastView(message: $toastMessage) // Now a direct child of ZStack
}
}

private func showToast(_ message: String) {
toastMessage = message
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
toastMessage = nil
}
}
}

struct ConsentButtons: View {
let showToast: (String) -> Void

var body: some View {
VStack(spacing: 12) {
ConsentButton(title: "Has User Choice?", color: .blue) {
let hasConsent = CMPManager.shared.cmpManager?.hasConsent()
showToast("Has User Choice: \(String(describing: hasConsent))")
}

ConsentButton(title: "Get CMP String", color: .teal) {
let cmpString = CMPManager.shared.cmpManager?.getConsentString()
showToast("CMP String: \(String(describing: cmpString))")
}

ConsentButton(title: "Get All Purposes", color: .mint) {
let purposes = CMPManager.shared.cmpManager?.getAllPurposes()
showToast("Purposes: \(String(describing: purposes))")
}

ConsentButton(title: "Has Purpose ID c53?", color: .mint) {
let hasPurpose = CMPManager.shared.cmpManager?.hasPurposeConsent("c53")
showToast("Has Purpose c53: \(String(describing: hasPurpose))")
}

ConsentButton(title: "Get Enabled Purposes", color: .mint) {
let enabled = CMPManager.shared.cmpManager?.getEnabledPurposes()
showToast("Enabled Purposes: \(String(describing: enabled))")
}

ConsentButton(title: "Get Disabled Purposes", color: .gray) {
let disabled = CMPManager.shared.cmpManager?.getDisabledPurposes()
showToast("Disabled Purposes: \(String(describing: disabled))")
}

ConsentButton(title: "Enable Purposes c52 and c53", color: .mint) {
CMPManager.shared.cmpManager?.enablePurposeList(["c52", "c53"])
showToast("Purposes c52 and c53 enabled.")
}

ConsentButton(title: "Disable Purposes c52 and c53", color: .red) {
CMPManager.shared.cmpManager?.disablePurposeList(["c52", "c53"])
showToast("Purposes c52 and c53 disabled")
}

ConsentButton(title: "Get All Vendors", color: .cyan) {
let vendors = CMPManager.shared.cmpManager?.getAllVendors()
showToast("All Vendors: \(String(describing: vendors))")
}

ConsentButton(title: "Has Vendor ID s2789?", color: .cyan) {
let hasVendor = CMPManager.shared.cmpManager?.hasVendorConsent("s2789")
showToast("Has Vendor s2789: \(String(describing: hasVendor))")
}

ConsentButton(title: "Get Enabled Vendors", color: .cyan) {
let enabled = CMPManager.shared.cmpManager?.getEnabledVendors()
showToast("Enabled Vendors: \(String(describing: enabled))")
}

ConsentButton(title: "Get Disabled Vendors", color: .gray) {
let disabled = CMPManager.shared.cmpManager?.getDisabledVendors()
showToast("Disabled Vendors: \(String(describing: disabled))")
}

ConsentButton(title: "Enable Vendors s2790 and s2791", color: .cyan) {
CMPManager.shared.cmpManager?.enableVendorList(["s2790", "s2791"])
showToast("Vendors s2790 and s2791 enabled")
}

ConsentButton(title: "Disable Vendors s2790 and s2791", color: .red) {
CMPManager.shared.cmpManager?.disableVendorList(["s2790", "s2791"])
showToast("Vendors s2790 and s2791 disabled")
}

ConsentButton(title: "Reject All", color: .red) {
CMPManager.shared.cmpManager?.rejectAll {
showToast("All consents rejected")
}
}

ConsentButton(title: "Accept All", color: .green) {
CMPManager.shared.cmpManager?.acceptAll {
showToast("All consents accepted")
}
}

ConsentButton(title: "Check and Open Consent Layer", color: .indigo) {
CMPManager.shared.cmpManager?.checkAndOpenConsentLayer()
}

ConsentButton(title: "Open Consent Layer", color: .indigo) {
CMPManager.shared.cmpManager?.openView()
}

ConsentButton(title: "Import CMP String", color: .mint) {
let cmpString = "Q1FERkg3QVFERkg3QUFmR01CSVRCQkVnQUFBQUFBQUFBQWlnQUFBQUFBQUEjXzUxXzUyXzUzXzU0XzU1XzU2XyNfczI3ODlfczI3OTBfczI3OTFfczI2OTdfczk3MV9VXyMxLS0tIw"
importConsentString(cmpString, showToast: showToast)
}
}
}

private func importConsentString(_ cmpString: String, showToast: @escaping (String) -> Void) {
Task {
if let result = await CMPManager.shared.cmpManager?.importCmpString(cmpString) {
let (success, error) = result
await MainActor.run {
if success {
showToast("New consent string imported successfully")
} else {
showToast("Error: \(error ?? "Unknown error")")
}
}
}
}
}
}

struct ToastView: View {
@Binding var message: String?

var body: some View {
GeometryReader { geometry in
if let message = message {
Text(message)
.foregroundColor(.white)
.padding()
.background(Color.black.opacity(0.8))
.cornerRadius(10)
.position(x: geometry.size.width / 2, y: geometry.size.height / 2)
.ignoresSafeArea()
}
}
}
}

struct ConsentButton: View {
let title: String
let color: Color
let action: () -> Void

var body: some View {
Button(action: action) {
Text(title)
.foregroundColor(.white)
.frame(maxWidth: .infinity)
.padding()
.background(color)
.cornerRadius(10)
}
}
}
Loading

0 comments on commit 2e1162d

Please sign in to comment.