Code Examples

Learn by example with our interactive code samples and tutorials.

Quick Start Examples

iOS App Setup

Complete setup for a new iOS app using the Cuppa framework:

import SwiftUI
import CuppaCore
import CuppaNavigation
import CuppaAnalyticsPlugin
import CuppaAuthPlugin

@main
struct MyCuppaApp: App {
    @StateObject private var coordinator = NavigationCoordinator()

    init() {
        setupPlugins()
    }

    var body: some Scene {
        WindowGroup {
            NavigationStack(path: $coordinator.path) {
                HomeView()
                    .navigationDestination(for: NavigationItem.self) { item in
                        coordinator.view(for: item)
                    }
            }
            .environmentObject(coordinator)
            .environmentObject(AuthManager.shared)
            .task {
                await coordinator.loadManifest()
            }
        }
    }

    private func setupPlugins() {
        // Analytics Plugin
        let analyticsProviders: [AnalyticsProvider] = [
            ConsoleAnalyticsProvider(enableTimestamps: true)
        ]

        try? PluginRegistry.shared.register(
            CuppaAnalyticsPlugin.self,
            with: AnalyticsPluginConfiguration(
                providers: analyticsProviders,
                enableDebugLogging: true
            )
        )

        // Auth Plugin
        let authProvider = ConsoleAuthProvider(
            enableTimestamps: true,
            simulateDelay: false
        )

        try? PluginRegistry.shared.register(
            CuppaAuthPlugin.self,
            with: AuthPluginConfiguration(
                provider: authProvider,
                enableDebugLogging: true
            )
        )

        // Error Handling Plugin
        let errorProviders: [ErrorReportingProvider] = [
            ConsoleErrorProvider(enableStackTraces: true)
        ]

        try? PluginRegistry.shared.register(
            CuppaErrorHandlingPlugin.self,
            with: ErrorHandlingPluginConfiguration(
                providers: errorProviders,
                enableDebugLogging: true
            )
        )
    }
}

Authentication Flow

Complete authentication flow with SwiftUI:

import SwiftUI
import CuppaAuthPlugin

struct AuthenticationView: View {
    @EnvironmentObject var authManager: AuthManager
    @State private var email = ""
    @State private var password = ""
    @State private var isSignUp = false
    @State private var errorMessage: String?
    @State private var isLoading = false

    var body: some View {
        VStack(spacing: 24) {
            // Header
            VStack(spacing: 8) {
                Image(systemName: "cup.and.saucer.fill")
                    .font(.system(size: 60))
                    .foregroundColor(.brown)

                Text(isSignUp ? "Create Account" : "Welcome Back")
                    .font(.title.bold())

                Text(isSignUp ? "Join MyCuppa today" : "Sign in to continue")
                    .font(.subheadline)
                    .foregroundColor(.secondary)
            }
            .padding(.bottom, 32)

            // Form
            VStack(spacing: 16) {
                TextField("Email", text: $email)
                    .textFieldStyle(.roundedBorder)
                    .textContentType(.emailAddress)
                    .autocapitalization(.none)
                    .keyboardType(.emailAddress)

                SecureField("Password", text: $password)
                    .textFieldStyle(.roundedBorder)
                    .textContentType(isSignUp ? .newPassword : .password)

                if let error = errorMessage {
                    Text(error)
                        .font(.caption)
                        .foregroundColor(.red)
                        .frame(maxWidth: .infinity, alignment: .leading)
                }
            }

            // Actions
            VStack(spacing: 12) {
                Button(action: handlePrimaryAction) {
                    if isLoading {
                        ProgressView()
                            .tint(.white)
                    } else {
                        Text(isSignUp ? "Sign Up" : "Sign In")
                            .fontWeight(.semibold)
                    }
                }
                .frame(maxWidth: .infinity)
                .padding()
                .background(Color.brown)
                .foregroundColor(.white)
                .cornerRadius(12)
                .disabled(isLoading || email.isEmpty || password.isEmpty)

                Button(action: { isSignUp.toggle() }) {
                    Text(isSignUp ? "Already have an account? Sign In" : "Don't have an account? Sign Up")
                        .font(.subheadline)
                        .foregroundColor(.brown)
                }
                .disabled(isLoading)

                if !isSignUp {
                    Button("Forgot Password?") {
                        handlePasswordReset()
                    }
                    .font(.caption)
                    .foregroundColor(.secondary)
                }
            }

            // OAuth
            Divider()
                .padding(.vertical)

            VStack(spacing: 12) {
                Text("Or continue with")
                    .font(.caption)
                    .foregroundColor(.secondary)

                HStack(spacing: 16) {
                    OAuthButton(provider: .google) {
                        handleOAuthSignIn(.google)
                    }

                    OAuthButton(provider: .apple) {
                        handleOAuthSignIn(.apple)
                    }

                    OAuthButton(provider: .github) {
                        handleOAuthSignIn(.github)
                    }
                }
            }
        }
        .padding(24)
    }

    private func handlePrimaryAction() {
        Task {
            errorMessage = nil
            isLoading = true

            do {
                if isSignUp {
                    try await authManager.signUp(
                        email: email,
                        password: password,
                        metadata: ["source": "ios_app"]
                    )
                } else {
                    try await authManager.signIn(
                        email: email,
                        password: password
                    )
                }
            } catch let error as AuthError {
                errorMessage = error.localizedDescription
            } catch {
                errorMessage = "An unexpected error occurred"
            }

            isLoading = false
        }
    }

    private func handleOAuthSignIn(_ provider: OAuthProvider) {
        Task {
            errorMessage = nil
            isLoading = true

            do {
                try await authManager.signInWithOAuth(provider: provider)
            } catch {
                errorMessage = "OAuth sign in failed"
            }

            isLoading = false
        }
    }

