Abrova
☰ Docs menu · iOS SDK

iOS SDK

Abrova Auth for iOS and macOS (Abrova Auth, Swift). Native Sign in with Apple in one call, plus anonymous, Google, e-mail and password, magic link and Telegram sign-in. Session in the Keychain; token provider for every Abrova SDK.

iOS 0.1.1iOS 13+macOS 12+Swift 5.7+Last updated: 27 Oct 2026
Client-Safe

Uses the public API key only. Safe to ship in an app

Apple in One Call

signInWithAppleNative() runs the sheet, nonce included

Keychain

Refresh token on this device only; access token in memory

Token Providers

tokenProvider and strictTokenProvider for the other Abrova SDKs

Swift Concurrency

async/await API

Upgrade Guests

linkApple, linkGoogle, linkPassword keep the user id

Abrova Auth iOS SDK v0.1.1.

This page describes AbrovaAuth 0.1.1.

Requirements.

iOS 13 or later, or macOS 12 or later. Swift 5.7 or later.

Using an AI assistant? Give it this page with Copy page for AI, or all the docs as plain text from /docs/llms.txt. See AI assistants.

Installation#

Install with Swift Package Manager. In Xcode: File → Add Packages → enter the repository URL:

text
https://github.com/Abrova-co/abrova-auth-ios-sdk

Or add it to your Package.swift:

swift
dependencies: [
    .package(url: "https://github.com/Abrova-co/abrova-auth-ios-sdk.git", from: "0.1.1")
]

Then add AbrovaAuth to your target's dependencies.

In Abrova Console, turn on Abrova Auth for your project (Settings › Products) and the sign-in methods you want (Abrova Auth › Sign-in methods).

Initialization#

Configure the SDK once at app start, before any other call, with your public API key (ab_live_...). A session saved by an earlier launch is restored.

swift
import AbrovaAuth

@main
struct MyApp: App {
    init() {
        AbrovaAuth.shared.configure(apiKey: "ab_live_your_api_key")
    }
    var body: some Scene { WindowGroup { ContentView() } }
}
ParameterDefaultDescription
apiKey-Your public API key (ab_live_...). Never the server secret.
keychainAccessGroupnilShare the session with your app extensions.

The Keychain survives an uninstall, so the SDK forgets a session left by a previous install: a fresh install starts signed out.

Sign in#

swift
let auth = AbrovaAuth.shared

let methods = try await auth.getMethods()
if auth.currentUserId == nil && methods.isEnabled("anonymous") {
    try await auth.signInAnonymously()
}
print(auth.currentUserId!) // ru_...

Show only the buttons for methods where methods.isEnabled(...) is true: anonymous, apple, google, password, magicLink, telegram.

Use the user with other Abrova SDKs#

Coming soon. Abrova Sync, Chat, Push, Storage and A/B Testing are coming soon. The calls below show how they will take the Auth user; today, attach the user to Abrova Trace with AbrovaTrace.shared.setUserId(auth.currentUserId).
swift
// Abrova Sync
sync.userTokens.provider = auth.tokenProvider

// Abrova Push
AbrovaPushConfig(apiKey: key, tokenProvider: auth.tokenProvider)

// Abrova Chat: create the client after sign-in
AbrovaChatConfig(apiKey: key, userId: auth.currentUserId!, tokenProvider: auth.strictTokenProvider)

tokenProvider returns nil when nobody is signed in; strictTokenProvider throws. Both return a token that is renewed before it expires. After a sign-in or sign-out, call the other SDK's refresh method (for example sync.refreshUserToken()). Abrova A/B Testing and more: Use with other Abrova products.

Sign-in methods#

Each method has its own page with the Console setup: Anonymous, Apple, Google, E-mail & password, Magic link, Telegram.

Sign in with Apple

Add the Sign in with Apple capability to your app and your bundle ID under Abrova Auth › Sign-in methods › Apple. Then:

swift
try await AbrovaAuth.shared.signInWithAppleNative()

The SDK runs Apple's sheet with a nonce and passes the authorization code (so account deletion can revoke the Apple sign-in) and the name Apple shares on the first sign-in. It throws .canceled when the user closes the sheet. If you run the Apple request yourself:

