Αποτυγχάνει η αποθήκευση του NEVPNManager; Η σειρά είναι φόρτωση, ενεργοποίηση, αποθήκευση, σύνδεση
Ο κωδικός 4 και ο κωδικός 5 συνήθως σημαίνουν ότι το προφίλ τροποποιήθηκε πριν φορτωθεί ή αποθηκεύτηκε ενώ ήταν απενεργοποιημένο. Διορθώστε τη σειρά των κλήσεων και μετά ελέγξτε το δικαίωμα.
Δύο κωδικοί σφάλματος εξηγούν τις περισσότερες πρώτες προσπάθειες για VPN Network Extension στο iOS: 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 και περάστε μια μόνιμη αναφορά αντί για τη συμβολοσειρά. Μια μηδενική αναφορά κατά την αποθήκευση συνήθως σημαίνει ότι η αναζήτηση έτρεξε πριν γραφτεί το στοιχείο, όχι ότι ο διαχειριστής είναι χαλασμένος.
Και τα δύο είναι σχεδιαστικές αποφάσεις και όχι παρακαμπτήριες λύσεις. Μια εφαρμογή που κρατά τον κωδικό στις δικές της προτιμήσεις διαλέγει δρόμο που το πλαίσιο αποθαρρύνει, και η αποτυχία που παράγει διαβάζεται σαν σφάλμα αποθήκευσης.
Αποκλείστε το δικαίωμα πριν ξαναγράψετε κώδικα
Όταν η loadFromPreferences δεν επιστρέφει καθόλου κλήση, η πιθανή αιτία είναι μια δυνατότητα Network Extension που λείπει ή ένα προφίλ παροχής που δεν τη φέρει. Αυτή η αποτυχία κρέμεται αντί να δίνει σφάλμα, και γι’ αυτό κώδικας που δουλεύει ξαναγράφεται για ώρες. Ελέγξτε το δικαίωμα στο υπογεγραμμένο build που σκοπεύετε να διανείμετε, γιατί μια εκτέλεση στον εξομοιωτή και μια στη συσκευή μπορεί να διαφέρουν και ο στόχος που μετράει είναι η συσκευή. Ανοίξτε τις ρυθμίσεις υπογραφής του στόχου και επιβεβαιώστε ότι η δυνατότητα Network Extension υπάρχει για αυτό ακριβώς το build.
Ένα προφίλ παροχής χωρίς το δικαίωμα αποτυγχάνει με τον ίδιο τρόπο στο υλικό, ενώ το ίδιο build μπορεί να φορτώνει κανονικά στον εξομοιωτή. Δοκιμάστε το υπογεγραμμένο αρχείο σε πραγματική συσκευή πριν ξαναγράψετε τη σειρά κλήσεων.
Παρατηρήστε τις αλλαγές κατάστασης, όχι τις υποθέσεις
Παρατηρήστε το NEVPNStatusDidChangeNotification και καταγράψτε το manager.connection.status μετά από κάθε βήμα. Μια κατάσταση που δεν φεύγει ποτέ από το invalid σημαίνει ότι το προφίλ δεν αποθηκεύτηκε ή ότι λείπει το δικαίωμα. Μια σύνδεση που φτάνει στο connecting και δεν συνδέεται ποτέ δείχνει στην πρόταση ή στα διαπιστευτήρια, που είναι άλλη έρευνα με άλλα στοιχεία.
Επιβεβαιώστε ότι το προφίλ εμφανίζεται στις Ρυθμίσεις, Γενικά, VPN, και καταγράψτε το σφάλμα από κάθε closure. Αυτά τα δύο γεγονότα χωρίζουν ένα σφάλμα σειράς από ένα σφάλμα δικαιωμάτων χωρίς εικασίες.