NEVPNManager सहेजता नहीं? क्रम है लोड, सक्षम, सहेजें, कनेक्ट
कोड 4 और कोड 5 आम तौर पर बताते हैं कि प्रोफ़ाइल लोड होने से पहले संपादित हुई या अक्षम रहते हुए सहेजी गई। कॉल का क्रम ठीक करें, फिर entitlement जाँचें।
दो त्रुटि कोड iOS पर Network Extension VPN के ज़्यादातर पहले प्रयासों की व्याख्या करते हैं: 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 में रखें और स्ट्रिंग के बजाय स्थायी संदर्भ दें। सहेजते समय शून्य संदर्भ आम तौर पर बताता है कि खोज आइटम लिखे जाने से पहले चली थी, यह नहीं कि प्रबंधक टूटा है।
दोनों कामचलाऊ उपाय नहीं, डिज़ाइन निर्णय हैं। जो ऐप पासवर्ड अपनी प्राथमिकताओं में रखता है वह वह रास्ता चुनता है जिसे ढाँचा हतोत्साहित करता है, और उससे पैदा विफलता सहेजने की त्रुटि जैसी पढ़ी जाती है।
कोड फिर से लिखने से पहले entitlement को बाहर करें
जब loadFromPreferences बिलकुल कॉलबैक नहीं करता, तो संभावित कारण Network Extension क्षमता का अनुपस्थित होना या ऐसी प्रोविज़निंग प्रोफ़ाइल है जो उसे नहीं रखती। वह विफलता त्रुटि देने के बजाय अटक जाती है, और इसीलिए काम करता कोड घंटों दोबारा लिखा जाता है। उस हस्ताक्षरित बिल्ड पर entitlement जाँचें जिसे आप भेजना चाहते हैं, क्योंकि सिम्युलेटर पर चलाना और डिवाइस पर चलाना अलग हो सकते हैं और असली लक्ष्य डिवाइस है। लक्ष्य की साइनिंग सेटिंग्स खोलें और पुष्टि करें कि Network Extension क्षमता ठीक उसी बिल्ड के लिए मौजूद है।
बिना entitlement वाली प्रोविज़निंग प्रोफ़ाइल हार्डवेयर पर उसी तरह विफल होती है, जबकि वही बिल्ड सिम्युलेटर में सामान्य रूप से लोड हो सकती है। कॉल का क्रम दोबारा लिखने से पहले हस्ताक्षरित संग्रह को असली डिवाइस पर जाँचें।
धारणाएँ नहीं, स्थिति के बदलाव देखें
NEVPNStatusDidChangeNotification देखें और हर चरण के बाद manager.connection.status लॉग करें। जो स्थिति कभी invalid नहीं छोड़ती उसका अर्थ है कि प्रोफ़ाइल सहेजी नहीं गई या entitlement नहीं है। जो कनेक्शन connecting तक पहुँचकर कभी जुड़ता नहीं, वह प्रस्ताव या क्रेडेंशियल की ओर संकेत करता है, और वह अलग साक्ष्यों वाली अलग जाँच है।
पुष्टि करें कि प्रोफ़ाइल सेटिंग्स, सामान्य, VPN के अंतर्गत दिखती है, और हर closure की त्रुटि दर्ज करें। ये दो तथ्य बिना अनुमान के क्रम की बग और अनुमति की बग को अलग करते हैं।