Două coduri de eroare explică majoritatea primelor încercări cu un VPN Network Extension pe iOS: NEVPNErrorDomain Code=4 și Code=5. Niciunul nu este o plângere a serverului. Unul apare când aplicația scrie setări într-un obiect care nu a fost citit niciodată de pe disc, iar celălalt când scrierea însăși eșuează, cel mai des pentru că profilul este salvat în timp ce este încă dezactivat. Ambele se rezolvă schimbând ordinea a patru apeluri, nu atingând parametrii IKEv2.

Încărcați mai întâi, altfel salvarea nu are cu ce compara

Managerul păstrează o copie a profilului salvat, iar obiectul pe care îl editați nu este acea copie până nu o citiți. Apelați mai întâi loadFromPreferences, editați în handlerul său de finalizare, apoi salvați. Dacă săriți citirea, frameworkul vede o nepotrivire între ce are și ce scrieți. În Swift forma este aceeași la fiecare pas, iar fiecare pas aparține propriului 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
    }
}

Pornirea tunelului din interiorul closure-ului de salvare este aceeași greșeală în alt loc. Rulează înainte ca profilul să fie recitit, așa că apelul de pornire vede starea pe care ați construit-o, nu starea care a fost salvată. Closure-ul de salvare se termină cu un al doilea loadFromPreferences, și doar acel handler de finalizare apelează startVPNTunnel.

Indicatorul de activare face parte din salvare

Un profil salvat este inert până când este pornit. Setați isEnabled = true în aceeași scriere, altfel profilul ajunge pe disc dezactivat și startVPNTunnel refuză chiar dacă Setările arată o configurație care pare completă.

Modificările externe sunt cealaltă jumătate. Dacă utilizatorul schimbă ceva în Setări, sau dispozitivul se mută între rețele, citiți din nou înainte de a vă baza pe valorile pe care încă le țineți în memorie. Obiectul nu observă acele schimbări pentru dumneavoastră. O copie învechită este felul în care o aplicație scrie un profil care anulează în tăcere modificarea utilizatorului. Două câmpuri alăturate creează probleme tăcute în același moment: regulile on-demand trebuie să fie un tablou de obiecte regulă, nu un substituent gol, iar disconnectOnSleep ar trebui să reflecte comportamentul ales, nu o valoare implicită copiată.

Doar două protocoale sunt disponibile pentru aplicațiile terțe

Network Extension le oferă aplicațiilor IPsec și IKEv2. L2TP și PPTP rămân în interiorul sistemului, așa că o aplicație care le necesită nu le poate avea, iar răspunsurile realiste sunt o poartă compatibilă cu IKEv2 sau un profil de configurare gestionat.

Credențialele urmează același model. Puneți parola în Keychain și transmiteți o referință persistentă în locul șirului. O referință nulă la salvare înseamnă de obicei că căutarea a rulat înainte ca elementul să fie scris, nu că managerul este stricat.

Ambele sunt decizii de proiectare, nu soluții de ocol. O aplicație care ține parola în propriile preferințe alege o cale pe care frameworkul nu o recomandă, iar eșecul pe care îl produce se citește ca o eroare de salvare.

Eliminați dreptul înainte de a rescrie codul

Când loadFromPreferences nu mai apelează deloc, cauza probabilă este o capacitate Network Extension lipsă sau un profil de provizionare care nu o conține. Acel eșec atârnă în loc să dea eroare, și de aceea codul funcțional este rescris ore întregi. Verificați dreptul pe buildul semnat pe care intenționați să îl livrați, pentru că o rulare în simulator și una pe dispozitiv pot diferi, iar ținta care contează este dispozitivul. Deschideți setările de semnare ale țintei și confirmați că capacitatea Network Extension este prezentă pentru exact acel build.

Un profil de provizionare fără drept eșuează la fel pe hardware, în timp ce același build poate fi încărcat normal în simulator. Testați arhiva semnată pe un dispozitiv real înainte de a rescrie ordinea apelurilor.

Urmăriți schimbările de stare, nu presupunerile

Observați NEVPNStatusDidChangeNotification și înregistrați manager.connection.status după fiecare pas. O stare care nu părăsește niciodată invalid înseamnă că profilul nu a fost salvat sau că dreptul lipsește. O conexiune care ajunge la connecting și nu se conectează niciodată indică propunerea sau credențialele, ceea ce este o altă investigație cu alte dovezi.

Confirmați că profilul apare sub Setări, General, VPN, și notați eroarea din fiecare closure. Aceste două fapte separă un defect de ordine de un defect de permisiuni fără ghicit.

Articole similare