Skip to main content

Installation

Add InsForge to your Swift Package Manager dependencies:
dependencies: [
    .package(url: "https://github.com/insforge/insforge-swift.git", from: "0.0.9")
]
import InsForge

let insforge = InsForgeClient(
    baseURL: URL(string: "https://your-app.insforge.app")!,
    anonKey: "your-anon-key"
)

Enable Logging (Optional)

For debugging, you can configure the SDK log level and destination:
let options = InsForgeClientOptions(
    global: .init(
        logLevel: .debug,
        logDestination: .osLog,
        logSubsystem: "com.example.MyApp"
    )
)

let insforge = InsForgeClient(
    baseURL: URL(string: "https://your-app.insforge.app")!,
    anonKey: "your-anon-key",
    options: options
)
Log Levels:
LevelDescription
.traceMost verbose, includes all internal details
.debugDetailed information for debugging
.infoGeneral operational information (default)
.warningWarnings that don’t prevent operation
.errorErrors that affect functionality
.criticalCritical failures
Log Destinations:
DestinationDescription
.consoleStandard output (print)
.osLogApple’s unified logging system (recommended for iOS/macOS)
.noneDisable logging
.customProvide your own LogHandler factory
Use .info or .error in production to avoid exposing sensitive data in logs.

signUp()

Create a new user account with email and password.

Parameters

  • email (String) - User’s email address
  • password (String) - User’s password
  • name (String, optional) - User’s display name

Returns

SignUpResponse

SignUpResponse

public struct SignUpResponse: Codable, Sendable {
    /// User object (nil when email verification is required)
    public let user: User?
    /// Access token (nil when email verification is required)
    public let accessToken: String?
    /// Refresh token (nil when email verification is required)
    public let refreshToken: String?
    /// Indicates if email verification is required before sign-in
    public let requireEmailVerification: Bool?

    /// Check if email verification is required
    public var needsEmailVerification: Bool
    /// Check if sign up completed with session (no verification required)
    public var hasSession: Bool
}

Example (Complete Flow with Verification)

func handleSignUp(email: String, password: String, name: String?) async {
    do {
        let result = try await insforge.auth.signUp(
            email: email,
            password: password,
            name: name
        )

        if result.needsEmailVerification {
            // Show verification code input screen
            // User will receive a 6-digit code via email
            showEmailVerificationScreen(email: email)
        } else if result.hasSession {
            // Registration complete, user is signed in
            navigateToDashboard()
        }
    } catch {
        showError(error.localizedDescription)
    }
}

// Called when user enters the verification code
func handleVerifyEmail(email: String, code: String) async {
    do {
        try await insforge.auth.verifyEmail(email: email, code: code)
        // Verification successful, user can now sign in
        navigateToSignIn()
    } catch {
        showError("Invalid verification code")
    }
}

// Called when user requests a new verification code
func handleResendCode(email: String) async {
    do {
        try await insforge.auth.resendVerificationEmail(email: email)
        showMessage("Verification code sent to \(email)")
    } catch {
        showError("Failed to resend verification code")
    }
}

Email Verification

For users who register with email, the InsForge backend provides three options:
  1. No email verification - Users can sign in immediately after registration. SignUpResponse will have hasSession = true.
  2. Link-based verification - Users must open their email and click the verification link before they can sign in.
  3. Code-based verification - The InsForge backend sends a 6-digit verification code to the user’s email. The client app needs to display a verification screen where users can enter the code, then call verifyEmail(email:code:) to complete verification. Only after this can users sign in with email + password.
When requireEmailVerification is true, the response will have:
  • accessToken = nil
  • user = nil
  • needsEmailVerification = true
This indicates that verification via option 2 or 3 is required before the user can sign in.
MethodDescription
verifyEmail(email:code:)Verify email with 6-digit code
resendVerificationEmail(email:)Resend verification code to email

signIn()

Sign in an existing user with email and password.

Parameters

  • email (String) - User’s email address
  • password (String) - User’s password

Example

do {
    let result = try await insforge.auth.signIn(
        email: "user@example.com",
        password: "secure_password123"
    )

    if let user = result.user {
        print("Welcome back, \(user.profile?.name ?? user.email)")
    }
} catch {
    print("Sign in failed: \(error)")
}

Email Verification

If the sign in response is:
{"error":"FORBIDDEN","message":"Email verification required","statusCode":403,"nextActions":"Please verify your email address before logging in"}
This indicates that verification via option 2 or 3 (link or code, see signUp()) is required before the user can sign in.

signOut()

Sign out the current user.

Example

do {
    try await insforge.auth.signOut()
    print("User signed out")
} catch {
    print("Sign out failed: \(error)")
}

getCurrentUser()

Get authenticated user with profile data.

Example

do {
    if let user = try await insforge.auth.getCurrentUser() {
        print("Email: \(user.email)")
        print("Name: \(user.profile?.name ?? "N/A")")
    } else {
        print("No user signed in")
    }
} catch {
    print("Error: \(error)")
}

setProfile()

Update current user’s profile.

Example

do {
    let result = try await insforge.auth.setProfile([
        "name": "JohnDev",
        "bio": "iOS Developer",
        "avatar_url": "https://example.com/avatar.jpg"
    ])
    print("Profile updated")
} catch {
    print("Update failed: \(error)")
}

Password Reset

InsForge supports two password reset methods, configured in the backend:
  • Code method: User receives a 6-digit code via email, verifies it to get a reset token, then resets password
  • Link method: User receives a magic link via email containing the reset token, then resets password directly

sendPasswordReset()

Send a password reset email to the user. The email will contain either a 6-digit code or a magic link depending on the backend configuration.

