NEVPNManager n’enregistre pas ? L’ordre est charger, activer, enregistrer, connecter
Les codes 4 et 5 signifient le plus souvent que le profil a été modifié avant son chargement ou enregistré alors qu’il était désactivé. Corrigez l’ordre des appels, puis vérifiez l’autorisation.
Deux codes d’erreur expliquent la plupart des premières tentatives de VPN Network Extension sous iOS : NEVPNErrorDomain Code=4 et Code=5. Aucun des deux n’est une plainte du serveur. L’un apparaît quand l’app écrit des réglages dans un objet qui n’a jamais été lu depuis le disque, l’autre quand l’écriture elle-même échoue, le plus souvent parce que le profil est enregistré alors qu’il est encore désactivé. Les deux se corrigent en changeant l’ordre de quatre appels, pas en touchant aux paramètres IKEv2.
Chargez d’abord, sinon l’enregistrement n’a rien à comparer
Le gestionnaire détient une copie du profil stocké, et l’objet que vous modifiez n’est cette copie qu’une fois que vous l’avez lu. Appelez d’abord loadFromPreferences, modifiez dans son gestionnaire d’achèvement, puis enregistrez. Si vous sautez la lecture, le framework voit un écart entre ce qu’il a et ce que vous écrivez. En Swift la forme est la même à chaque étape, et chaque étape appartient à sa propre fermeture :
let mgr = NEVPNManager.shared()
mgr.loadFromPreferences { loadErr in
guard loadErr == nil else { return }
let proto = NEVPNProtocolIKEv2()
proto.serverAddress = "vpn.example.net"
proto.username = "alice"
proto.useExtendedAuthentication = true
mgr.protocolConfiguration = proto
mgr.isEnabled = true
mgr.saveToPreferences { saveErr in
// do not start here; reload, then connect
}
}
Démarrer le tunnel depuis l’intérieur de la fermeture d’enregistrement est la même erreur ailleurs. Cela s’exécute avant que le profil ait été relu, donc l’appel de démarrage voit l’état que vous avez construit et non celui qui a été enregistré. La fermeture d’enregistrement se termine par un second loadFromPreferences, et seul ce gestionnaire d’achèvement appelle startVPNTunnel.
L’indicateur d’activation fait partie de l’enregistrement
Un profil enregistré est inerte tant qu’il n’est pas activé. Définissez isEnabled = true dans la même écriture, sinon le profil arrive sur le disque désactivé et startVPNTunnel refuse alors même que Réglages montre une configuration qui semble complète.
Les modifications externes sont l’autre moitié. Si l’utilisateur change quelque chose dans Réglages, ou si l’appareil passe d’un réseau à l’autre, relisez avant de faire confiance aux valeurs que vous gardez encore en mémoire. L’objet n’observe pas ces changements pour vous. Une copie périmée est la façon dont une app écrit un profil qui annule silencieusement la modification de l’utilisateur. Deux champs voisins posent problème au même moment : les règles on-demand doivent être un tableau d’objets règle et non un espace réservé vide, et disconnectOnSleep doit refléter le comportement que vous avez choisi et non une valeur par défaut recopiée.
Seuls deux protocoles sont disponibles pour les apps tierces
Network Extension donne aux apps IPsec et IKEv2. L2TP et PPTP restent à l’intérieur du système, donc une app qui en a besoin ne peut pas les avoir, et les réponses réalistes sont une passerelle compatible IKEv2 ou un profil de configuration géré.
Les identifiants suivent le même schéma. Placez le mot de passe dans le Keychain et transmettez une référence persistante au lieu de la chaîne. Une référence nulle à l’enregistrement signifie généralement que la recherche a eu lieu avant l’écriture de l’élément, pas que le gestionnaire est cassé.
Les deux sont des décisions de conception et non des contournements. Une app qui garde le mot de passe dans ses propres préférences choisit une voie que le framework déconseille, et l’échec qu’elle produit se lit comme une erreur d’enregistrement.
Écartez l’autorisation avant de réécrire du code
Quand loadFromPreferences ne rappelle jamais, la cause probable est une capacité Network Extension absente ou un profil d’approvisionnement qui ne la porte pas. Cette défaillance se bloque au lieu de signaler une erreur, et c’est pourquoi du code qui fonctionne est réécrit pendant des heures. Vérifiez l’autorisation sur la build signée que vous comptez livrer, car une exécution en simulateur et une exécution sur appareil peuvent différer et la cible qui compte est l’appareil. Ouvrez les réglages de signature de la cible et confirmez que la capacité Network Extension est présente pour cette build exacte.
Un profil d’approvisionnement sans l’autorisation échoue de la même manière sur le matériel, alors que la même build peut se charger normalement dans le simulateur. Testez l’archive signée sur un appareil réel avant de réécrire l’ordre des appels.
Observez les changements d’état, pas les suppositions
Observez NEVPNStatusDidChangeNotification et journalisez manager.connection.status après chaque étape. Un état qui ne quitte jamais invalid signifie que le profil n’a pas été stocké ou que l’autorisation est absente. Une connexion qui atteint connecting et ne se connecte jamais pointe vers la proposition ou les identifiants, ce qui est une autre enquête avec d’autres preuves.
Confirmez que le profil apparaît dans Réglages, Général, VPN, et notez l’erreur de chaque fermeture. Ces deux faits séparent un bug d’ordre d’un bug d’autorisation sans deviner.