NEVPNManager nie zapisuje? Kolejność to wczytaj, włącz, zapisz, połącz
Kody 4 i 5 zwykle oznaczają, że profil zmodyfikowano przed wczytaniem albo zapisano go, gdy był wyłączony. Popraw kolejność wywołań, a potem sprawdź uprawnienie.
Dwa kody błędu wyjaśniają większość pierwszych prób z VPN Network Extension w iOS: NEVPNErrorDomain Code=4 i Code=5. Żaden nie jest skargą serwera. Jeden pojawia się, gdy aplikacja zapisuje ustawienia do obiektu, którego nigdy nie odczytano z dysku, a drugi, gdy sam zapis się nie udaje, najczęściej dlatego, że profil jest zapisywany, gdy jest jeszcze wyłączony. Oba naprawia się, zmieniając kolejność czterech wywołań, a nie dotykając parametrów IKEv2.
Najpierw wczytaj, inaczej zapis nie ma z czym porównać
Menedżer trzyma kopię zapisanego profilu, a obiekt, który edytujesz, nie jest tą kopią, dopóki jej nie odczytasz. Najpierw wywołaj loadFromPreferences, edytuj w jego procedurze ukończenia, a potem zapisz. Jeśli pominiesz odczyt, framework zobaczy rozbieżność między tym, co ma, a tym, co zapisujesz. W Swift kształt jest taki sam na każdym kroku, a każdy krok należy do własnego 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
}
}
Uruchamianie tunelu z wnętrza closure zapisu to ten sam błąd w innym miejscu. Działa, zanim profil zostanie ponownie odczytany, więc wywołanie startu widzi stan, który zbudowałeś, a nie stan, który został zapisany. Closure zapisu kończy się drugim loadFromPreferences i tylko ta procedura ukończenia wywołuje startVPNTunnel.
Flaga włączenia jest częścią zapisu
Zapisany profil jest bezużyteczny, dopóki nie zostanie włączony. Ustaw isEnabled = true w tym samym zapisie, inaczej profil trafi na dysk wyłączony i startVPNTunnel odmówi, nawet gdy Ustawienia pokazują konfigurację, która wygląda na kompletną.
Zewnętrzne zmiany to druga połowa. Jeśli użytkownik zmieni coś w Ustawieniach albo urządzenie przejdzie między sieciami, odczytaj ponownie, zanim zaufasz wartościom, które wciąż trzymasz w pamięci. Obiekt nie obserwuje tych zmian za ciebie. Nieaktualna kopia to sposób, w jaki aplikacja zapisuje profil, który po cichu cofa zmianę użytkownika. Dwa sąsiednie pola powodują cichy problem w tej samej chwili: reguły on-demand muszą być tablicą obiektów reguł, a nie pustym zastępnikiem, a disconnectOnSleep powinien odzwierciedlać wybrane zachowanie, a nie skopiowaną wartość domyślną.
Tylko dwa protokoły są dostępne dla aplikacji innych firm
Network Extension daje aplikacjom IPsec i IKEv2. L2TP i PPTP zostają w systemie, więc aplikacja, która ich potrzebuje, nie może ich mieć, a realistyczne odpowiedzi to brama obsługująca IKEv2 albo zarządzany profil konfiguracji.
Dane logowania podlegają temu samemu wzorcowi. Umieść hasło w Keychain i przekaż trwałe odwołanie zamiast łańcucha. Puste odwołanie przy zapisie zwykle oznacza, że wyszukiwanie odbyło się przed zapisaniem elementu, a nie że menedżer jest zepsuty.
Oba są decyzjami projektowymi, a nie obejściami. Aplikacja, która trzyma hasło we własnych preferencjach, wybiera ścieżkę, której framework nie zaleca, a błąd, który produkuje, czyta się jak błąd zapisu.
Wyklucz uprawnienie, zanim przepiszesz kod
Gdy loadFromPreferences w ogóle nie wywołuje odpowiedzi, prawdopodobną przyczyną jest brakująca możliwość Network Extension albo profil provisioningu, który jej nie zawiera. Ten błąd wisi zamiast zwracać błąd, i dlatego działający kod jest przepisywany godzinami. Sprawdź uprawnienie w podpisanej kompilacji, którą zamierzasz wydać, bo uruchomienie w symulatorze i na urządzeniu mogą się różnić, a celem, który się liczy, jest urządzenie. Otwórz ustawienia podpisywania celu i potwierdź, że możliwość Network Extension jest obecna dla dokładnie tej kompilacji.
Profil provisioningu bez uprawnienia zawodzi tak samo na sprzęcie, podczas gdy ta sama kompilacja może wczytać się normalnie w symulatorze. Przetestuj podpisane archiwum na prawdziwym urządzeniu, zanim przepiszesz kolejność wywołań.
Obserwuj zmiany stanu, a nie założenia
Obserwuj NEVPNStatusDidChangeNotification i zapisuj manager.connection.status po każdym kroku. Stan, który nigdy nie opuszcza invalid, oznacza, że profil nie został zapisany albo brakuje uprawnienia. Połączenie, które osiąga connecting i nigdy się nie łączy, wskazuje na propozycję albo dane logowania, a to jest inne śledztwo z innymi dowodami.
Potwierdź, że profil pojawia się w Ustawienia, Ogólne, VPN, i zanotuj błąd z każdego closure. Te dwa fakty oddzielają błąd kolejności od błędu uprawnień bez zgadywania.