swift
let rawNonce = AbrovaNonce.generate()
request.nonce = AbrovaNonce.sha256(rawNonce)   // to Apple
// ... when Apple answers:
try await auth.signInWithApple(idToken: idToken, rawNonce: rawNonce,
                               authorizationCode: code, fullName: name)

Sign in with Google

Request the Google ID token with AbrovaNonce.sha256(rawNonce) as its nonce, then:

swift
try await auth.signInWithGoogle(idToken: idToken, rawNonce: rawNonce)

Google sign-in needs a connection to Google, which some users in Iran don’t have. Anonymous, e-mail and password, magic link and Telegram code work without Google, so offer at least one of them as well. See Sign in with Google.

E-mail and password

swift
let result = try await auth.signUp(email: email, password: password,
                                   redirectURL: "https://example.com/auth/verify")
// result.signedIn is false when the project requires a verified e-mail first.

try await auth.signIn(email: email, password: password)

try await auth.sendPasswordReset(email: email, redirectURL: "https://example.com/auth/reset")
try await auth.resetPassword(token: token, newPassword: newPassword) // ends every session
try await auth.verifyEmail(token: token)
try await auth.sendEmailVerification(redirectURL: "https://example.com/auth/verify")

AbrovaAuth.token(in: url) reads the token from the link the app was opened with.

Magic link

swift
try await auth.sendMagicLink(email: email, redirectURL: "myapp://auth/magic")
// When the app is opened with the link:
try await auth.signInWithMagicLink(url: openedURL)

Telegram

swift
let code = try await auth.requestTelegramCode(phone: "+989121234567")
if !code.sent, let url = code.botURL { await UIApplication.shared.open(url) }
try await auth.verifyTelegramCode(phone: "+989121234567", code: "123456")

Upgrade an anonymous user#

Linking keeps the user id, so everything they created stays theirs:

swift
do {
    try await auth.signInWithAppleNative(link: true)
    // or linkGoogle(idToken:rawNonce:), linkApple(...), linkPassword(email:password:)
} catch let error as AbrovaAuthError where error.code == .providerAlreadyLinked {
    // This Apple ID already belongs to another user.
}

The current user#

swift
auth.currentUserId                  // nil when signed out
auth.isSignedIn
let user = try await auth.me()      // AbrovaUser: id, isAnonymous, emailVerified, createdAt, providers
auth.currentUser                    // the profile last loaded by me()

let listener = auth.addAuthStateListener { userId in
    // On the main queue: now, then on every sign-in, sign-out and session end
}
listener.remove()

let token = try await auth.getAccessToken() // if you call your own API with it

Sign out and delete the account#

swift
await auth.signOut()                // this device; never fails
try await auth.signOutEverywhere()  // every device
try await auth.deleteAccount()      // required by the App Store for apps with sign-in

See Security & data for what deletion removes.

Handle errors#

Every error is an AbrovaAuthError. Branch on code:

swift
do {
    try await auth.signIn(email: email, password: password)
} catch let error as AbrovaAuthError {
    switch error.code {
    case .invalidCredentials: showError("Wrong e-mail or password")
    case .rateLimited: showError("Try again in \(error.retryAfterSec ?? 60) s")
    case .network: showError("No connection")
    default: showError("Sign-in failed")
    }
}

message is an English hint for developers. Besides the server's codes the SDK uses .network, .canceled (the user closed the Apple sheet), .notSignedIn and .sdkNotConfigured (call configure first). A network error never signs the user out. All codes: Error codes.

Troubleshooting#

SDK_NOT_CONFIGURED

Call AbrovaAuth.shared.configure(apiKey:) at app start, before any other call.

Sign in with Apple fails with INVALID_ID_TOKEN

Add your app's bundle ID under Abrova Auth › Sign-in methods › Apple, and the Sign in with Apple capability to the target.

METHOD_DISABLED or PRODUCT_DISABLED

Turn on Abrova Auth under Settings › Products and the method under Abrova Auth › Sign-in methods.

Was this page helpful?
Report a problem