### Supabase Authentication Client Setup
Source: https://docs.shipthat.app/docs/configurations
Initializes the Supabase client for authentication services. Requires Supabase URL and Anon Key, which are used to create an instance of SupabaseClient.
```swift
let client = SupabaseClient(supabaseURL: URL(string: "https://your-instance.supabase.co")!, supabaseKey: "your-supabase-annon-key")
```
--------------------------------
### Paywall3View SwiftUI Code Example
Source: https://docs.shipthat.app/docs/in-app-purchases
A SwiftUI code example demonstrating how Paywall3View interacts with the PurchaseManager to display product information and initiate purchases.
```swift
struct Paywall3View: View {
@Environment(PurchaseManager.self) private var purchaseManager
var body: some View {
ForEach(purchaseManager.products, id: \.self) {
product in
Button(action: {
// Initiate the purchase
await purchaseManager.purchase(product)
}) {
// Custom view representing the product
Text(product.displayName)
}
}
}
}
```
--------------------------------
### SwiftUI App Initialization
Source: https://docs.shipthat.app/index
Demonstrates the basic initialization of the ShipThatApp application, including configuring telemetry and revenue cat services. This is the entry point for the application's setup.
```swift
struct ShipThatAppApp: App {
// MARK: - Initialization
init() {
configureTelemetry()
configureRevenueCat()
}
// ...
}
```
--------------------------------
### SwiftUI App Configuration Example
Source: https://docs.shipthat.app/index
Illustrates how to customize the ShipThatApp boilerplate by adding custom configurations within the application's initialization block. This allows for personalization of splash screens, authentication methods, and other services.
```swift
// ShipThatAppApp.swift
…
init() {
configureTelemetry()
configureRevenueCat()
// Add your custom configurations
}
…
```
--------------------------------
### Cloning ShipThatApp Repository
Source: https://docs.shipthat.app/index
Provides the command to clone the ShipThatApp project from its GitHub repository. This is the first step for users to get the boilerplate code into their local environment.
```bash
git clone https://github.com/matious89pl/ShipThatApp.git
cd ShipThatApp
```
--------------------------------
### RevenueCat In-App Purchases Configuration
Source: https://docs.shipthat.app/docs/configurations
Sets up the RevenueCat SDK for managing in-app purchases and subscriptions. An API Key from RevenueCat is required, which must be added to Info.plist and then used to configure the Purchases client.
```APIDOC
Info.plist Configuration:
RC_API_KEY
YOUR_REVENUECAT_API_KEY
Swift Initialization:
private func configureRevenueCat() {
guard let revenueCatApiString = Bundle.main.infoDictionary?["RC_API_KEY"] as? String else { return }
Purchases.logLevel = .debug
Purchases.configure(withAPIKey: revenueCatApiString)
}
Usage:
Call configureRevenueCat() within the init() of ShipThatAppApp.
```
```swift
private func configureRevenueCat() {
guard let revenueCatApiString = Bundle.main.infoDictionary?["RC_API_KEY"] as? String else { return }
Purchases.logLevel = .debug
Purchases.configure(with: revenueCatApiString)
}
```
--------------------------------
### Swift String Extension: Test Email Validation
Source: https://docs.shipthat.app/docs/string-extensions
Provides an example of unit testing the `isValidEmail` extension method using XCTest. It asserts the expected boolean output for both valid and invalid email string formats.
```swift
func testEmailValidation() {
let validEmail = "test@example.com"
let invalidEmail = "test_at_example.com"
XCTAssertTrue(validEmail.isValidEmail(), "The method should return true for a valid email")
XCTAssertFalse(invalidEmail.isValidEmail(), "The method should return false for an invalid email")
}
```
--------------------------------
### Swift Feature Model Definition and Usage
Source: https://docs.shipthat.app/docs/feature-model
Demonstrates the Swift `Feature` struct, conforming to `Identifiable`, used for onboarding content. Shows its properties (`id`, `title`, `description`, `icon`) and how it's utilized within a SwiftUI `OnboardingView` using `ForEach`.
```swift
struct Feature {
let id: UUID = UUID()
let title: String
let description: String
let icon: String?
}
struct OnboardingView: View {
let features: [Feature] = [
Feature(title: "Easy to Use", description: "Get started quickly with a user-friendly interface.", icon: "icon-easy-to-use"),
Feature(title: "Secure", description: "We use state-of-the-art security measures to protect your information.", icon: "icon-secure")
]
var body: some View {
TabView {
ForEach(features) { feature in
FeatureCardView(feature: feature)
}
}
.tabViewStyle(PageTabViewStyle())
}
}
```
--------------------------------
### RevenueCat Configuration for Info.plist
Source: https://docs.shipthat.app/docs/in-app-purchases
Details the necessary steps to configure RevenueCat by adding the API key to the application's Info.plist file.
```APIDOC
RevenueCat Configuration:
To configure RevenueCat, an API key from the RevenueCat dashboard must be added to your Info.plist file.
Steps:
1. Obtain the RevenueCat API Key from your RevenueCat project dashboard.
2. Add the key to your Info.plist file using the following structure:
RC_API_KEY
Your_RevenueCat_API_Key
3. Initialize RevenueCat in the app entry point (e.g., ShipThatAppApp.swift) using a function like configureRevenueCat().
```
--------------------------------
### AuthManager Initialization
Source: https://docs.shipthat.app/docs/authentication
Initializes the AuthManager with Supabase client credentials. Requires Supabase URL and Key to connect to the authentication service.
```swift
let client = SupabaseClient(supabaseURL: URL(string: "")!, supabaseKey: "")
```
--------------------------------
### ContentView SwiftUI Structure
Source: https://docs.shipthat.app/docs/content-view
This conceptual code sample illustrates the structure of ContentView.swift, demonstrating how it uses SwiftUI property wrappers like @AppStorage and @EnvironmentObject to conditionally render different views based on the user's onboarding and authentication status.
```swift
struct ContentView: View {
@AppStorage("onboarding_complete") var onBoardingComplete: Bool = false
@EnvironmentObject var authManager: AuthManager
var body: some View {
ZStack {
if !onBoardingComplete {
OnboardingView()
} else if !authManager.isUserAuthenticated {
SignInView()
} else {
HomeView()
}
}
}
}
```
--------------------------------
### SplashScreenStateManager API
Source: https://docs.shipthat.app/docs/splash-screen-state-manager
Documentation for the SplashScreenStateManager class, detailing its purpose in managing splash screen transitions and its key `dismiss` function for controlling the animation progression.
```APIDOC
SplashScreenStateManager:
File: SplashScreenStateManager.swift
Purpose: Manages the state and transition of the splash screen animation and determines when to navigate to the main content of the app.
Key Functions:
dismiss: Controls the progression of the splash screen through its steps, from start to finish (firstStep, secondStep, finished).
Usage: This manager affects the user experience right from the launch of the app. It is used in the SplashScreenView to control the transition of the view states from the initial splash to the app's main content view.
```
--------------------------------
### SignInViewModel Conceptual Usage in SwiftUI
Source: https://docs.shipthat.app/docs/signin-view-model
Illustrates how the SignInViewModel can be integrated into a SwiftUI View for handling user input, displaying errors, and triggering authentication actions via buttons.
```swift
struct SignInView: View {
@StateObject private var signInViewModel = SignInViewModel()
@State private var email: String = ""
@State private var password: String = ""
var body: some View {
Form {
TextField("Email", text: $email)
SecureField("Password", text: $password)
if let errorText = signInViewModel.errorText {
Text(errorText).foregroundColor(.red)
}
Button("Sign In") {
Task {
do {
let user = try await signInViewModel.signInWithEmail(email: email, password: password)
// Handle successful sign-in, e.g., navigate to home screen
} catch {
// Update UI with error message from ViewModel
signInViewModel.errorText = error.localizedDescription
}
}
}
}
}
}
```
--------------------------------
### TelemetryDeck Analytics Configuration
Source: https://docs.shipthat.app/docs/configurations
Configures the TelemetryDeck SDK for app analytics. Requires an App ID from TelemetryDeck, which should be added to Info.plist and then used to initialize the TelemetryManager in the application's entry point.
```APIDOC
Info.plist Configuration:
TD_APP_ID
YOUR_TELEMETRYDECK_APP_ID
Swift Initialization:
private func configureTelemetry() {
guard let telemetryDeckAppID = Bundle.main.infoDictionary?["TD_APP_ID"] as? String else { return }
let configuration = TelemetryManagerConfiguration(appID: telemetryDeckAppID)
TelemetryManager.initialize(with: configuration)
}
Usage:
Call configureTelemetry() within the init() of ShipThatAppApp.
```
```swift
private func configureTelemetry() {
guard let telemetryDeckAppID = Bundle.main.infoDictionary?["TD_APP_ID"] as? String else { return }
let configuration = TelemetryManagerConfiguration(appID: telemetryDeckAppID)
TelemetryManager.initialize(with: configuration)
}
```
--------------------------------
### AuthManager API Documentation
Source: https://docs.shipthat.app/docs/auth-manager
Documentation for the AuthManager class, responsible for handling all authentication-related tasks including user session management, registration, sign-in methods, magic link authentication, and sign-out.
```APIDOC
AuthManager:
Purpose: Handles all the authentication related tasks such as signing in, signing up, sending magic links, managing the current user session, and signing out.
File: AuthManager.swift
Key Functions:
getCurrentSession(): Fetches the current user session if available.
getSessionFromUrl(url: URL): Processes a URL callback after a magic link sign-in, extracting the user session.
registerNewUserWithEmail(email: String, password: String): Registers a new user using their email and password.
signInWithEmail(email: String, password: String): Authenticates a user by their email and password.
signInWithApple(idToken: String): Authenticates a user with Sign in with Apple using the provided idToken.
sendMagicLink(email: String): Sends a magic link to the user's email for passwordless authentication.
signOut(): Signs out the current user.
Usage:
Wisely employed throughout the app in views where user authentication state changes are relevant, such as the SignInView or the SettingsView.
```
--------------------------------
### SignInViewModel Swift Implementation
Source: https://docs.shipthat.app/docs/signin-view-model
Details the SignInViewModel's role in managing user authentication, including form validation, initiating sign-in/registration, and handling magic link requests. It outlines key properties like errorText and isUserAuthenticated, and functions for validation and authentication actions.
```swift
class SignInViewModel: ObservableObject {
@Published var errorText: String = ""
@Published var isUserAuthenticated: Bool = false
// Validates email and password format.
func isFormValid(email: String, password: String) -> Bool {
// Implementation details for email format and password strength checks.
// Returns true if valid, false otherwise.
return true // Placeholder
}
// Registers a new user with email and password.
func registerNewUserWithEmail(email: String, password: String) async throws -> AppUser {
// Calls AuthManager to perform registration.
// Returns the AppUser object upon success.
// Throws an error on failure.
return AppUser() // Placeholder
}
// Sends a magic link for passwordless authentication.
func sendMagicLink(email: String) async throws {
// Calls AuthManager to send the magic link.
// Throws an error on failure.
}
// Signs in a user with email and password.
func signInWithEmail(email: String, password: String) async throws -> AppUser {
// Calls AuthManager to perform sign-in.
// Returns the AppUser object upon success.
// Throws an error on failure.
return AppUser() // Placeholder
}
}
```
--------------------------------
### SignInViewModel Methods
Source: https://docs.shipthat.app/docs/authentication
Handles the UI logic for authentication forms, validating inputs and calling corresponding AuthManager methods. It provides feedback to the user through an errorText property.
```APIDOC
SignInViewModel:
errorText: String
A string to display error messages to the user.
isFormValid(email: String, password: String) -> Bool
Validates email and password inputs against predefined criteria.
email: The email string to validate.
password: The password string to validate.
Returns: True if the form inputs are valid, false otherwise.
registerNewUserWithEmail(email: String, password: String) async throws -> AppUser
Delegates user registration to AuthManager.registerNewUserWithEmail.
sendMagicLink(email: String) async throws
Delegates sending a magic link to AuthManager.sendMagicLink.
signInWithEmail(email: String, password: String) async throws -> AppUser
Delegates email/password sign-in to AuthManager.signInWithEmail.
```
--------------------------------
### AuthManager Authentication Methods
Source: https://docs.shipthat.app/docs/authentication
Provides methods for user authentication, including registration, email/password login, magic link, and Sign in with Apple. These methods interact with the GoTrue authentication service and return AppUser objects on success or throw errors on failure.
```APIDOC
AuthManager Service:
__init__(client: SupabaseClient)
client: The Supabase client instance for authentication.
registerNewUserWithEmail(email: String, password: String) async throws -> AppUser
email: The user's email address for registration.
password: The user's chosen password.
Returns: An AppUser object upon successful registration.
signInWithEmail(email: String, password: String) async throws -> AppUser
email: The user's registered email address.
password: The user's password.
Returns: An AppUser object upon successful sign-in.
Throws: Error if sign-in fails.
sendMagicLink(email: String) async throws
email: The user's email address to send the magic link to.
Throws: Error if the magic link cannot be sent.
signInWithApple(idToken: String) async throws -> AppUser
idToken: The identity token received from Apple's sign-in process.
Returns: An AppUser object upon successful sign-in.
getCurrentSession() async throws -> AppUser
Fetches the current user session and updates the internal state.
Returns: The current AppUser object.
getSessionFromUrl(url: URL) async throws -> AppUser
Processes a URL callback, typically from a magic link, to retrieve user session details.
url: The callback URL.
Returns: An AppUser object from the session.
updateCurrentSession() async
Refreshes the current user session state, often called on app launch.
signOut() async throws
Invalidates the current user session and logs the user out.
```
--------------------------------
### Swift Splash Screen Delay Configuration
Source: https://docs.shipthat.app/docs/configurations
Configures the splash screen delay duration within the `ShipThatAppApp.swift` file. This snippet shows how to use `Task.sleep` to introduce a delay before dismissing the splash screen, allowing customization of the display time.
```swift
private func dismissSplashScreenAfterDelay() async {
try? await Task.sleep(for: .seconds(1)) // Set your desired time here
splashScreenState.dismiss()
}
```
--------------------------------
### PurchaseManager Swift Class Documentation
Source: https://docs.shipthat.app/docs/in-app-purchases
Documents the PurchaseManager class in Swift, detailing its properties for product management and functions for handling purchases and transaction updates. It relies on RevenueCat and StoreKit for in-app purchase operations.
```APIDOC
PurchaseManager.swift Class Documentation:
This class is central to the in-app purchase functionality, handling product fetching, purchasing, and transaction state management.
Properties:
- productIds: Set
Identifiers for your products, matching App Store Connect and RevenueCat.
- products: [Product]
An array of Product objects representing available products.
- purchasedProductIDs: Set
Keeps track of product IDs purchased by the user.
Functions:
- loadProducts():
Calls Product.products(for:) to load SKProduct information from the App Store.
- purchase(_ product: Product) async:
Initiates a purchase transaction for the given Product.
- updatePurchasedProducts():
Checks current entitlements to update purchasedProductIDs.
Transaction Observer:
- observeTransactionUpdates:
Observes the StoreKit transaction queue and processes updates, including verification, pending states, and cancellations.
```
--------------------------------
### Handle Incoming URL for Magic Link Authentication
Source: https://docs.shipthat.app/docs/authentication
This snippet demonstrates how to handle incoming URLs, typically from a magic link, within a SwiftUI view. It uses the .onOpenURL modifier to capture the URL and pass it to a handler function for processing.
```swift
.onOpenURL { incomingURL in
handleIncomingURL(incomingURL)
}
```
--------------------------------
### TelemetryDeck API Reference
Source: https://docs.shipthat.app/docs/analytics
This section provides a reference for key TelemetryDeck functionalities used in the boilerplate. It covers initialization, sending events, and setting debug identifiers.
```apidoc
TelemetryManager:
initialize(with: TelemetryManagerConfiguration)
Initializes the TelemetryManager with the provided configuration.
Parameters:
configuration: TelemetryManagerConfiguration object containing the appID.
TelemetryManagerConfiguration:
appID: String
The unique identifier for your application on TelemetryDeck.
send(event: String, with properties: [String: Any]? = nil)
Sends a custom event to TelemetryDeck.
Parameters:
event: The name of the event to send (e.g., "AppLaunched", "PurchaseAttempt").
properties: An optional dictionary of key-value pairs to associate with the event.
setDebugIdentifier(identifier: String)
Sets a unique identifier for the current device during development.
This helps in filtering development data from production analytics.
Parameters:
identifier: A string representing the debug identifier (e.g., "Developer_iPhone").
Note: This should only be used in development builds and conditionally excluded from production.
```
--------------------------------
### PurchaseManager Swift Implementation
Source: https://docs.shipthat.app/docs/purchase-manager
Details the PurchaseManager class in Swift, responsible for managing the in-app purchase lifecycle. It covers fetching products, initiating purchases, handling transaction results, and observing background updates from StoreKit.
```swift
class PurchaseManager {
// Purpose: Manages the purchase lifecycle, which includes loading available products, making purchases, restoring purchases, and keeping track of what the user purchased.
// Fetches products from the App Store based on given product IDs and makes them available for purchase.
func loadProducts(productIDs: [String]) async throws {
// ... implementation ...
}
// Initiates a purchase of a selected product and handles the result, which can be successful, pending, or failed due to user cancellation.
func purchase(product: Product) async throws -> PurchaseResult {
// ... implementation ...
}
// Updates the user's purchased products based on completed transactions.
func updatePurchasedProducts() async {
// ... implementation ...
}
// A background task that listens for updates from StoreKit regarding transactions and reacts accordingly.
func observeTransactionUpdates() {
// ... implementation ...
}
}
// Usage:
// Mainly used within paywall views (Paywall1View, Paywall2View, Paywall3View) to present the user with purchase options and handle their transaction responses.
// It's also used in the SettingsView to give users the option to restore purchases or upgrade their subscription.
```
--------------------------------
### Custom URL Scheme for Magic Links
Source: https://docs.shipthat.app/docs/configurations
Configures a custom URL scheme in the application's Info.plist to handle incoming magic links for passwordless authentication. This allows the app to receive and process authentication deep links.
```APIDOC
Info.plist Configuration:
CFBundleURLTypes
CFBundleURLSchemes
shipthatapp
Note:
Replace 'shipthatapp' with your chosen custom URL scheme. The app must also implement logic to handle these incoming URLs.
```
```xml
CFBundleURLTypes
CFBundleURLSchemes
shipthatapp
```
--------------------------------
### SwiftUI Splash Screen View Implementation
Source: https://docs.shipthat.app/docs/splash-screen
The SplashScreenView is a SwiftUI view responsible for displaying the application's splash screen. It utilizes state management to control animations and transitions, providing an engaging user experience during app startup. It binds to an ObservableObject for state updates.
```Swift
struct SplashScreenView: View {
// Bind to the SplashScreenStateManager
@EnvironmentObject private var splashScreenState: SplashScreenStateManager
// States for animating the splash screen elements
@State private var firstAnimation = false
@State private var secondAnimation = false
@State private var startFadeoutAnimation = false
// Body
var body: some View {
ZStack {
// Background color or image
Color(.accent).edgesIgnoringSafeArea(.all)
// Content: Can include logo, title, tagline, and animations
VStack {
Image("Logo")
// Animation and transition effects based on splash screen state
}
// Transitions and animations are triggered by splashScreenState changes
}
.onReceive(animationTimer) { timerValue in
updateAnimation()
}
}
// Defines how animations are triggered based on splash screen state
private func updateAnimation() {
// ... implementation details ...
}
}
```
--------------------------------
### Swift: Manage App Review Request Logic
Source: https://docs.shipthat.app/docs/review-request
This snippet covers the core logic for managing app review requests. It includes incrementing a user interaction count and conditionally triggering a delayed review prompt based on interaction thresholds and app version.
```swift
private func incrementProcessCount() {
count += 1
let currentVersion = Bundle.main.object(forInfoDictionaryKey: kCFBundleVersionKey as String) as? String ?? ""
if count >= MIN_APP_RUNS_BEFORE_REVIEW_REQ && currentVersion != lastVersionPromptedForReview {
requestReviewAfterDelay(for: currentVersion)
}
}
```
```swift
private func requestReviewAfterDelay(for version: String) {
Task {
try await Task.sleep(for: .seconds(2))
await requestReview()
lastVersionPromptedForReview = version
TelemetryManager.send("reviewRequested", with: ["version": version])
}
}
```
```swift
@Environment(\.requestReview) private var requestReview
```
--------------------------------
### Initialize TelemetryDeck in App Entry
Source: https://docs.shipthat.app/docs/analytics
This Swift code demonstrates how to initialize the TelemetryManager with your TelemetryDeck App ID. It reads the ID from Info.plist and configures the manager upon app launch.
```swift
private func configureTelemetry() {
guard let telemetryDeckAppID = Bundle.main.infoDictionary?["TD_APP_ID"] as? String else { return }
let configuration = TelemetryManagerConfiguration(appID: telemetryDeckAppID)
TelemetryManager.initialize(with: configuration)
}
```