Två felkoder förklarar de flesta första försök med en Network Extension VPN på iOS: NEVPNErrorDomain Code=4 och Code=5. Ingen av dem är ett klagomål från servern. Den ena visas när appen skriver inställningar i ett objekt som aldrig lästes från disken, och den andra när själva skrivningen misslyckas, oftast för att profilen sparas medan den fortfarande är inaktiverad. Båda åtgärdas genom att ändra ordningen på fyra anrop, inte genom att röra IKEv2-parametrarna.

Läs in först, annars har sparningen inget att jämföra med

Hanteraren håller en kopia av den sparade profilen, och objektet du redigerar är inte den kopian förrän du läser den. Anropa loadFromPreferences först, redigera i dess completion-hanterare och spara sedan. Om du hoppar över läsningen ser ramverket en diskrepans mellan det den har och det du skriver. I Swift är formen densamma för varje steg, och varje steg hör till sin egen closure:

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
    }
}

Att starta tunneln inifrån spara-closuren är samma misstag på en annan plats. Det körs innan profilen har lästs in igen, så startanropet ser det tillstånd du byggde och inte det tillstånd som sparades. Spara-closuren slutar med en andra loadFromPreferences, och bara den completion-hanteraren anropar startVPNTunnel.

Aktiveringsflaggan är en del av sparningen

En sparad profil är inaktiv tills den slås på. Sätt isEnabled = true i samma skrivning, annars hamnar profilen inaktiverad på disken och startVPNTunnel vägrar även om Inställningar visar en konfiguration som ser komplett ut.

Externa ändringar är den andra halvan. Om användaren ändrar något i Inställningar, eller enheten flyttar sig mellan nätverk, läs igen innan du litar på värdena du fortfarande håller i minnet. Objektet observerar inte de ändringarna åt dig. En inaktuell kopia är hur en app skriver en profil som tyst rullar tillbaka användarens ändring. Två intilliggande fält orsakar tysta problem i samma ögonblick: on-demand-regler måste vara en array av regelobjekt och inte en tom platshållare, och disconnectOnSleep bör spegla det beteende du valde och inte ett kopierat standardvärde.

Bara två protokoll är tillgängliga för tredjepartsappar

Network Extension ger appar IPsec och IKEv2. L2TP och PPTP stannar inne i systemet, så en app som behöver dem kan inte få dem, och de realistiska svaren är en IKEv2-kompatibel gateway eller en hanterad konfigurationsprofil.

Inloggningsuppgifter följer samma mönster. Lägg lösenordet i Keychain och skicka en beständig referens i stället för strängen. En nollreferens vid sparning betyder oftast att sökningen kördes innan posten skrevs, inte att hanteraren är trasig.

Båda är designval och inte kringgåenden. En app som håller lösenordet i sina egna inställningar väljer en väg som ramverket avråder från, och felet den producerar läses som ett sparfel.

Uteslut rättigheten innan du skriver om koden

När loadFromPreferences aldrig anropar tillbaka är den troliga orsaken en saknad Network Extension-funktion eller en provisioning-profil som inte bär den. Det felet hänger i stället för att ge ett fel, och därför skrivs fungerande kod om i timmar. Kontrollera rättigheten på den signerade bygge du tänker leverera, eftersom en simulatorkörning och en enhetskörning kan skilja sig och målet som betyder något är enheten. Öppna målets signeringsinställningar och bekräfta att Network Extension-funktionen finns för exakt den bygget.

En provisioning-profil utan rättigheten misslyckas på samma sätt på hårdvara, medan samma bygge kan läsas in normalt i simulatorn. Testa det signerade arkivet på en riktig enhet innan du skriver om ordningen på anropen.

Följ statusändringarna, inte antagandena

Observera NEVPNStatusDidChangeNotification och logga manager.connection.status efter varje steg. En status som aldrig lämnar invalid betyder att profilen inte sparades eller att rättigheten saknas. En anslutning som når connecting och aldrig ansluter pekar på förslaget eller inloggningsuppgifterna, och det är en annan undersökning med andra bevis.

Bekräfta att profilen visas under Inställningar, Allmänt, VPN, och notera felet från varje closure. De två fakta skiljer ett ordningsfel från ett behörighetsfel utan gissningar.

Relaterade artiklar