Skip to main content

Get Started

1

Create a new project

Create a new iOS or macOS project for this quickstart.In Xcode:
  1. FileNewProject (or ⌘+Shift+N)
  2. Select either:
    • iOS tab → App template
    • macOS tab → App template
  3. Configure your project:
    • Product Name: Auth0-Sample
    • Interface: SwiftUI
    • Language: Swift
    • Use Core Data: Unchecked
    • Include Tests: Checked (recommended)
  4. Choose a location and click Create
This creates a standard app with SwiftUI and Swift Package Manager support, perfect for Auth0 integration.
2

Add the Auth0 SDK

Add the Auth0 SDK to your project using your preferred package manager.
  • Swift Package Manager
  • CocoaPods
  • Carthage
In Xcode:
  1. FileAdd Package Dependencies… (or ⌘+Shift+K)
  2. Enter the Auth0 SDK URL:
    https://github.com/auth0/Auth0.swift
    
  3. Add Package → Select your app target → Add Package
3

Configure Auth0

Create a new app on your Auth0 tenant and configure your project.
  • Auth0.plist
  • Programmatic
Create Auth0.plist in your project directory:
Auth0.plist
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>ClientId</key>
    <string>YOUR_AUTH0_CLIENT_ID</string>
    <key>Domain</key>
    <string>YOUR_AUTH0_DOMAIN</string>
</dict>
</plist>
  1. Go to Auth0 Dashboard
  2. Applications > Create Application > Name it, select Native > Create
  3. Copy Client ID and Domain from Settings tab into Auth0.plist
  4. Drag Auth0.plist into Xcode (check “Add to target”)
  5. Set Allowed Callback URLs and Allowed Logout URLs:
iOS:
https://YOUR_AUTH0_DOMAIN/ios/YOUR_BUNDLE_IDENTIFIER/callback,
YOUR_BUNDLE_IDENTIFIER://YOUR_AUTH0_DOMAIN/ios/YOUR_BUNDLE_IDENTIFIER/callback
macOS:
https://YOUR_AUTH0_DOMAIN/macos/YOUR_BUNDLE_IDENTIFIER/callback,
YOUR_BUNDLE_IDENTIFIER://YOUR_AUTH0_DOMAIN/macos/YOUR_BUNDLE_IDENTIFIER/callback
4

Create the Authentication Service

Create AuthenticationService.swift:
  1. Right-click your project → New File…Swift File
  2. Name it AuthenticationService
  3. Replace contents with:
AuthenticationService.swift
import Foundation
import Auth0
import Combine

@MainActor
class AuthenticationService: ObservableObject {
    @Published var isAuthenticated = false
    @Published var user: User?
    @Published var isLoading = false
    @Published var errorMessage: String?
    
    private let credentialsManager = CredentialsManager(authentication: Auth0.authentication())
    
    init() {
        Task {
            await checkAuthenticationStatus()
        }
    }
    
    private func checkAuthenticationStatus() async {
        isLoading = true
        defer { isLoading = false }
        
        guard let credentials = try? await credentialsManager.credentials() else {
            isAuthenticated = false
            return
        }
        
        isAuthenticated = true
        // Get user info from the ID token
        user = credentials.user
    }
    
    func login() async {
        isLoading = true
        errorMessage = nil
        defer { isLoading = false }
        
        do {
            let credentials = try await Auth0
                .webAuth()
                .scope("openid profile email offline_access")
                .start()
            
            _ = try credentialsManager.store(credentials: credentials)
            isAuthenticated = true
            // Get user info from the ID token
            user = credentials.user
        } catch {
            errorMessage = "Login failed: \(error.localizedDescription)"
        }
    }
    
    func logout() async {
        isLoading = true
        defer { isLoading = false }
        
        do {
            try await Auth0.webAuth().clearSession()
            _ = credentialsManager.clear()
            isAuthenticated = false
            user = nil
        } catch {
            errorMessage = "Logout failed: \(error.localizedDescription)"
        }
    }
}
5

Create UI Components

Create UI files and add code:
touch AuthenticatedView.swift UnauthenticatedView.swift ProfileCard.swift LoadingView.swift
6

Configure Authentication Flow (Optional)

Eliminate the permission alert by choosing one option:
Skip this step to use the default behavior with a permission alert. You can configure this later.
7

Run your app

Press ⌘+R in Xcode.
  1. Tap “Log In” → Permission alert (if using default) → Tap “Continue”
  2. Complete login in browser
  3. See your profile!
