Продакт-менеджер просит кнопку, которая включает корпоративный VPN, и запрос звучит банально. В iOS это не мелкая функция; она находится вне публичного контракта, и любой обход либо не проходит проверку, либо ломается в следующем релизе. Проведите запрос через то, что платформа действительно разрешает, и дизайн во многом напишется сам. Приложение может владеть конфигурацией VPN и запускать её. Приложение не может дотянуться до системного переключателя, не может прочитать состояние профиля, который само не создавало, и не может удерживать пользователя подключённым против его воли.

Начните с трёх вещей, которые имеет в виду пользователь

Разделите смыслы, прежде чем разделять API. Иногда пользователь хочет, чтобы туннель вашего приложения был подключён, иногда — чтобы переключатель в Настройках включился для профиля, установленного кем-то другим, а иногда — чтобы телефон не мог выйти в интернет без туннеля. Это соответствует трём разным механизмам, и только первый открыт обычному приложению.

Второй смысл и порождает вопросы на Stack Overflow, и поддерживаемого ответа на него нет. Переключатель в Настройках принадлежит пользователю, а на управляемых устройствах — профилю. Ни один публичный API не перечисляет конфигурации VPN, не сообщает, поднят ли системный туннель, и не переключает его.

Что приложение действительно может создать

NetworkExtension даёт приложению собственную конфигурацию через NEVPNManager. С правом Personal VPN и согласием пользователя приложение сохраняет конфигурацию, которая появляется в Настройках под его именем, и может запустить или остановить именно это соединение. Это реальная, проверяемая возможность, и это же весь объём: менеджер читает и пишет только то, что создал сам.

Право не выдаётся автоматически. Вы запрашиваете его у Apple и обосновываете, зачем приложению вообще нужен туннель, а у клиента, единственная цель которого — включить чужой профиль, хорошего ответа нет. Поставщики пакетных туннелей следуют тому же правилу с другим классом: NETunnelProviderManager владеет конфигурациями на основе поставщика, которые установило само приложение. Ни один из путей не достигает профиля, доставленного MDM.

Согласие действует и в момент сохранения. Запись конфигурации спрашивает пользователя, и этот запрос не то, что приложение может подавить ради удобства.

Чтение состояния упирается в ту же стену

Статус выглядит дружелюбнее управления и так же закрыт. NEVPNStatus сообщает недействительно, отключено, подключение, подключено, повторное подтверждение или отключение для собственной конфигурации приложения, и при каждом изменении срабатывает уведомление. Он ничего не говорит о туннеле, установленном профилем управления, а именно это состояние и хочет видеть служба поддержки.

Мониторинг сетевого пути и изменения интерфейса предлагают в качестве замены на обзорах дизайна. Они описывают путь, по которому идёт трафик приложения, а он меняется по причинам, не связанным с состоянием VPN, и использование их как индикатора VPN даёт интерфейс, который лжёт в обе стороны.

On Demand и Always On — настоящие рычаги

Поддерживаемые рычаги живут в профиле, а не в приложении. Правила On Demand говорят системе, когда подключаться: упорядоченный список условий с действиями, который оценивает операционная система, а не ваш код. Правило, которое подключается на любом интерфейсе, создаёт ощущение постоянного подключения, не давая приложению никакого контроля.

Always On VPN — это механизм принуждения, и он привязан к надзору. На устройстве под надзором MDM устанавливает профиль, который держит туннель поднятым; на личном телефоне без надзора те же ключи не дают того же поведения. Эта асимметрия намеренна, и никакая комбинация ключей полезной нагрузки её не убирает. Когда требование действительно в том, что VPN должен быть включён, требование на самом деле в том, что устройством нужно управлять.

Между ними сидит более слабый родственник: правило, которое переподключается после того, как пользователь отключился. Оно подключается при следующей оценке правила, что не то же самое, что сразу, и пользователь, отключившийся нарочно, заметит разницу. Проектируйте интерфейс вокруг этого зазора, а не обещайте замок.

Поставляйте поддерживаемый путь

Четыре вопроса решают механизм до того, как появится код: кому принадлежит устройство, под надзором ли оно, какой клиент завершает туннель и откуда берётся профиль. Если что-то из этого неизвестно, запрос на функцию не готов к оценке.

Приватный API, который ковыряется в системном VPN, пройдёт демонстрацию и провалит проверку, а если его поставят иным способом, он сломается в следующем релизе iOS. Нет версии этой сделки, которая стоила бы одного переключателя.

Телеметрия управления — отдельный канал: она сообщает, что профиль установлен и соответствует ли устройство требованиям, а это отчётность, а не поверхность управления для каждого приложения. Тестируйте поток на реальном устройстве после каждого обновления, потому что поддерживаемое поведение живёт в ОС, а ОС движется.

Похожие статьи