> ## Documentation Index
> Fetch the complete documentation index at: https://translations.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Agrega Login a tu aplicación iOS o macOS con el SDK de Auth0.swift

export const HowToSchema = () => <script type="application/ld+json">
    {'{"@context":"https://schema.org","@type":"HowTo"}'}
  </script>;

export const AuthCodeGroup = ({children, dropdown}) => {
  const [processedChildren, setProcessedChildren] = useState(children);
  useEffect(() => {
    let unsubscribe = null;
    function init() {
      unsubscribe = window.autorun(() => {
        const processChildren = node => {
          if (typeof node === "string") {
            let processedNode = node;
            for (const [key, value] of window.rootStore.variableStore.values.entries()) {
              const escapedKey = key.replaceAll(/[.*+?^${}()|[\]\\]/g, (String.raw)`\$&`);
              processedNode = processedNode.replaceAll(new RegExp(escapedKey, "g"), value);
            }
            return processedNode;
          } else if (Array.isArray(node)) {
            return node.map(processChildren);
          } else if (node && node.props && node.props.children) {
            return {
              ...node,
              props: {
                ...node.props,
                children: processChildren(node.props.children)
              }
            };
          }
          return node;
        };
        setProcessedChildren(processChildren(children));
      });
    }
    if (window.rootStore) {
      init();
    } else {
      window.addEventListener("adu:storeReady", init);
    }
    return () => {
      window.removeEventListener("adu:storeReady", init);
      unsubscribe?.();
    };
  }, [children]);
  return <CodeGroup dropdown={dropdown}>{processedChildren}</CodeGroup>;
};

<HowToSchema />