Parameters

  • email (String) - User’s email address

Example

do {
    try await insforge.auth.sendPasswordReset(email: "user@example.com")
    // Show message to check email
    showMessage("If your email is registered, you will receive a password reset email.")
} catch {
    print("Failed to send reset email: \(error)")
}

exchangeResetPasswordToken()

Exchange a 6-digit reset code for a reset token. This method is only used with the code-based reset flow.

Parameters

  • email (String) - User’s email address
  • code (String) - 6-digit numeric code received via email

Returns

ResetPasswordTokenResponse

ResetPasswordTokenResponse

public struct ResetPasswordTokenResponse: Codable, Sendable {
    /// Reset token to use with resetPassword()
    public let token: String
    /// Token expiration timestamp
    public let expiresAt: Date?
}

Example

do {
    let response = try await insforge.auth.exchangeResetPasswordToken(
        email: "user@example.com",
        code: "123456"
    )
    // Store the token and proceed to password reset screen
    let resetToken = response.token
    showPasswordResetScreen(token: resetToken)
} catch {
    print("Invalid or expired code: \(error)")
}

resetPassword()

Reset the user’s password using a reset token.

Parameters

  • otp (String) - Reset token (from exchangeResetPasswordToken() for code flow, or from magic link URL for link flow)
  • newPassword (String) - New password meeting the configured requirements

Example

do {
    try await insforge.auth.resetPassword(
        otp: resetToken,
        newPassword: "newSecurePassword123"
    )
    // Password reset successful
    showMessage("Password reset successfully. You can now sign in.")
    navigateToSignIn()
} catch {
    print("Password reset failed: \(error)")
}

signInWithDefaultView()

InsForge provides a hosted authentication page that supports:
  • OAuth Providers: Google, GitHub, Discord, LinkedIn, Facebook, Instagram, TikTok, Apple, X (Twitter), Spotify, Microsoft
  • Email + Password: Traditional email/password authentication
This approach simplifies authentication by letting InsForge handle the UI and OAuth flows.
For direct OAuth provider authentication without the hosted page, use signInWithOAuthView() instead.

Parameters

  • redirectTo (String) - Callback URL where InsForge will redirect after authentication

Returns

AuthResponse
Returns AuthResponse containing the authenticated user and session tokens.

Implementation

InsForge SDK supports two callback URL methods:
  1. Custom URL Scheme - Simple, recommended for development and macOS desktop apps
  2. Universal Links (iOS) / App Links (Android) - Recommended for production mobile apps
Configuration
macOS / iOS (Info.plist):
<key>CFBundleURLTypes</key>
<array>
    <dict>
        <key>CFBundleURLSchemes</key>
        <array>
            <string>yourapp</string>
        </array>
        <key>CFBundleURLName</key>
        <string>com.yourcompany.yourapp</string>
    </dict>
</array>
Usage:
let response = try await client.auth.signInWithDefaultView(
    redirectTo: "yourapp://auth/callback"
)
print("Authenticated: \(response.user.email)")
You can find the documentation for setting up Universal Links / App Links from Apple and Google.

signInWithOAuthView()

Sign in directly with a specific OAuth provider. Unlike signInWithDefaultView() which shows a hosted page with all authentication options, this method opens the OAuth provider’s authentication page directly. On iOS 12+ and macOS 10.15+, the SDK uses ASWebAuthenticationSession to present an in-app authentication browser with automatic callback handling.

Supported Providers

public enum OAuthProvider: String, Sendable {
    case google
    case github
    case discord
    case linkedin
    case facebook
    case instagram
    case tiktok
    case apple
    case x
    case spotify
    case microsoft
}

Parameters

  • provider (OAuthProvider) - The OAuth provider to authenticate with
  • redirectTo (String) - Callback URL where InsForge will redirect after authentication

Returns

AuthResponse
Returns AuthResponse containing the authenticated user and session tokens.

Authentication Flow

1. App calls signInWithOAuthView(provider:redirectTo:)
2. SDK fetches the OAuth authorization URL from InsForge
3. SDK opens in-app authentication browser (ASWebAuthenticationSession)
4. User authenticates with the provider (Google, GitHub, etc.)
5. SDK automatically handles callback and creates session
6. Method returns AuthResponse with user data

Example

import SwiftUI
import InsForge

struct LoginView: View {
    let client: InsForgeClient
    @State private var currentUser: User?
    @State private var errorMessage: String?

    var body: some View {
        VStack(spacing: 16) {
            Text("Sign in with")
                .font(.headline)

            // Google Sign In
            Button {
                Task {
                    do {
                        let response = try await client.auth.signInWithOAuthView(
                            provider: .google,
                            redirectTo: "yourapp://auth/callback"
                        )
                        currentUser = response.user
                    } catch {
                        errorMessage = error.localizedDescription
                    }
                }
            } label: {
                HStack {
                    Image(systemName: "g.circle.fill")
                    Text("Continue with Google")
                }
                .frame(maxWidth: .infinity)
            }
            .buttonStyle(.bordered)

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

URL Scheme Configuration

The callback URL configuration is the same as signInWithDefaultView().

Error Handling

do {
    let result = try await insforge.auth.signIn(
        email: email,
        password: password
    )
} catch let error as InsForgeAuthError {
    switch error {
    case .invalidCredentials:
        print("Invalid email or password")
    case .userNotFound:
        print("User not found")
    case .emailNotVerified:
        print("Please verify your email")
    case .networkError(let underlying):
        print("Network error: \(underlying)")
    default:
        print("Auth error: \(error.localizedDescription)")
    }
}