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:
| Level | Description |
|---|
.trace | Most verbose, includes all internal details |
.debug | Detailed information for debugging |
.info | General operational information (default) |
.warning | Warnings that don’t prevent operation |
.error | Errors that affect functionality |
.critical | Critical failures |
Log Destinations:
| Destination | Description |
|---|
.console | Standard output (print) |
.osLog | Apple’s unified logging system (recommended for iOS/macOS) |
.none | Disable logging |
.custom | Provide 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
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:
- No email verification - Users can sign in immediately after registration.
SignUpResponse will have hasSession = true.
- Link-based verification - Users must open their email and click the verification link before they can sign in.
- 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.
| Method | Description |
|---|
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.
Parameters
redirectTo (String) - Callback URL where InsForge will redirect after authentication
Returns
Returns AuthResponse containing the authenticated user and session tokens.
Implementation
InsForge SDK supports two callback URL methods:
- Custom URL Scheme - Simple, recommended for development and macOS desktop apps
- Universal Links (iOS) / App Links (Android) - Recommended for production mobile apps
Option 1: Custom URL Scheme (Recommended for Development)
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)")
Option 2: Universal Links / App Links (Recommended for Production)
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
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)")
}
}