Два кода за грешка обясняват повечето първи опити за Network Extension VPN в iOS: NEVPNErrorDomain Code=4 и Code=5. Нито един от тях не е оплакване от сървъра. Единият се появява, когато приложението записва настройки в обект, който никога не е бил прочетен от диска, а другият — когато самият запис се провали, най-често защото профилът се запазва, докато все още е изключен. И двете се оправят чрез промяна на реда на четири извиквания, а не чрез пипане на параметрите на IKEv2.

Първо заредете, иначе запазването няма с какво да сравни

Мениджърът държи копие на съхранения профил и обектът, който редактирате, не е това копие, докато не го прочетете. Извикайте loadFromPreferences първо, редактирайте в неговия манипулатор за завършване, после запазете. Пропуснете ли четенето, рамката вижда несъответствие между това, което има, и това, което пишете. В Swift формата е еднаква за всяка стъпка и всяка стъпка принадлежи на собствен 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
    }
}

Стартирането на тунела от вътрешността на closure-а за запазване е същата грешка на друго място. То се изпълнява, преди профилът да бъде прочетен отново, така че извикването за стартиране вижда състоянието, което сте изградили, а не състоянието, което е било съхранено. Closure-ът за запазване завършва с второ loadFromPreferences и само този манипулатор за завършване извиква startVPNTunnel.

Флагът за включване е част от запазването

Съхраненият профил е инертен, докато не бъде включен. Задайте isEnabled = true в същия запис, иначе профилът попада на диска изключен и startVPNTunnel отказва, дори когато Настройки показват конфигурация, която изглежда пълна.

Външните редакции са другата половина. Ако потребителят промени нещо в Настройки или устройството се премести между мрежи, прочетете отново, преди да се доверите на стойностите, които още държите в паметта. Обектът не наблюдава тези промени вместо вас. Остаряло копие е начинът, по който приложението записва профил, който тихо връща назад редакцията на потребителя. Две съседни полета създават тиха беда в същия момент: правилата on-demand трябва да са масив от обекти на правила, а не празен заместител, а disconnectOnSleep трябва да отразява поведението, което сте избрали, а не копирана стойност по подразбиране.

Само два протокола са достъпни за приложения на трети страни

Network Extension дава на приложенията IPsec и IKEv2. L2TP и PPTP остават вътре в системата, така че приложение, което се нуждае от тях, не може да ги получи, а реалистичните отговори са шлюз с поддръжка на IKEv2 или управляван конфигурационен профил.

Идентификационните данни следват същия модел. Поставете паролата в Keychain и подайте постоянна референция вместо низа. Празна референция при запазване обикновено означава, че търсенето е текло, преди елементът да бъде записан, а не че мениджърът е счупен.

И двете са решения за дизайна, а не заобиколни решения. Приложение, което държи паролата в собствените си предпочитания, избира път, който рамката не насърчава, и провалът, който произвежда, изглежда като грешка при запазване.

Изключете правото, преди да пренаписвате код

Когато loadFromPreferences изобщо не върне обратно извикване, вероятната причина е липсваща възможност Network Extension или provisioning профил, който не я носи. Този провал виси, вместо да даде грешка, и затова работещ код се пренаписва с часове. Проверете правото в подписаната сборка, която възнамерявате да доставите, защото пускането в симулатор и на устройство може да се различава, а целта, която има значение, е устройството. Отворете настройките за подписване на целта и потвърдете, че възможността Network Extension присъства точно за тази сборка.

Provisioning профил без правото се проваля по същия начин на хардуер, докато същата сборка може да се зареди нормално в симулатора. Тествайте подписания архив на реално устройство, преди да пренаписвате реда на извикванията.

Следете промените в състоянието, а не предположенията

Наблюдавайте NEVPNStatusDidChangeNotification и записвайте manager.connection.status след всяка стъпка. Състояние, което никога не напуска invalid, означава, че профилът не е съхранен или правото липсва. Връзка, която стига до connecting и никога не се свързва, сочи към предложението или идентификационните данни, а това е друго разследване с други доказателства.

Потвърдете, че профилът се показва в Настройки, Общи, VPN, и запишете грешката от всеки closure. Тези два факта разделят грешка в реда от грешка в разрешенията без догадки.

Подобни статии