CheckpointYou now have a fully functional Auth0 login in your iOS or macOS app!

Troubleshooting & Advanced

Build errors: ‘Auth0’ module not found

Solutions:
  1. Swift Package Manager: Check Package Dependencies → Verify Auth0.swift is listed
  2. CocoaPods: Ensure you’re opening the .xcworkspace file, not .xcodeproj
  3. Carthage: Verify Auth0.xcframework is added to Frameworks, Libraries, and Embedded Content
  4. Clean and rebuild: ⌘+Shift+K then ⌘+R
  5. Restart Xcode if needed

App crashes: ‘Auth0.plist not found’

Fix:
  1. Verify Auth0.plist is in your Xcode project navigator
  2. Select the file → Inspector → Ensure your app target is checked
  3. Confirm it has ClientId and Domain keys with your values
  4. Alternative: Use programmatic configuration (see Step 3, Programmatic tab)

Browser opens but never returns to app

Fix:
  1. Check callback URLs in Auth0 Dashboard match your bundle identifier and platform exactly
  2. For iOS: URLs should contain /ios/, for macOS: /macos/
  3. Verify bundle identifier in Xcode matches Auth0 settings
  4. Ensure no typos in URLs (common: missing colons, wrong domain format)
  5. Custom domain users: Verify you’re using your custom domain, not the Auth0 domain

Permission alert appears every time

This is standard iOS/macOS security behavior when using custom URL schemes. See Step 6 to eliminate this alert using Universal Links or Ephemeral Sessions.
If you’re using a custom domain, use its value instead of your Auth0 domain everywhere.Example: Use login.example.com instead of tenant.auth0.comThis is required for certain features to work properly:
  • Update Auth0.plist with your custom domain
  • Use custom domain in callback/logout URLs
  • For Universal Links, use: webcredentials:login.example.com

App Store Preparation

  • Configure Universal Links to eliminate the permission alert
  • Test on multiple platform versions and device sizes
  • Implement proper error handling for network failures
  • Add Privacy Usage descriptions if using Keychain with biometrics
  • Follow App Store Review Guidelines for authentication flows

Security Best Practices

  • Never log sensitive authentication data in production
  • Implement App Transport Security (ATS) compliance
  • Use HTTPS for all network requests
  • Do NOT pin Auth0 API certificates - Auth0 does not recommend this practice

Performance Optimization

  • All async operations properly use @MainActor for UI updates
  • @Published properties use proper memory handling
  • Credentials are cached securely in the Keychain for offline access
  • User profile is retrieved from ID token (no additional network request)

Enhanced Keychain Security with Biometrics

Require Face ID or Touch ID to access stored credentials:
private let credentialsManager: CredentialsManager = {
    let manager = CredentialsManager(authentication: Auth0.authentication())
    manager.enableBiometrics(
        withTitle: "Unlock with Face ID", 
        cancelTitle: "Cancel", 
        fallbackTitle: "Use Passcode"
    )
    return manager
}()
When enabled, users must authenticate with biometrics before the SDK can retrieve stored credentials.

Automatic Token Refresh

The CredentialsManager automatically refreshes expired access tokens:
// Get credentials - automatically refreshes if expired
func getAccessToken() async throws -> String {
    let credentials = try await credentialsManager.credentials()
    return credentials.accessToken
}
Use this pattern when making API calls that require an access token.

Shared Credentials Across App Extensions

For widgets, app extensions, or background tasks that need access tokens:
// Create a shared credentials manager with an app group
let credentialsManager = CredentialsManager(
    authentication: Auth0.authentication(),
    storeKey: "credentials",
    storage: .shared(withIdentifier: "group.com.example.myapp")
)
Requirements:
  1. Enable App Groups capability in Xcode for all targets
  2. Use the same app group identifier across targets
  3. Configure the shared CredentialsManager in each target

Authentication Flow Options Comparison

FeatureUniversal LinksEphemeral SessionDefault (Alert)
Permission AlertNoneNoneShows alert
SSO SupportYesNoYes
Apple Developer AccountRequiredNot requiredNot required
User ExperienceBestGoodAcceptable
Setup ComplexityMediumEasyEasy
Private Browsing SupportYesYesNo
Recommendations:
  • Production apps: Universal Links (best UX, requires Apple Developer account)
  • Testing/Development: Ephemeral Sessions (quick setup, no alert)
  • Quick start/Prototyping: Default with alert (no setup, can migrate later)