---
title: "sdk/ios"
description: "SDK Swift para iOS y macOS que usa ASWebAuthenticationSession, flujo de código de autorización PKCE S256 y almacenamiento de tokens en Keychain."
locale: "es"
---

> Documentation Index
> Fetch the locale documentation index at: https://xid.dev/es/llms.txt
> Use this file to discover all available pages before exploring further.

# sdk/ios

## Estado

El estado del paquete es **Implementado · verificado localmente**. Las pruebas unitarias (19 pasadas) se ejecutan en macOS apuntando a un simulador iOS. La prueba de ida y vuelta real contra un IdP en una instancia XID activa está pendiente de verificación manual. Esta página documenta el comportamiento implementado; no es una declaración de disponibilidad para producción.

## Requisitos

- iOS 16+ / macOS 13+
- Swift 5.9+ y Xcode 15+
- Sin dependencias de terceros: solo usa frameworks del sistema Apple

## Instalación

Añade el paquete mediante Swift Package Manager en Xcode (File -&gt; Add Package Dependencies) o directamente en `Package.swift`:

```swift
// Package.swift
dependencies: [
.package(url: "https://github.com/StringKe/xid", from: "0.1.0"),
],
targets: [
.target(name: "YourApp", dependencies: [.product(name: "Xid", package: "xid")]),
]
```

## Inicio rápido

```swift
import Xid

// 1. Configure in @main App.init
Xid.shared.configure(options: XidConfiguration(
issuer: URL(string: "https://xid.dev")!,
clientId: "your_client_id",
redirectUri: URL(string: "com.example.app://auth/callback")!,
scopes: ["openid", "profile", "email", "offline_access"]
))

// 2. Sign in (opens ASWebAuthenticationSession)
try await Xid.shared.signIn()

// 3. Handle redirect in SceneDelegate
let session = try await Xid.shared.handleRedirect(url: callbackUrl)

// 4. Get current session (auto-refreshes near expiry)
if let session = try await Xid.shared.getSession() {
let token = try await Xid.shared.getAccessToken()
}

// 5. Sign out
try await Xid.shared.signOut(callEndSession: true)
```

## API principal

| Método | Descripción |
| --- | --- |
| `configure(options:)` | Inicializa con issuer, clientId, redirectUri, scopes. Llámalo antes que los demás. |
| `signIn(options:) async throws` | Abre ASWebAuthenticationSession con la URL de autorización PKCE S256. Devuelve cuando finaliza la sesión del navegador. |
| `handleRedirect(url:) async throws -> XidSession` | Valida el estado OAuth, intercambia el código de autorización en el endpoint de tokens, persiste los tokens en Keychain y devuelve una sesión. |
| `getSession() async throws -> XidSession?` | Devuelve la sesión almacenada, desencadenando la rotación del refresh token si está próxima a expirar. |
| `getAccessToken(forceRefresh:) async throws -> String` | Devuelve una cadena de access token válida, renovándola automáticamente si es necesario. |
| `signOut(callEndSession:) async throws` | Limpia los tokens del Keychain. Pasa true para llamar al endpoint end\_session desde el navegador. |
| `setTokenStorage(_:) throws` | Reemplaza el KeychainTokenStorage predeterminado con una implementación personalizada de TokenStorageAdapter. |

## Adaptador de almacenamiento

El almacenamiento predeterminado usa Keychain con `kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly`: los tokens no se sincronizan con iCloud Keychain. Implementa el protocolo `TokenStorageAdapter` para usar una política de Keychain empresarial:

```swift
struct EnterpriseKeychain: TokenStorageAdapter {
func save(key: String, value: String) throws { /* ... */ }
func load(key: String) throws -> String? { /* ... */ }
func delete(key: String) throws { /* ... */ }
}
try Xid.shared.setTokenStorage(EnterpriseKeychain())
```

## Seguridad

- Cliente público: no se almacena ni transmite ningún secreto de cliente.
- Solo PKCE S256. El servidor rechaza el método plain de challenge.
- Estado OAuth aleatorio generado por solicitud; validado en la redirección para prevenir CSRF.
- El code\_verifier PKCE se escribe en el Keychain solo durante el flujo de autorización y se elimina inmediatamente después del intercambio de código.
- ASWebAuthenticationSession iniciada con prefersEphemeralWebBrowserSession = true para evitar compartir cookies del navegador entre apps.

## Limitaciones conocidas

- La verificación ES256/RS256 de ID token basada en JWKS, el cierre de sesión end\_session y refresh single-flight están implementados y probados localmente. Sigue siendo necesaria una prueba de IdP real en dispositivo o simulador iOS para L4.
- El comportamiento de Keychain debe verificarse en una prueba de dispositivo o simulador de Xcode.

Source: https://xid.dev/es/sdks/ios/index.mdx
