Qué puede crear NEVPNManager en iOS (y qué no)
La API de VPN de iOS construye una configuración propia de la aplicación a partir de tres clases de protocolo. L2TP, PPTP y los perfiles firmados no forman parte de esa superficie.
Cree una pantalla de VPN dentro de una app de iOS y la primera sorpresa es que la lista de protocolos de la app Ajustes no es la lista de la API. El marco Network Extension permite a su app crear una configuración de VPN personal, propiedad de esa app, y solo acepta unos pocos objetos de protocolo. Todo lo demás que la gente espera, desde L2TP hasta un perfil descargado, queda fuera de esa superficie o es privado de Apple. Los fallos que siguen normalmente no son errores: es la API rechazando un trabajo que nunca le dieron.
El mito: la API no es un editor de Ajustes
La creencia es que, como iOS puede configurar perfiles IKEv1, IKEv2, L2TP e IPsec, una app puede crear cualquiera de ellos por programa. No puede. El marco expone exactamente una ranura de configuración a la app que lo llama, y esa ranura acepta un conjunto pequeño de clases de protocolo públicas. Todo lo demás que la gente espera, desde L2TP hasta un perfil descargado, queda fuera de esa superficie o es privado de Apple.
Los fallos que siguen normalmente no son errores. Son la API rechazando un trabajo que nunca le dieron, y la solución es diseñar la pantalla en torno a lo que posee la API.
Tres objetos de protocolo y los que no existen
Sus opciones son IKEv1 mediante NEVPNProtocolIPSec, IKEv2 mediante NEVPNProtocolIKEv2 y NETunnelProviderProtocol si distribuye una extensión de túnel de paquetes propia. La referencia de NEVPNManager enumera los objetos de protocolo aceptados. L2TP y PPTP nunca aparecen en esa lista porque Apple no publicó clases para ellos. Intentar cualquiera de los dos acaba al guardar con un error o, peor, con una configuración que el sistema declina usar en silencio.
El código de escritorio sigue otras reglas. En macOS, SCNetworkInterfaceCreateWithInterface apila un tipo de interfaz como L2TP sobre IPv4 y lo adjunta a un servicio de red, y networksetup -connectpppoeservice inicia el resultado. Hacen falta derechos de administrador y una herramienta auxiliar, porque el secreto compartido y la contraseña van al llavero del sistema. Copie ese diseño a iOS y no compilará nada.
Pase una referencia del llavero, no la contraseña
Ninguna de las dos clases IKE acepta una contraseña como texto. Las dos propiedades passwordReference y sharedSecretReference quieren una referencia persistente del llavero, que se obtiene de SecItemCopyMatching pidiendo kSecReturnPersistentRef. Pasar los datos del elemento o forzar una cadena en el campo produce un fallo al guardar o una conexión con credenciales vacías. La referencia solo es tan duradera como el elemento del llavero que hay detrás, por eso el elemento debe existir antes de montar la configuración. Créelo en la misma transacción que el guardado y elimina toda una clase de errores de orden.
La autenticación con certificado toma otra ruta: identityData más identityDataPassword para un blob PKCS#12. Distribuir ese blob dentro del paquete de la app es una costumbre heredada del código de ejemplo y no una decisión de entrega, porque la contraseña viaja con él y cada copia de la app lleva la misma identidad.
El derecho y la disponibilidad lo condicionan todo
Puede que el gestor no exista en absoluto, y la razón es el aprovisionamiento. El identificador de su app necesita la capacidad Network Extension junto con el derecho de VPN personal, y el perfil que firma la compilación debe llevar ambos.
Omítalo y la instancia compartida devuelve nil, o el guardado falla con un error que nunca menciona el derecho. La disponibilidad es la otra puerta. Apunte a algo anterior a iOS 8 y el símbolo falta en tiempo de ejecución, así que el fallo es un bloqueo o un gestor con valor nil en vez de un gestor sin configuración. Compruebe el entorno de ejecución y el derecho antes de depurar el grafo de objetos.
Cargue, modifique, guarde y luego vigile el orden bajo demanda
Trate el ciclo de vida como carga, modificación y guardado, y no omita nunca la carga. Hasta que loadFromPreferences no termine, el gestor no retiene nada y el objeto de protocolo no se puede leer ni intercambiar.
Un segundo guardado sustituye la configuración en lugar de añadir otra, así que un guardado a medias puede dañar un perfil que funcionaba. Las reglas bajo demanda forman una matriz ordenada, y ese orden es la política. Ponga una regla de conexión desde cualquier lugar delante de la regla de desconexión y una desconexión manual va seguida de una reconexión inmediata, lo que parece un defecto pero sigue la evaluación documentada.
Mueva la regla de desconexión al frente cuando la acción del usuario tenga que ganar. Lo que queda fuera del control de la app importa igual. Las rutas vienen del túnel o de la política del servidor, no de una preferencia que usted fije, y el proveedor de túnel de paquetes las informa cuando arranca. La app no puede listar ni editar perfiles instalados por otras apps o perfiles de configuración, así que no prometa una pantalla que muestre cada VPN del dispositivo.