<Accordion title="Usa IA para integrar Auth0" icon="microchip-ai" iconType="solid" defaultOpen>
  Si usas un asistente de programación con IA como Claude Code, Cursor o GitHub Copilot, puedes añadir la autenticación de Auth0 automáticamente en cuestión de minutos con [agent skills](https://agentskills.io/home).

  **Instala:**

  ```bash theme={null}
  npx skills add auth0/agent-skills --skill auth0-quickstart --skill auth0-swift
  ```

  **Después, pídele a tu asistente de IA:**

  ```text theme={null}
  Add Auth0 authentication to my iOS app
  ```

  Tu asistente de IA creará automáticamente tu aplicación de Auth0, obtendrá las credenciales, añadirá la dependencia del SDK Auth0.swift, configurará Auth0.plist, establecerá las URL de callback e implementará los flujos de login y Logout. [Documentación completa de agent skills →](/es/docs/quickstart/agent-skills)
</Accordion>

<div id="get-started">
  ## Primeros pasos
</div>

<Steps>
  <Step title="Crear un proyecto nuevo" stepNumber={1}>
    Cree un nuevo proyecto de iOS o macOS para este inicio rápido.

    **En Xcode:**

    1. **File** → **New** → **Project** (o **⌘+Mayús+N**)
    2. Seleccione una de estas opciones:
       * Pestaña **iOS** → plantilla **App**
       * Pestaña **macOS** → plantilla **App**
    3. Configure el proyecto:
       * **Product Name**: `Auth0-Sample`
       * **Interface**: SwiftUI
       * **Language**: Swift
       * **Use Core Data**: Desactivado
       * **Include Tests**: Activado (recomendado)
    4. Elija una ubicación y haga clic en **Create**

    <Tip>
      Esto crea una aplicación estándar con soporte para SwiftUI y Swift Package Manager, ideal para integrar Auth0.
    </Tip>
  </Step>

  <Step title="Agrega el SDK de Auth0" stepNumber={2}>
    Agrega el SDK de Auth0 a tu proyecto con el gestor de paquetes que prefieras.

    <Tabs>
      <Tab title="Swift Package Manager">
        **En Xcode:**

        1. **File** → **Add Package Dependencies...** (o **⌘+Shift+K**)
        2. Ingresa la URL del SDK de Auth0:
           ```
           https://github.com/auth0/Auth0.swift
           ```
        3. **Add Package** → Selecciona el target de tu app → **Add Package**
      </Tab>

      <Tab title="CocoaPods">
        1. Crea un `Podfile` en el directorio de tu proyecto:
           ```ruby Podfile theme={null}
           platform :ios, '14.0' # O platform :osx, '11.0' para macOS
           use_frameworks!

           target 'YourApp' do
             pod 'Auth0', '~> 2.0'
           end
           ```
        2. Instala las dependencias:
           ```bash theme={null}
           pod install
           ```
        3. Abre el archivo `.xcworkspace` generado (no el `.xcodeproj`)
      </Tab>

      <Tab title="Carthage">
        1. Crea un `Cartfile` en el directorio de tu proyecto:
           ```text Cartfile theme={null}
           github "auth0/Auth0.swift" ~> 2.0
           ```
        2. Ejecuta Carthage:
           ```bash theme={null}
           carthage update --platform iOS --use-xcframeworks
           ```
           Para macOS, usa `--platform macOS`
        3. Arrastra el `Auth0.xcframework` generado desde `Carthage/Build` a tu proyecto de Xcode
        4. En la configuración **General** de tu target, agrega `Auth0.xcframework` a **Frameworks, Libraries, and Embedded Content**
      </Tab>
    </Tabs>
  </Step>

  <Step title="Configurar Auth0" stepNumber={3}>
    Cree una nueva aplicación en Auth0 y configure las URL de callback.

    1. Vaya a [Auth0 Dashboard](https://manage.auth0.com/dashboard/)
    2. **Applications** > **Create Application** > Asígnele un nombre, seleccione **Native** > **Create**
    3. En la pestaña **Settings**, anote su **ID de cliente** y **dominio**
    4. Agregue las siguientes URL a **Allowed Callback URLs**:

    <Tabs>
      <Tab title="iOS">
        ```
        https://{yourDomain}/ios/YOUR_BUNDLE_IDENTIFIER/callback,
        YOUR_BUNDLE_IDENTIFIER://{yourDomain}/ios/YOUR_BUNDLE_IDENTIFIER/callback
        ```
      </Tab>

      <Tab title="macOS">
        ```
        https://{yourDomain}/macos/YOUR_BUNDLE_IDENTIFIER/callback,
        YOUR_BUNDLE_IDENTIFIER://{yourDomain}/macos/YOUR_BUNDLE_IDENTIFIER/callback
        ```
      </Tab>
    </Tabs>

    5. Agregue las siguientes URL a **Allowed Logout URLs**:

    <Tabs>
      <Tab title="iOS">
        ```
        https://{yourDomain}/ios/YOUR_BUNDLE_IDENTIFIER/callback,
        YOUR_BUNDLE_IDENTIFIER://{yourDomain}/ios/YOUR_BUNDLE_IDENTIFIER/callback
        ```
      </Tab>

      <Tab title="macOS">
        ```
        https://{yourDomain}/macos/YOUR_BUNDLE_IDENTIFIER/callback,
        YOUR_BUNDLE_IDENTIFIER://{yourDomain}/macos/YOUR_BUNDLE_IDENTIFIER/callback
        ```
      </Tab>
    </Tabs>

    6. Haga clic en **Save Changes**
  </Step>

  <Step title="Configurar las credenciales de la aplicación" stepNumber={4}>
    Crea `Auth0.plist` en el directorio del proyecto:

    ```xml Auth0.plist theme={null}
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    <plist version="1.0">
    <dict>
        <key>ClientId</key>
        <string>YOUR_AUTH0_CLIENT_ID</string>
        <key>Domain</key>
        <string>{yourDomain}</string>
    </dict>
    </plist>
    ```

    Arrastra `Auth0.plist` a Xcode y asegúrate de que la opción "Add to target" esté seleccionada.
  </Step>

  <Step title="Crear el servicio de autenticación" stepNumber={5}>
    Cree `AuthenticationService.swift` para gestionar el inicio de sesión, el cierre de sesión y el almacenamiento de tokens.

    <Info>
      **Use `CredentialsManager` para almacenar tokens.** La clase `CredentialsManager` almacena las credenciales de forma segura en el Keychain y actualiza automáticamente los tokens de acceso vencidos. Úsela siempre; no almacene tokens en memoria, `UserDefaults` ni `localStorage`.
    </Info>

    1. Haga clic derecho en su proyecto → **New File...** → **Swift File**
    2. Asígnele el nombre `AuthenticationService`
    3. Reemplace el contenido con:

    ```swift AuthenticationService.swift expandable lines theme={null}
    import Foundation
    import Auth0
    import Combine

    @MainActor
    class AuthenticationService: ObservableObject {
        @Published var isAuthenticated = false
        @Published var user: User?
        @Published var isLoading = false
        @Published var errorMessage: String?
        
        private let credentialsManager = CredentialsManager(authentication: Auth0.authentication())
        
        init() {
            Task {
                await checkAuthenticationStatus()
            }
        }
        
        private func checkAuthenticationStatus() async {
            isLoading = true
            defer { isLoading = false }
            
            guard let credentials = try? await credentialsManager.credentials() else {
                isAuthenticated = false
                return
            }
            
            isAuthenticated = true
            // Obtener información del usuario desde el token de ID
            user = credentials.user
        }
        
        func login() async {
            isLoading = true
            errorMessage = nil
            defer { isLoading = false }
            
            do {
                let credentials = try await Auth0
                    .webAuth()
                    .scope("openid profile email offline_access")
                    .start()
                
                _ = credentialsManager.store(credentials: credentials)
                isAuthenticated = true
                // Get user info from the ID token
                user = credentials.user
            } catch {
                errorMessage = "Login failed: \(error.localizedDescription)"
            }
        }
        
        func logout() async {
            isLoading = true
            defer { isLoading = false }
            
            do {
                try await Auth0
                  .webAuth()
                  .clearSession()
                _ = credentialsManager.clear()
                isAuthenticated = false
                user = nil
            } catch {
                errorMessage = "Logout failed: \(error.localizedDescription)"
            }
        }
    }
    ```
  </Step>

  <Step title="Configurar el flujo de autenticación (opcional)" stepNumber={6}>
    Para mejorar la experiencia del usuario, puede minimizar las alertas del sistema de las siguientes maneras:

    1. Use Universal Links: esto elimina el mensaje '¿Abrir en "AppName"?' que aparece durante la redirección. Nota: la alerta de permiso de ASWebAuthenticationSession seguirá apareciendo.
    2. Use sesiones efímeras: esto elimina todas las alertas de permiso. Nota: esto desactiva el inicio de sesión único (SSO) y las cookies compartidas.

    <Tip>
      **Omita este paso** para usar el comportamiento predeterminado con una alerta de permiso. Puede configurarlo más adelante.
    </Tip>

    <Tabs>
      <Tab title="Universal Links">
        1. Auth0 Dashboard → **Applications** → Su aplicación → **Settings** → **Advanced Settings** → **Device Settings**
        2. Agregue **Apple Team ID** y **bundle identifier** → **Save**
        3. Xcode: Target → **Signing & Capabilities** → **+ Capability** → **Associated Domains**
        4. Agregue: `webcredentials:{yourDomain}`

        <Warning>Requiere: una cuenta de pago de Apple Developer, iOS 17.4+/macOS 14.4+</Warning>

        <Tip>
          Ideal para aplicaciones en producción.
        </Tip>
      </Tab>

      <Tab title="Sesión efímera">
        Agregue `.useEphemeralSession()` a la llamada de Login en `AuthenticationService.swift`:

        ```swift theme={null}
        // En la función login()
        let credentials = try await Auth0
            .webAuth()
            .scope("openid profile email offline_access")
            .useEphemeralSession()
            .start()
        ```

        <Info>
          Al usar sesiones efímeras, no necesita llamar a `clearSession()` al cerrar sesión. Solo borre las credenciales de su aplicación; no hay ninguna cookie compartida que eliminar.
        </Info>

        <Tip>
          Configuración rápida, sin alertas, pero los usuarios deben iniciar sesión cada vez (sin SSO).
        </Tip>
      </Tab>
    </Tabs>
  </Step>

  <Step title="Ejecuta la aplicación" stepNumber={8}>
    Presiona **⌘+R** en Xcode.

    1. Toca "Iniciar sesión" → Alerta de permisos (si usas la configuración predeterminada) → Toca "Continuar"
    2. Completa el inicio de sesión en el navegador
    3. ¡Verás tu perfil!
  </Step>
</Steps>

<Check>
  **Punto de control**

  ¡Ya tienes un inicio de sesión con Auth0 totalmente funcional en tu aplicación para iOS o macOS!
</Check>

***

<div id="troubleshooting-advanced">
  ## Solución de problemas y opciones avanzadas
</div>

<Accordion title="Problemas comunes y soluciones">
  ### Errores de compilación: no se encuentra el módulo 'Auth0'

  **Soluciones**:

  1. **Swift Package Manager**: Revisa **Package Dependencies** → Verifica que `Auth0.swift` figure en la lista
  2. **CocoaPods**: Asegúrate de abrir el archivo `.xcworkspace`, no `.xcodeproj`
  3. **Carthage**: Verifica que `Auth0.xcframework` esté agregado en **Frameworks, Libraries, and Embedded Content**
  4. Limpia y vuelve a compilar: **⌘+Shift+K** y luego **⌘+R**
  5. Reinicia Xcode si es necesario

  ### La app se cierra: 'Auth0.plist not found'

  **Solución**:

  1. Verifica que `Auth0.plist` esté en el navegador del proyecto de Xcode
  2. Selecciona el archivo → Inspector → Asegúrate de que el target de tu app esté marcado
  3. Confirma que tenga las claves `ClientId` y `Domain` con tus valores

  ### El navegador se abre, pero nunca regresa a la app

  **Solución**:

  1. Comprueba que las URL de callback en Auth0 Dashboard coincidan exactamente con tu identificador de paquete y la plataforma
  2. Para iOS: las URL deben contener `/ios/`; para macOS: `/macos/`
  3. Verifica que el identificador de paquete en Xcode coincida con la configuración de Auth0
  4. Asegúrate de que no haya errores tipográficos en las URL (los más comunes: dos puntos faltantes o formato de dominio incorrecto)
  5. **Si usas un dominio personalizado**: Verifica que estés usando tu dominio personalizado, no el dominio de Auth0

  ### La alerta de permisos aparece cada vez

  Este es el comportamiento de seguridad estándar de iOS/macOS al usar esquemas de URL personalizados. Consulta el **Paso 6** para eliminar esta alerta usando Universal Links o Ephemeral Sessions.
</Accordion>

<Accordion title="Configuración de dominio personalizado">
  Si usas un [dominio personalizado](/es/docs/customize/custom-domains), usa ese valor en lugar de tu dominio de Auth0 en todas partes.

  **Ejemplo:** Usa `login.example.com` en lugar de `tenant.auth0.com`

  Esto es **necesario** para que ciertas funciones funcionen correctamente:

  * Actualiza `Auth0.plist` con tu dominio personalizado
  * Usa el dominio personalizado en las URL de callback/logout
  * Para Universal Links, usa: `webcredentials:login.example.com`
</Accordion>

<Accordion title="Implementación en producción">
  ### Preparación para App Store

  * Configura Universal Links para eliminar la alerta de permisos
  * Haz pruebas en varias versiones de la plataforma y tamaños de dispositivo
  * Implementa un manejo de errores adecuado para fallos de red
  * Agrega descripciones de uso de privacidad si usas Keychain con biometría
  * Sigue las directrices de revisión de App Store para los flujos de autenticación

  ### Prácticas recomendadas de seguridad

  * Nunca registres datos de autenticación sensibles en producción
  * Implementa el cumplimiento de App Transport Security (ATS)
  * Usa HTTPS para todas las solicitudes de red
  * **NO** fijes certificados de la API de Auth0: [Auth0 no recomienda esta práctica](/es/docs/troubleshoot/product-lifecycle/past-migrations#avoid-pinning-or-fingerprinting-tls-certificates-for-auth0-endpoints)

  ### Optimización del rendimiento

  * Todas las operaciones asíncronas usan correctamente `@MainActor` para actualizar la UI
  * Las propiedades `@Published` usan un manejo de memoria adecuado
  * Las credenciales se almacenan en caché de forma segura en el Keychain para acceso sin conexión
  * El perfil de usuario se obtiene del token de ID (sin ninguna solicitud de red adicional)
</Accordion>

<Accordion title="Integración avanzada">
  ### Seguridad reforzada de Keychain con biometría

  Exige Face ID o Touch ID para acceder a las credenciales almacenadas:

  ```swift theme={null}
  private let credentialsManager: CredentialsManager = {
      let manager = CredentialsManager(authentication: Auth0.authentication())
      manager.enableBiometrics(
          withTitle: "Unlock with Face ID", 
          cancelTitle: "Cancel", 
          fallbackTitle: "Use Passcode"
      )
      return manager
  }()
  ```

  Cuando está habilitado, los usuarios deben autenticarse con biometría antes de que el SDK pueda recuperar las credenciales almacenadas.

  ### Renovación automática de tokens

  `CredentialsManager` renueva automáticamente los tokens de acceso caducados:

  ```swift theme={null}
  // Obtener credenciales: se renuevan automáticamente si han caducado
  func getAccessToken() async throws -> String {
      let credentials = try await credentialsManager.credentials()
      return credentials.accessToken
  }
  ```

  Usa este patrón al hacer llamadas a la API que requieran un token de acceso.

  ### Credenciales compartidas entre extensiones de la app

  Para widgets, extensiones de la app o tareas en segundo plano que necesiten tokens de acceso:

  ```swift theme={null}
  // Crear un administrador de credenciales compartidas con un grupo de apps
  let credentialsManager = CredentialsManager(
      authentication: Auth0.authentication(),
      storeKey: "credentials",
      storage: .shared(withIdentifier: "group.com.example.myapp")
  )
  ```

  **Requisitos:**

  1. Habilita la capacidad **App Groups** en Xcode para todos los targets
  2. Usa el mismo identificador de grupo de apps en todos los targets
  3. Configura el `CredentialsManager` compartido en cada target

  ### Comparación de opciones del flujo de autenticación

  | Característica                        | Universal Links                     | Sesión efímera | Por defecto (alerta)      |
  | ------------------------------------- | ----------------------------------- | -------------- | ------------------------- |
  | Alerta de permisos                    | Reducida (sin aviso de redirección) | Ninguna        | Muestra todas las alertas |
  | Compatibilidad con SSO                | Sí                                  | No             | Sí                        |
  | Cuenta de desarrollador de Apple      | Obligatoria                         | No obligatoria | No obligatoria            |
  | Experiencia de usuario                | Mejor                               | Buena          | Aceptable                 |
  | Complejidad de configuración          | Media                               | Fácil          | Fácil                     |
  | Compatibilidad con navegación privada | Sí                                  | Sí             | No                        |

  **Recomendaciones:**

  * **Apps de producción con SSO**: Universal Links (mejor UX, compatibilidad con SSO, requiere una cuenta de desarrollador de Apple)
  * **Apps de producción sin SSO**: Sesiones efímeras (sin alertas, configuración más sencilla)
  * **Pruebas/desarrollo**: Sesiones efímeras (configuración rápida, UX más limpia)
  * **Inicio rápido/prototipado**: Opción predeterminada con alertas (sin configuración, puedes migrar más adelante)
</Accordion>
