iOS NETunnelProviderManager保存多个配置

iOS NETunnelProviderManager保存多个配置,ios,objective-c,network-programming,networkextension,nevpnmanager,Ios,Objective C,Network Programming,Networkextension,Nevpnmanager,我正在尝试将我的VPN配置保存到首选项,该首选项已经起作用(我可以连接到我的VPN)。但由于某些原因,每次我再次运行代码而不是使用上一个配置时,它都会创建一个新的配置。因此,我最终得到了一系列配置 这是我目前的代码,如果有人能让我知道它出了什么问题,那就太棒了。谢谢 // Initialize Manager NETunnelProviderManager *manager = [[NETunnelProviderManager alloc] init]; [manager loadFromP

我正在尝试将我的VPN配置保存到首选项,该首选项已经起作用(我可以连接到我的VPN)。但由于某些原因,每次我再次运行代码而不是使用上一个配置时,它都会创建一个新的配置。因此,我最终得到了一系列配置

这是我目前的代码,如果有人能让我知道它出了什么问题,那就太棒了。谢谢

// Initialize Manager
NETunnelProviderManager *manager = [[NETunnelProviderManager alloc] init];

[manager loadFromPreferencesWithCompletionHandler:^(NSError *error) {
    if (error) {
        NSLog(@"Load Error: %@", error.description);
    } else {

        // Create the protocol object
        NETunnelProviderProtocol *protocol = [[NETunnelProviderProtocol alloc] init]; // Create the protocol object

        // Configure the protocol object
        protocol.providerBundleIdentifier = @"com.nfisc.testvpn.ptp";                 // Bundle ID of tunnel provider
        protocol.providerConfiguration = @{};                                         // Currently blank, but will be used later
        protocol.serverAddress = @"0.0.0.0";                                          // Ommited for security reasons
        protocol.username = @"username";                                              // The username for the configuration
        protocol.identityDataPassword = @"password";                                  // The password for the configuration
        protocol.disconnectOnSleep = NO;

        // Configure the manager with the protocol
        manager.protocolConfiguration = protocol;
        manager.enabled = true;

        [manager saveToPreferencesWithCompletionHandler:^(NSError *error) {
            if (error) {
                NSLog(@"Save Error: %@", error.description);
            } else {
                if ([[manager connection] status] != NEVPNStatusConnected) {
                    NSLog(@"Starting VPN");
                    [self start:manager];
                } else {
                    NSLog(@"VPN Already Connected");
                    [_statusLabel setText:@"Connected"];
                    [_statusLabel setTextColor:[UIColor greenColor]];
                }

            }
        }];
    }
}];

解决方案是首先调用
[NETunnelProviderManager loadAllFromPreferencesWithCompletionHandler:
,然后执行其余操作

固定代码:

__block NETunnelProviderManager *manager = [[NETunnelProviderManager alloc] init];

NETunnelProviderProtocol *protocol = [[NETunnelProviderProtocol alloc] init];
protocol.providerBundleIdentifier = @"com.nfisc.testvpn.ptp";   // bundle ID of tunnel provider
protocol.providerConfiguration = @{@"key": @"value"};
protocol.serverAddress = @"0.0.0.0";        // VPN server address
protocol.username = @"username";
protocol.identityDataPassword = @"password";
manager.protocolConfiguration = protocol;
manager.enabled = true;

[NETunnelProviderManager loadAllFromPreferencesWithCompletionHandler:^(NSArray<NETunnelProviderManager *> * _Nullable managers, NSError * _Nullable error) {
    if ([managers count] > 0) {
        manager = [managers objectAtIndex:0];
        [self start:manager];
    } else {
        [manager saveToPreferencesWithCompletionHandler:^(NSError *error) {
            if (error) {
                NSLog(@"Error 1: %@", error.description);
            } else {
                [manager loadFromPreferencesWithCompletionHandler:^(NSError * _Nullable error) {
                    if (error) {
                        NSLog(@"Error 2: %@", error.description);
                    } else {
                        [self start:manager];
                    }
                }];
            }
        }];
    }
}
\u块NETunnelProviderManager*管理器=[[NETunnelProviderManager alloc]init];
NETunnelProviderProtocol*协议=[[NETunnelProviderProtocol alloc]init];
protocol.providerBundleIdentifier=@“com.nfisc.testvpn.ptp”;//隧道提供程序的包ID
protocol.providerConfiguration=@{@“key”:@“value”};
protocol.serverAddress=@“0.0.0.0”;//VPN服务器地址
protocol.username=@“username”;
protocol.identityDataPassword=@“password”;
manager.protocolConfiguration=协议;
manager.enabled=true;
[NETunnelProviderManager loadAllFromPreferencesWithCompletionHandler:^(NSArray*\u可为空的管理器,NSError*\u可为空的错误){
如果([managers count]>0){
manager=[managers objectAtIndex:0];
[自启动:管理器];
}否则{
[manager saveToPreferencesWithCompletionHandler:^(n错误*错误){
如果(错误){
NSLog(@“错误1:%@”,错误描述);
}否则{
[manager loadFromPreferencesWithCompletionHandler:^(n错误*\u可为空错误){
如果(错误){
NSLog(@“错误2:%@”,错误描述);
}否则{
[自启动:管理器];
}
}];
}
}];
}
}
使用
+(void)loadAllFromPreferencesWithCompletionHandler:(void(^)(NSArray*managers,NSError*error))completionHandler
API

仅当块中的managers.count==0时创建新协议

[NETunnelProviderManager loadAllFromPreferencesWithCompletionHandler:^(NSArray<NETunnelProviderManager *> * _Nullable managers, NSError * _Nullable error) {
    if (error) {
        NSLog(@"Load Error: %@", error.description);
    }

    NETunnelProviderManager *manager;
    if (managers.count > 0) {
        manager = managers[0];
    }else {
        manager = [[NETunnelProviderManager alloc] init];
        manager.protocolConfiguration = [[NETunnelProviderProtocol alloc] init];
    }

//... your code here...
}];
[NETunnelProviderManager loadAllFromPreferencesWithCompletionHandler:^(NSArray*\u可空管理器,NSError*\u可空错误){
如果(错误){
NSLog(@“加载错误:%@”,错误说明);
}
NETunnelProviderManager*管理器;
如果(managers.count>0){
经理=经理[0];
}否则{
manager=[[NETunnelProviderManager alloc]init];
manager.protocolConfiguration=[[NETunnelProviderProtocol alloc]init];
}
//…你的代码在这里。。。
}];

Hey@jacky,我们必须同时提交,但我肯定会接受你的:)不幸的是,我必须等待24小时才能授予你奖金。谢谢!我在开发VPN相关应用程序方面有一些经验。如果你还有任何问题,请随时通知我。谢谢你的解决方案,但我还有另一个问题,即多个问题虽然我从控制器中删除了通知的观察者,但仍触发了ple vpn状态通知。对此有任何帮助吗?