Dalawang error code ang nagpapaliwanag sa karamihan ng unang pagtatangka sa isang Network Extension VPN sa iOS: NEVPNErrorDomain Code=4 at Code=5. Wala sa kanila ang reklamo ng server. Lumilitaw ang isa kapag nagsusulat ang app ng mga setting sa isang object na hindi kailanman nabasa mula sa disk, at ang isa kapag nabigo ang mismong pagsulat, kadalasan dahil nise-save ang profile habang naka-disable pa ito. Pareho silang naaayos sa pamamagitan ng pagbabago ng pagkakasunod-sunod ng apat na tawag, hindi sa paghawak sa mga parameter ng IKEv2.

Mag-load muna, kung hindi ay wala nang maihahambing ang pag-save

May hawak na kopya ang manager ng naka-save na profile, at ang object na ine-edit mo ay hindi ang kopyang iyon hanggang mabasa mo ito. Tawagin muna ang loadFromPreferences, mag-edit sa loob ng completion handler nito, pagkatapos ay i-save. Kapag nilaktawan mo ang pagbasa, nakikita ng framework ang pagkakaiba sa pagitan ng mayroon ito at ng isinusulat mo. Sa Swift pareho ang hugis sa bawat hakbang, at bawat hakbang ay nabibilang sa sarili nitong 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
    }
}

Ang pagsisimula ng tunnel mula sa loob ng save closure ay parehong pagkakamali sa ibang lugar. Tumatakbo ito bago muling basahin ang profile, kaya nakikita ng start call ang estadong ginawa mo at hindi ang estadong na-save. Nagtatapos ang save closure sa pangalawang loadFromPreferences, at tanging ang completion handler na iyon ang tumatawag ng startVPNTunnel.

Ang enable flag ay bahagi ng pag-save

Ang naka-save na profile ay hindi gumagana hanggang buksan ito. Itakda ang isEnabled = true sa parehong pagsulat, kung hindi ay mapupunta ang profile sa disk na naka-disable at tatanggi ang startVPNTunnel kahit nagpapakita ang Settings ng configuration na mukhang kumpleto.

Ang mga panlabas na edit ay ang kabilang kalahati. Kung may binago ang user sa Settings, o gumalaw ang device sa pagitan ng mga network, basahin muli bago magtiwala sa mga value na hawak mo pa sa memory. Hindi binabantayan ng object ang mga pagbabagong iyon para sa iyo. Ang lumang kopya ang paraan ng pagsulat ng app ng profile na tahimik na binabalik ang edit ng user. Dalawang magkatabing field ang nagdudulot ng tahimik na problema sa parehong sandali: ang on-demand rules ay dapat array ng rule object at hindi walang laman na placeholder, at ang disconnectOnSleep ay dapat sumasalamin sa pag-uugaling pinili mo at hindi sa kinopyang default.

Dalawang protocol lang ang available sa mga third-party na app

Binibigyan ng Network Extension ang mga app ng IPsec at IKEv2. Nananatili sa loob ng system ang L2TP at PPTP, kaya ang app na nangangailangan ng mga ito ay hindi makakakuha, at ang makatotohanang sagot ay isang gateway na sumusuporta sa IKEv2 o isang managed configuration profile.

Sinusundan ng mga credential ang parehong pattern. Ilagay ang password sa Keychain at magpasa ng persistent reference sa halip na ang string. Ang null na reference sa pag-save ay karaniwang ibig sabihin na tumakbo ang paghahanap bago naisulat ang item, hindi na sira ang manager.

Parehong desisyon sa disenyo ang dalawa at hindi mga suway. Ang app na nag-iingat ng password sa sariling mga preference ay pumipili ng landas na hindi hinihikayat ng framework, at ang kabiguang nalilikha nito ay nababasa na parang error sa pag-save.

Ibukod ang entitlement bago muling isulat ang code

Kapag hindi kailanman tumawag pabalik ang loadFromPreferences, ang malamang na dahilan ay kulang na kakayahan ng Network Extension o isang provisioning profile na hindi ito dala. Ang kabiguang iyon ay nakabitin sa halip na magbigay ng error, at iyon ang dahilan kung bakit ang gumaganang code ay muling isinusulat nang maraming oras. Suriin ang entitlement sa naka-sign na build na balak mong ipadala, dahil maaaring magkaiba ang run sa simulator at sa device at ang target na mahalaga ay ang device. Buksan ang signing settings ng target at kumpirmahin na naroroon ang kakayahan ng Network Extension para sa eksaktong build na iyon.

Ang provisioning profile na walang entitlement ay nabibigo sa parehong paraan sa hardware, habang ang parehong build ay maaaring normal na mag-load sa simulator. Subukan ang naka-sign na archive sa totoong device bago muling isulat ang pagkakasunod-sunod ng mga tawag.

Panoorin ang mga pagbabago ng status, hindi ang mga palagay

Obserbahan ang NEVPNStatusDidChangeNotification at i-log ang manager.connection.status pagkatapos ng bawat hakbang. Ang status na hindi kailanman umaalis sa invalid ay ibig sabihin na hindi na-save ang profile o wala ang entitlement. Ang koneksyong umabot sa connecting at hindi kailanman kumokonekta ay tumuturo sa proposal o sa mga credential, na isa pang imbestigasyon na may ibang ebidensya.

Kumpirmahin na lumilitaw ang profile sa Settings, General, VPN, at itala ang error mula sa bawat closure. Ang dalawang katotohanang iyon ay naghihiwalay ng bug sa pagkakasunod-sunod mula sa bug sa pahintulot nang walang hula.

Kaugnay na mga artikulo