# Sign in with Apple

Sign in with Apple is the **native** social login on iOS — no browser round-trip. The system presents Apple's sheet, returns an Apple ID credential containing an `identityToken`, and you hand that token to Openfort with `loginWithIdToken`. This is the recommended social path on Apple platforms and is required by App Store review if you offer third-party social login.

:::note
Other social providers (Google, Discord, and so on) use the browser-based OAuth flow instead — see [Login with OAuth](/docs/products/embedded-wallet/swift/auth/oauth).
:::

::::steps

## Add your native application

Add your iOS application on the **Users** page of the [Openfort Dashboard](https://dashboard.openfort.io). You'll need your app's **App ID Prefix** (Team ID) and **Bundle ID**. The bundle ID must also be [whitelisted as a native app](/docs/configuration/native-apps) or the embedded wallet won't connect.

## Enable Apple as a social connection

1. In the dashboard, open the **Auth Providers** page.
2. Select **Add connection → For all users**.
3. In the provider dropdown, choose **Apple**.
4. Make sure **Enable for sign-up and sign-in** is on.

:::note
Apple's [Hide My Email](https://support.apple.com/en-us/HT210425#hideemail) lets users sign in without revealing their real address — your app instead receives an app-specific relay address. To deliver email to relay addresses, configure the email relay in the Apple Developer portal.
:::

## Add the Sign in with Apple capability

In Xcode, [add the **Sign in with Apple** capability](https://developer.apple.com/documentation/xcode/configuring-sign-in-with-apple#Add-the-Sign-in-with-Apple-capability-to-your-app) to your target (Signing & Capabilities → + Capability).

## Obtain an Apple ID credential

You need an [`ASAuthorizationAppleIDCredential`](https://developer.apple.com/documentation/authenticationservices/asauthorizationappleidcredential). The simplest path is Apple's built-in `SignInWithAppleButton`. Other options: Openfort's `AppleAuthManager`, or building the request manually per [Apple's docs](https://developer.apple.com/documentation/authenticationservices/asauthorizationappleidcredential).

:::warning
You **must** set the `nonce` on the `ASAuthorizationAppleIDRequest` when requesting the credential — Openfort validates it. Requests without a nonce will fail to authenticate.
:::

## Build your sign-in flow

Read the `identityToken` from the credential, decode it to a UTF-8 string, and call `loginWithIdToken` with provider `.apple`:

```swift
import SwiftUI
import AuthenticationServices
import OpenfortSwift

struct AppleSignInView: View {
    @State private var status = ""
    @State private var currentNonce = ""

    var body: some View {
        VStack {
            SignInWithAppleButton(.signIn) { request in
                request.requestedScopes = [.fullName, .email]
                currentNonce = randomNonce()
                request.nonce = sha256(currentNonce) // see Apple's nonce guidance
            } onCompletion: { result in
                Task { await handle(result) }
            }
            .frame(height: 48)

            Text(status).font(.footnote)
        }
    }

    @MainActor
    func handle(_ result: Result<ASAuthorization, Error>) async {
        guard
            case let .success(auth) = result,
            let credential = auth.credential as? ASAuthorizationAppleIDCredential,
            let tokenData = credential.identityToken,
            let idToken = String(data: tokenData, encoding: .utf8)
        else {
            status = "Couldn't read Apple ID credential."
            return
        }

        do {
            let response = try await OFSDK.shared.loginWithIdToken(
                params: OFLoginWithIdTokenParams(
                    provider: OFAuthProvider.apple.rawValue,
                    token: idToken
                )
            )
            status = "Signed in as \(response?.user?.id ?? "user")."
        } catch {
            status = "Openfort login failed: \(error.localizedDescription)"
        }
    }
}
```

::::

## Parameters

```swift
public struct OFLoginWithIdTokenParams: OFCodableSendable {
    public let provider: String // OFAuthProvider.apple.rawValue
    public let token: String    // the Apple identityToken as a UTF-8 string
}
```

## Available auth providers

`loginWithIdToken` accepts any provider you've configured. Use the matching `OFAuthProvider` case:

```swift
public enum OFAuthProvider: String {
    case email, wallet, apple, google, twitter, discord, facebook,
         epic_games, accelbyte, firebase, lootlocker, playfab,
         supabase, custom, oidc
}
```

## Returns

Returns [`OFAuthResponse`](/docs/products/embedded-wallet/authentication#response-types).

## Next steps

* [Configure the embedded wallet](/docs/products/embedded-wallet/swift/wallet/recovery) after login
* Integrating your own identity provider instead? See [third-party authentication](/docs/products/embedded-wallet/swift/auth/third-party)
