SDK · Experimental

iOS SDK (Swift)

Native iOS authentication with OAuth 2.0 PKCE, Keychain storage, and Face ID / Touch ID support.

Experimental — unlike the Android and Java SDKs, this one has no CI, minimal test coverage, and no tagged release.

The Swift source is real and the API below is accurate to it, but there's no automated build/test pipeline verifying it compiles or behaves correctly on every change, and no versioned release to pin — only a branch or commit SHA. Treat it as a starting point to fork or contribute to, not a production dependency yet.

Key Features

OAuth 2.0 Authorization Code + PKCE
Secure Keychain token storage
Face ID / Touch ID (via a separate BiometricAuth type)
Automatic token refresh
Standard OIDC user claims
Async/await API

Requirements

  • iOS 15+ / macOS 12+
  • Swift 5.9+
  • Xcode 15+

Installation

Add the package via Swift Package Manager. There is no tagged release yet — pin a branch or commit SHA rather than a version number.

// In Xcode: File → Add Package Dependencies
// Enter repository URL:
https://github.com/idenplane/idenplane-ios

// Or in Package.swift (branch-pinned, no release tag exists yet):
dependencies: [
    .package(url: "https://github.com/idenplane/idenplane-ios", branch: "main")
]

Configuration

Create an AuthConfig and an IdenplaneClient in your app delegate or SwiftUI App.

import Idenplane

let config = AuthConfig(
    serverUrl: URL(string: "https://auth.example.com")!,
    realm: "my-realm",
    clientId: "my-ios-app",
    redirectUri: "myapp://callback"
)
let idenplane = IdenplaneClient(config: config)

Login with PKCE

The SDK handles the full OAuth 2.0 Authorization Code + PKCE flow via ASWebAuthenticationSession.

// Present the system login sheet
try await idenplane.login()

// Handle the redirect back into the app (e.g. in your SwiftUI .onOpenURL)
try await idenplane.handleRedirectURL(url)

// Check authentication state
if idenplane.isAuthenticated {
    let accessToken = idenplane.getAccessToken()
}

Biometric Authentication

BiometricAuth is a separate, standalone type — it is not a method on IdenplaneClient. Use it to gate access to already-stored tokens with Face ID / Touch ID.

import Idenplane

let biometrics = BiometricAuth()

if biometrics.isBiometricAvailable {
    try await biometrics.authenticate(reason: "Unlock your account")
    // On success, read the already-stored token:
    let token = idenplane.getAccessToken()
}

User Info

Retrieve the authenticated user profile. Note: the User model does not include a roles or attributes field — only OIDC standard claims.

let user = try await idenplane.getUserInfo()
print(user.name)             // "John Doe"
print(user.email)            // "[email protected]"
print(user.preferredUsername)

Token Refresh

Tokens are refreshed automatically before expiry (AuthConfig.autoRefresh, default true). You can also trigger a manual refresh.

// Manual refresh:
try await idenplane.refreshToken()

// Get fresh access token for API calls
let token = idenplane.getAccessToken()

Logout

Logout clears tokens from the Keychain.

await idenplane.logout()
// Tokens cleared from Keychain

SwiftUI Integration

There is no bundled ObservableObject wrapper yet — drive your own @State off isAuthenticated and the client's async methods.

import SwiftUI
import Idenplane

struct ContentView: View {
    let idenplane: IdenplaneClient
    @State private var user: User?

    var body: some View {
        if idenplane.isAuthenticated {
            VStack {
                Text("Welcome, \(user?.name ?? "")")
                Button("Logout") { Task { await idenplane.logout() } }
            }
        } else {
            Button("Sign In") { Task { try? await idenplane.login() } }
        }
    }
}