iOS communities SDK


Prerequisites

Before integrating the SDK, ensure your development environment meets the following requirements:

  • iOS minimum deployment target: 15.0
  • Xcode: 16 or later
  • Swift: 5.9+

Adding the SDK to your project

1

In Xcode, go to File > Add Package Dependencies and enter the repository URL:

URL
https://github.com/IDme/ios-auth-sample-code.git

Select version 1.0.0 or later and add IDmeAuthSDK to your target.

2

Alternatively, add the dependency directly to your Package.swift:

Example
dependencies: [
.package(url: "https://github.com/IDme/ios-auth-sample-code.git", from: "1.0.0")
],
targets: [
.target(
name: "YourApp",
dependencies: ["IDmeAuthSDK"]
)
]

Required app integration steps

1

Register a custom URL scheme in your app’s Info.plist so iOS can route the OAuth callback back to your app after verification:

Example
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>yourapp</string>
</array>
</dict>
</array>

The scheme must match the scheme portion of your redirectURI. For example, if your redirect URI is yourapp://idme/callback, register yourapp as the scheme.

Initialization

Create an IDmeConfiguration with your client credentials and desired settings, then instantiate IDmeAuth:

Example
import IDmeAuthSDK
let config = IDmeConfiguration(
clientId: "YOUR_CLIENT_ID",
redirectURI: "yourapp://idme/callback",
scopes: [.military],
environment: .production
)
let idme = IDmeAuth(configuration: config)

Configuration reference

ParameterTypeDefaultDescription
clientIdStringOAuth Client ID from ID.me
redirectURIStringRegistered redirect URI — must match your URL scheme
scopes[IDmeScope]Community scopes to request
environmentIDmeEnvironment.production.production or .sandbox
verificationTypeIDmeVerificationType.single.single or .groups
clientSecretString?nilOptional. Required by the policies endpoint if used.

Available scopes

ScopeCommunity
.militaryActive duty, veterans, and military families
.firstResponderFirst responders
.nurseNurses
.teacherTeachers and educators
.studentStudents

Common usage patterns

Starting the verification flow

Call login(from:) from an async context, passing a UIWindow as the presentation anchor. The SDK opens a system browser sheet (ASWebAuthenticationSession) for the user to verify their community membership. The sheet dismisses automatically when verification completes.

Example
do {
let credentials = try await idme.login(from: window)
// Verification complete — credentials contains access and refresh tokens
print(credentials.accessToken)
print(credentials.expiresAt)
} catch let error as IDmeAuthError where error == .userCancelled {
// User dismissed the verification sheet
} catch {
print("Verification failed: \(error.localizedDescription)")
}

Retrieving community attributes

Example
let response = try await idme.attributes()
for attr in response.attributes {
print("\(attr.handle): \(attr.value ?? "")")
}
for status in response.status {
print("\(status.group): verified=\(status.verified)")
}

Token management

The SDK stores credentials in the Keychain and handles token refresh automatically:

Example
// Get valid credentials, refreshing if they expire within 60 seconds
let creds = try await idme.credentials(minTTL: 60)
// Check expiry
if creds.isExpired {
// Token has expired
}
if creds.expiresWithin(seconds: 300) {
// Token expires within 5 minutes
}

Fetching available policies

Discover which verification policies your organization supports:

Example
let policies = try await idme.policies()
for policy in policies.filter({ $0.active }) {
print("\(policy.name) — scope: \(policy.handle)")
}

Logout

Example
idme.logout()

Clears all stored credentials and tokens from the Keychain.

Error handling

All errors are thrown as IDmeAuthError, a Swift enum conforming to LocalizedError:

Example
do {
let credentials = try await idme.login(from: window)
} catch let error as IDmeAuthError {
switch error {
case .userCancelled:
// User dismissed the system browser sheet
break
case .tokenExchangeFailed(let statusCode, let message):
print("Token exchange failed (\(statusCode)): \(message)")
case .stateMismatch:
// OAuth state parameter mismatch — possible CSRF attempt
break
case .notAuthenticated:
print("No stored credentials available")
case .refreshTokenExpired:
print("Session expired — user must log in again")
default:
print(error.localizedDescription)
}
}