    private func handlePasswordReset() {
        Task {
            do {
                try await authManager.resetPassword(email: email)
                errorMessage = "Password reset email sent!"
            } catch {
                errorMessage = "Failed to send reset email"
            }
        }
    }
}

struct OAuthButton: View {
    let provider: OAuthProvider
    let action: () -> Void

    var body: some View {
        Button(action: action) {
            Image(systemName: icon)
                .font(.title3)
        }
        .frame(width: 60, height: 50)
        .background(Color.gray.opacity(0.1))
        .cornerRadius(12)
    }

    private var icon: String {
        switch provider {
        case .google: return "g.circle.fill"
        case .apple: return "apple.logo"
        case .github: return "chevron.left.forwardslash.chevron.right"
        default: return "person.circle.fill"
        }
    }
}

Analytics Tracking

Track user events and behavior:

import SwiftUI
import CuppaAnalyticsPlugin

struct ProductDetailView: View {
    let product: Product
    @EnvironmentObject var analyticsManager: AnalyticsManager

    var body: some View {
        ScrollView {
            VStack(alignment: .leading, spacing: 16) {
                // Product image
                AsyncImage(url: product.imageURL) { image in
                    image
                        .resizable()
                        .aspectRatio(contentMode: .fill)
                } placeholder: {
                    ProgressView()
                }
                .frame(height: 300)
                .clipped()

                VStack(alignment: .leading, spacing: 8) {
                    Text(product.name)
                        .font(.title.bold())

                    Text(product.description)
                        .foregroundColor(.secondary)

                    Text("$\(product.price, specifier: "%.2f")")
                        .font(.title2)
                        .foregroundColor(.brown)
                }
                .padding(.horizontal)

                Button("Add to Cart") {
                    addToCart()
                }
                .frame(maxWidth: .infinity)
                .padding()
                .background(Color.brown)
                .foregroundColor(.white)
                .cornerRadius(12)
                .padding(.horizontal)
            }
        }
        .navigationTitle(product.name)
        .task {
            // Track screen view
            await analyticsManager.trackScreen(
                name: "ProductDetail",
                properties: [
                    "product_id": product.id,
                    "product_name": product.name,
                    "product_category": product.category
                ]
            )
        }
    }

    private func addToCart() {
        Task {
            // Track add to cart event
            await analyticsManager.track(
                event: "add_to_cart",
                properties: [
                    "product_id": product.id,
                    "product_name": product.name,
                    "price": product.price,
                    "currency": "USD"
                ]
            )

            // Add to cart logic...
        }
    }
}

Error Handling

Comprehensive error tracking and reporting:

import SwiftUI
import CuppaErrorHandlingPlugin

struct DataSyncView: View {
    @State private var isSyncing = false
    @State private var lastSyncDate: Date?
    @State private var errorMessage: String?

    var body: some View {
        VStack(spacing: 20) {
            if let lastSync = lastSyncDate {
                Text("Last synced: \(lastSync, style: .relative)")
                    .foregroundColor(.secondary)
            }

            Button(isSyncing ? "Syncing..." : "Sync Data") {
                syncData()
            }
            .disabled(isSyncing)

            if let error = errorMessage {
                Text(error)
                    .foregroundColor(.red)
                    .font(.caption)
            }
        }
        .padding()
    }

    private func syncData() {
        Task {
            isSyncing = true
            errorMessage = nil

            // Add breadcrumb
            await ErrorReportingManager.shared.addBreadcrumb(
                message: "User initiated data sync",
                category: "user_action",
                level: .info
            )

            do {
                try await performSync()

                lastSyncDate = Date()

                // Track successful sync
                await ErrorReportingManager.shared.addBreadcrumb(
                    message: "Data sync completed successfully",
                    category: "sync",
                    level: .info
                )

            } catch {
                errorMessage = "Sync failed. Please try again."

                // Report error with context
                await ErrorReportingManager.shared.reportError(
                    error,
                    context: [
                        "operation": "data_sync",
                        "last_sync": lastSyncDate?.ISO8601Format() ?? "never",
                        "retry_count": "0"
                    ]
                )
            }

            isSyncing = false
        }
    }

    private func performSync() async throws {
        // Sync implementation
        // ...
    }
}

Navigation with Deep Linking

Handle deep links and navigation:

import SwiftUI
import CuppaNavigation

@main
struct MyApp: App {
    @StateObject private var coordinator = NavigationCoordinator()

    var body: some Scene {
        WindowGroup {
            ContentView()
                .environmentObject(coordinator)
                .onOpenURL { url in
                    handleDeepLink(url)
                }
        }
    }

    private func handleDeepLink(_ url: URL) {
        Task {
            // Add breadcrumb for debugging
            await ErrorReportingManager.shared.addBreadcrumb(
                message: "Deep link opened: \(url.absoluteString)",
                category: "navigation",
                level: .info
            )

            // Handle auth callbacks
            if url.path.contains("/auth/callback") {
                do {
                    try await AuthManager.shared.handleAuthCallback(url: url)
                } catch {
                    await ErrorReportingManager.shared.reportError(
                        error,
                        context: ["deep_link": url.absoluteString]
                    )
                }
                return
            }

            // Handle regular navigation
            await coordinator.handleDeepLink(url)

            // Track deep link usage
            await AnalyticsManager.shared.track(
                event: "deep_link_opened",
                properties: [
                    "url": url.absoluteString,
                    "path": url.path,
                    "source": url.scheme ?? "unknown"
                ]
            )
        }
    }
}

More Examples

Browse our GitHub repository for more examples:

Community Examples

Check out community-contributed examples:

Support

Need help with integration? Join our community:

Found an issue with this page? Report it on GitHub