“Error Domain=NEVPNErrorDomain Code=1 \\”(null)\\“

2019-02-14 20:03发布

问题:

I'm getting "Error Domain=NEVPNErrorDomain Code=1 \"(null)\"" only first time while connecting to VPN server, later onwards it works perfectly.

I've checked NEVPNErrorDomain Error 1 when trying to start TunnelProvider network extension similar to my problem and followed the way its said in this solution but still getting same error.

So here is my code for connecting to VPN Server using Network Extension.

func initVPNTunnelProviderManager(){

    self.vpnManager.loadFromPreferences { (error) -> Void in

        if((error) != nil) {
            print("VPN Preferences error: 1")
        }
        else {

            let p = NEVPNProtocolIKEv2()
            p.username = "******"
            p.remoteIdentifier = "*****"
            p.serverAddress = "******"

            let keychain = KeychainSwift()
            let data = keychain.getData("vpnPassword")

            p.passwordReference = data
            p.authenticationMethod = NEVPNIKEAuthenticationMethod.none
            p.useExtendedAuthentication = true
            p.disconnectOnSleep = false

            self.vpnManager.protocolConfiguration = p
            self.vpnManager.isEnabled = true

            self.vpnManager.saveToPreferences(completionHandler: { (error) -> Void in
                if((error) != nil) {
                    print("VPN Preferences error: 2")
                }
                else {

                    var startError: NSError?

                    do {
                        try self.vpnManager.connection.startVPNTunnel()
                    }
                    catch let error as NSError {
                        startError = error
                        print(startError)
                    }
                    catch {
                        print("Fatal Error")
                        fatalError()
                    }
                    if((startError) != nil) {

                        **// Here it comes first time later onwards it goes to else block. (Which I'm expecting first time too)
                        print("VPN Preferences error: 3")**

                        let alertController = UIAlertController(title: "Oops..", message:
                            "Something went wrong while connecting to the VPN. Please try again.", preferredStyle: UIAlertControllerStyle.alert)
                        alertController.addAction(UIAlertAction(title: "Dismiss", style: UIAlertActionStyle.default,handler: nil))

                        self.present(alertController, animated: true, completion: nil)
                        print(startError)
                    }
                    else {
                        print("Start VPN")
                    }
                }
            })
        }
    }
}

Can someone help me why its first time going inside if ?

if((startError) != nil) { 
 // Here is control coming for first time
}
else {
// Which should always come here //later onwards its coming here, not first time.
}

NOTE : I found relevant post here on GitHub but if I try this solution its giving Optional(Error Domain=NEVPNErrorDomain Code=4 "(null)") issue because, The configuration is stale and needs to be loaded. You should call loadFromPreferencesWithCompletionHandler: and in the completion handler modify the values you want to modify, and then call saveToPreferencesWithCompletionHandler:.

Thanks in advance.

回答1:

Solution is :

Calling loadFromPreferences again right after saveToPreferences and starting the connection after load completion will fix the issue. It's as idiotic as it may sound.

self.vpnManager.saveToPreferences(completionHandler: { (error) -> Void in
            if((error) != nil) {
                print("VPN Preferences error: 2")
            }
            else {

                self.vpnManager.loadFromPreferences(completionHandler: { (error) in

                    if((error) != nil) {

                        print("VPN Preferences error: 2")
                    }
                    else {

                        var startError: NSError?

                        do {
                            try self.vpnManager.connection.startVPNTunnel()
                        }
                        catch let error as NSError {
                            startError = error
                            print(startError)
                        }
                        catch {
                            print("Fatal Error")
                            fatalError()
                        }
                        if((startError) != nil) {
                            print("VPN Preferences error: 3")
                            let alertController = UIAlertController(title: "Oops..", message:
                                "Something went wrong while connecting to the VPN. Please try again.", preferredStyle: UIAlertControllerStyle.alert)
                            alertController.addAction(UIAlertAction(title: "Dismiss", style: UIAlertActionStyle.default,handler: nil))

                            self.present(alertController, animated: true, completion: nil)
                            print(startError)
                        }
                        else {
                            self.VPNStatusDidChange(nil)
                            print("Start VPN")
                        }

                    }

                })

            }
        })


回答2:

For me, worked this solution:

  [self save:settings callback:^(NSError *saveError) {
    if (saveError) {
        completionHandler(saveError);
        HMLog(@"Save config failed [%@]", saveError.localizedDescription);
        return;
    }
    [self.vpnManager loadFromPreferencesWithCompletionHandler:^(NSError *e) {  // hack for fix error "NEVPNErrorDomain Code=1"
        [self.vpnManager loadFromPreferencesWithCompletionHandler:^(NSError *loadError) {
            if (loadError) {
                completionHandler(loadError);
                return;
            }
            NSError *a1;
            [self.vpnManager.connection startVPNTunnelAndReturnError:&a1];
            if (a1) {
                completionHandler(a1);
            } else
                completionHandler(nil);
        }];
    }];
}];

Just twice call loadFromPreferences, after saving. This fix work on ios: 9, 10, 11. I don't know why, but its work....