Três produtos diferentes respondem pelo nome iOS VPN, e eles não compartilham uma API. Personal VPN usa os transportes IPsec e IKEv2 embutidos no sistema. Custom tunnel executa o seu próprio protocolo dentro de uma network extension. Configuration profile configura qualquer um dos dois e pode adicionar comportamento on-demand. Escolher pelo transporte com que você precisa falar é mais rápido do que escolher pelo tutorial que compilou primeiro.

Execute as verificações abaixo em ordem, porque cada passo pressupõe que o anterior produziu uma configuração válida.

Passo 1: escolha pelo transporte

Se o servidor for IKEv2 ou IPsec no estilo Cisco, o NEVPNManager basta e os transportes do sistema vêm de graça. Se o servidor fala OpenVPN, WireGuard ou qualquer outra coisa, o NEVPNManager não ajuda: ele não tem gancho para um protocolo de terceiros. Esse caso exige o NETunnelProviderManager com um packet tunnel provider que implemente o protocolo. Um perfil apenas distribui configuração, e ele não pode adicionar um transporte que o sistema operacional não tem.

PPTP não é alvo nos sistemas atuais. IPsec com segredo compartilhado ainda espera o nome do grupo em remoteIdentifier, um item de keychain que guarda o segredo e autenticação estendida quando o servidor pede um nome de usuário. Cada peça ausente aparece como o mesmo erro genérico de configuração, então adicione todas antes de depurar qualquer outra coisa.

Passo 2: respeite a ordem salvar, carregar, iniciar

O NEVPNManager grava nas preferences, lê de volta e só então inicia. Preencha os objetos de protocolo e manager, chame saveToPreferences, chame loadFromPreferences e chame startVPNTunnel a partir do load completion handler. Iniciar antes de o carregamento retornar produz um erro configuration-invalid, NEVPNErrorDomain code 1, numa configuração que de resto está correta.

A forma é curta o bastante para ficar num só lugar:

manager.protocolConfiguration = proto
manager.isEnabled = true
manager.saveToPreferences { }
manager.loadFromPreferences { manager.connection.startVPNTunnel() }

startVPNTunnel retorna quando a solicitação é aceita, não quando o túnel está no ar. Observe NEVPNStatusDidChange e leia connection.status para o estado real. Um app que presume sucesso no ponto da chamada relata uma VPN conectada enquanto a extension ainda negocia. Um status connecting é normal por um instante; um status que nunca sai dele é a falha que vale registrar.

Passo 3: dê ao processo provider o que ele precisa

Custom transport roda num processo separado com seu próprio bundle identifier e seu próprio entitlement. Tanto o app container quanto o provider precisam do entitlement network-extension na assinatura, e uma build Developer ID fora da App Store ainda tem de carregá-lo no provisioning profile. Um entitlement ausente parece um bug de protocolo porque a extension simplesmente não inicia.

Não há socket descriptor público para emprestar. O NEPacketTunnelProvider entrega o NEPacketTunnelFlow com read, write e cancel, e código que busca caminhos de chaves privadas quebra entre versões. O provider continua rodando enquanto o app está em segundo plano, então o app container não precisa de modo de segundo plano para isso.

Passo 4: on-demand é um conjunto de regras, não um interruptor

isOnDemandEnabled apenas arma as regras; NEOnDemandRuleConnect e seus irmãos decidem quando o túnel sobe. Uma regra evaluate-connection com probe URL vale tanto quanto essa URL. Se o probe responde sem o túnel, a regra conclui que a rede privada já está acessível e nunca conecta, então aponte-a para algo que só responda de dentro.

Always-on é uma promessa separada. Exige um dispositivo supervisionado e um perfil gerenciado, e um usuário não supervisionado pode remover um perfil quando quiser. Não entregue um design que dependa de always-on a menos que a frota seja supervisionada.

Passo 5: prove o caminho, não o rótulo

Escanear interfaces tun, tap, ppp ou ipsec prova que uma VPN está configurada, não que sua solicitação a usou. O NWPathMonitor com usesInterfaceType(.other) diz que uma interface virtual está disponível, e um viability handler pode testar um host. Nenhum dos dois prova o caminho de saída, então combine-os com uma solicitação a um recurso que só o túnel alcança. Nomes de interface são auxílio diagnóstico, nunca um portão em que a lógica do app deva ramificar.

Para uma verificação de campo, compare o endereço público com e sem o túnel e busque uma página somente interna. Uma chamada de status pode relatar conectado enquanto o provider negocia, então deixe o resultado do recurso decidir e trate o status como evidência de apoio.

Artigos relacionados