Два коди помилки пояснюють більшість перших спроб із Network Extension VPN на iOS: NEVPNErrorDomain Code=4 і Code=5. Жоден не є скаргою сервера. Один з’являється, коли застосунок записує налаштування в об’єкт, який жодного разу не читався з диска, а другий — коли сам запис не вдається, найчастіше через те, що профіль зберігається, поки він ще вимкнений. Обидва виправляються зміною порядку чотирьох викликів, а не правкою параметрів IKEv2.

Спочатку завантажте, інакше збереженню нема з чим порівнювати

Менеджер тримає копію збереженого профілю, і об’єкт, який ви редагуєте, не є цією копією, доки ви її не прочитаєте. Спочатку викличте loadFromPreferences, редагуйте всередині його обробника завершення, потім збережіть. Якщо пропустити читання, фреймворк побачить розбіжність між тим, що в нього є, і тим, що ви пишете. У Swift форма однакова на кожному кроці, і кожен крок належить своєму замиканню:

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

Запуск тунелю зсередини замикання збереження — та сама помилка в іншому місці. Він виконується до повторного читання профілю, тому виклик запуску бачить стан, який ви побудували, а не стан, який було збережено. Замикання збереження завершується другим loadFromPreferences, і лише цей обробник завершення викликає startVPNTunnel.

Прапорець увімкнення — частина збереження

Збережений профіль не діє, доки його не ввімкнуть. Задайте isEnabled = true у тому самому записі, інакше профіль потрапить на диск вимкненим, і startVPNTunnel відмовить, навіть якщо Налаштування показують конфігурацію, що виглядає повною.

Зовнішні зміни — друга половина. Якщо користувач щось змінює в Налаштуваннях або пристрій переміщується між мережами, перечитайте, перш ніж довіряти значенням, які ви ще тримаєте в пам’яті. Об’єкт не відстежує ці зміни за вас. Застаріла копія — це спосіб, у який застосунок записує профіль, що тихо відкочує правку користувача. Два сусідні поля створюють тиху проблему в той самий момент: правила on-demand мають бути масивом об’єктів правил, а не порожньою заглушкою, а disconnectOnSleep має відображати обрану вами поведінку, а не скопійоване значення за замовчуванням.

Стороннім застосункам доступні лише два протоколи

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

Облікові дані йдуть за тією самою схемою. Покладіть пароль у Keychain і передайте постійне посилання замість рядка. Нульове посилання під час збереження зазвичай означає, що пошук відбувся до запису елемента, а не що менеджер зламаний.

І те, і друге — рішення проєктування, а не обхідні шляхи. Застосунок, який тримає пароль у власних налаштуваннях, обирає шлях, якого фреймворк не схвалює, і його збій читається як помилка збереження.

Виключіть право, перш ніж переписувати код

Коли loadFromPreferences взагалі не викликає зворотний виклик, імовірна причина — відсутня можливість Network Extension або профіль підготовки, який її не містить. Цей збій зависає замість того, щоб дати помилку, і саме тому робочий код переписують годинами. Перевірте право в підписаній збірці, яку ви збираєтеся випускати, бо запуск у симуляторі й на пристрої може відрізнятися, а важлива ціль — пристрій. Відкрийте налаштування підпису цілі й підтвердьте, що можливість Network Extension присутня саме для цієї збірки.

Профіль підготовки без права зазнає збою так само на обладнанні, тоді як та сама збірка може нормально завантажитися в симуляторі. Перевірте підписаний архів на реальному пристрої, перш ніж переписувати порядок викликів.

Стежте за змінами стану, а не за припущеннями

Спостерігайте за NEVPNStatusDidChangeNotification і записуйте manager.connection.status після кожного кроку. Стан, який ніколи не покидає invalid, означає, що профіль не збережено або права немає. З’єднання, яке досягає connecting і ніколи не підключається, вказує на пропозицію або облікові дані, і це інше розслідування з іншими доказами.

Підтвердьте, що профіль з’являється в розділі Налаштування, Загальні, VPN, і запишіть помилку з кожного замикання. Ці два факти без здогадок відокремлюють помилку порядку від помилки прав.

Схожі статті