Cuando el código funciona en el simulador, pero falla en el dispositivo real: analizando UI_USER_INTERFACE_IDIOM() en Swift
\n\n¿Alguna vez has escrito una aplicación que se ve perfecta en el simulador de iPhone 14 Pro, pero en un iPad Mini se convierte en un desastre? ¿O al revés? ¿Tu elegante interfaz de iPad se desconfigura en un iPod touch antiguo? Un dolor familiar, ¿verdad?
\n\nLos desarrolladores de iOS a menudo se enfrentan a la necesidad de saber en qué dispositivo se está ejecutando la aplicación. Parecería algo sencillo, ¿no? Pero el diablo, como siempre, está en los detalles. La legendaria pregunta en Stack Overflow sobre UI_USER_INTERFACE_IDIOM() ha acumulado miles de visitas, lo que significa que incluso los programadores experimentados a veces se confunden con los matices.
En este artículo, desglosaremos todo lo que necesitas saber sobre la determinación del dispositivo en Swift. Sin rodeos: solo práctica, ejemplos reales y respuestas a las preguntas más frecuentes.
\n\n¿Qué es UI_USER_INTERFACE_IDIOM() y por qué se habla de ello?
\n\nEs una vieja y querida función de la era de Objective-C. Devuelve un valor de tipo UIUserInterfaceIdiom que indica con qué tipo de dispositivo estamos tratando: iPhone, iPad, TV o CarPlay.
Así se veía en el Objective-C clásico:
\n\nif (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {\n // Esto es un iPad\n} else {\n // Esto es un iPhone o iPod touch\n}\n\nPero Swift es un lenguaje más estricto y seguro. El uso directo de esta función C no siempre es conveniente. Ha sido reemplazado por un enfoque más moderno a través de UIDevice.current.
Cómo determinar correctamente el dispositivo en Swift: dos formas funcionales
\n\nForma n.º 1: la clásica a través de UIDevice (recomendada):
import UIKit\n\nlet deviceIdiom = UIDevice.current.userInterfaceIdiom\n\nswitch deviceIdiom {\ncase .phone:\n print("Esto es un iPhone o iPod touch")\ncase .pad:\n print("Esto es un iPad")\ncase .tv:\n print("Esto es un Apple TV")\ncase .carPlay:\n print("Esto es CarPlay")\ncase .mac:\n print("Esto es Mac Catalyst o Mac")\n@unknown default:\n print("Dispositivo desconocido (posiblemente futuro)")\n}\n\nImportante: El caso .mac apareció en iOS 14+. Si tu aplicación soporta versiones anteriores, usa @unknown default para manejar tipos futuros.
Forma n.º 2: compatibilidad con código Objective-C (si es necesario):
\n\nif UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiom.phone {\n print("Trabajando en un teléfono")\n}\n\nAmbas opciones son correctas, pero la primera es más idiomática para Swift.
\n\nPreguntas frecuentes y trampas comunes
\n\n1. ¿Por qué en un iPad mini se detecta como iPhone?
\n\nEsta es la pregunta más popular. Ejecutas la aplicación en un iPad mini, pero userInterfaceIdiom insiste en devolver .phone. ¿Cuál es el problema?
La respuesta es simple y poco obvia: el modo de escala (Scale Mode). Si en la configuración de tu aplicación (Target → General → Deployment Info) está seleccionado el modo "iPhone", incluso en un iPad físico el sistema emulará un iPhone.
\n\nSolución: verifica la configuración del proyecto.
\n- \n
- Ve a Target de tu aplicación \n
- General → Deployment Info \n
- Devices: selecciona "Universal" (si la aplicación debe funcionar en todos los dispositivos) \n
Si seleccionaste "iPhone Only", la aplicación se ejecutará en el iPad en modo de compatibilidad (como en un iPhone grande) y el idiom será .phone.
2. ¿Cómo diferenciar un iPhone de un iPod touch?
\n\nUI_USER_INTERFACE_IDIOM() no distingue entre iPhone y iPod touch: ambos devuelven .phone. Para una determinación precisa del modelo, debes usar UIDevice.current.model o modelName a través de sysctl.
Ejemplo de extensión para obtener el nombre exacto del modelo:
\n\nimport UIKit\n\nextension UIDevice {\