No se puede configurar la connection VPN utilizando Network Extension Framework iOS 8 en Swift

Así que he estado tratando de usar el marco de extensión de networking iOS 8 para configurar una connection VPN cuando los usuarios presionan un UIButton. He utilizado el siguiente tutorial: http://ramezanpour.net/post/2014/08/03/configure-and-manage-vpn-connections-programmatically-in-ios-8/

Pero por alguna razón sigue pidiendo la contraseña de vpn y el secreto compartido. Aunque establecí la contraseña de reference y shanetworkingSecretReference. Y si ingrese estos detalles al instalar el perfil, todavía no funcionará. Simplemente no hace nada al iniciar la connection utilizando el marco. Cuando intenta conectarse usando la aplicación de configuration, da un error de "no hay secreto compartido".

Este es el código que uso para configurar la connection.

func toggleConnection(sender: UIButton) { if(!self.connected){ self.manager.loadFromPreferencesWithCompletionHandler { (error) -> Void in if((error) != nil) { println("VPN Preferences error: 1") } else { var p = NEVPNProtocolIPSec() p.username = "$username" p.serverAddress = "$vpn" p.passwordReference = KeychainService.dataForKey("vpnPassword")! println(p.passwordReference) p.authenticationMethod = NEVPNIKEAuthenticationMethod.ShanetworkingSecret p.shanetworkingSecretReference = KeychainService.dataForKey("shanetworkingSecret")! println(p.shanetworkingSecretReference) p.localIdentifier = "vpn" p.remoteIdentifier = "vpn" p.disconnectOnSleep = false self.manager.`protocol` = p self.manager.onDemandEnabled = true self.manager.localizedDescription = "VPN" self.manager.saveToPreferencesWithCompletionHandler({ (error) -> Void in if((error) != nil) { println("VPN Preferences error: 2") println(error) } else { var startError: NSError? self.manager.connection.startVPNTunnelAndReturnError(&startError) if((startError) != nil) { println("VPN Preferences error: 3") println(startError) } else { println("Start VPN") } } }) } } } } 

Estas son las funciones que uso como reference de llavero.

 class func save(service: NSString, key: String, data: NSString) { var dataFromString: NSData = data.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)! var keychainQuery: NSMutableDictionary = NSMutableDictionary(objects: [kSecClassGenericPassword, service, key, dataFromString], forKeys: [kSecClass, kSecAttrService, kSecAttrAccount, kSecValueData]) SecItemDelete(keychainQuery as CFDictionaryRef) if data == "" { return } var status: OSStatus = SecItemAdd(keychainQuery as CFDictionaryRef, nil) println(status) } class func load(service: NSString, key: String) -> NSData? { var keychainQuery: NSMutableDictionary = NSMutableDictionary(objects: [kSecClassGenericPassword, service, key, kCFBooleanTrue, kSecMatchLimitOne, kCFBooleanTrue], forKeys: [kSecClass, kSecAttrService, kSecAttrAccount, kSecReturnData, kSecMatchLimit, kSecReturnPersistentRef]) var dataTypeRef :Unmanaged<AnyObject>? let status: OSStatus = SecItemCopyMatching(keychainQuery, &dataTypeRef) println(status) if (status != errSecSuccess) { return nil } let opaque = dataTypeRef?.toOpaque() var contentsOfKeychain: NSData? = nil if let op = opaque { let retrievedData = Unmanaged<NSData>.fromOpaque(op).takeUnretainedValue() contentsOfKeychain = retrievedData } println(contentsOfKeychain) return contentsOfKeychain } 

¡Se agradece cualquier ayuda!

Así que tuve que replace la biblioteca Swift que solía acceder al llavero con los siguientes methods Obj-C. Esto resolvió mi problema en la medida en que ahora puedo decirlo.

 + (void) storeData: (NSString * )key data:(NSData *)data { NSLog(@"Store Data"); NSMutableDictionary * dict = [[NSMutableDictionary alloc] init]; [dict setObject:(__bridge id)kSecClassGenericPassword forKey:(__bridge id)kSecClass]; NSData *encodedKey = [key dataUsingEncoding:NSUTF8StringEncoding]; [dict setObject:encodedKey forKey:(__bridge id)kSecAttrGeneric]; [dict setObject:encodedKey forKey:(__bridge id)kSecAttrAccount]; [dict setObject:@"VPN" forKey:(__bridge id)kSecAttrService]; [dict setObject:(__bridge id)kSecAttrAccessibleAlwaysThisDeviceOnly forKey:(__bridge id)kSecAttrAccessible]; [dict setObject:data forKey:(__bridge id)kSecValueData]; OSStatus status = SecItemAdd((__bridge CFDictionaryRef)dict, NULL); if(errSecSuccess != status) { NSLog(@"Unable add item with key =%@ error:%d",key,(int)status); } } + (NSData *) getData: (NSString *)key { NSMutableDictionary * dict = [[NSMutableDictionary alloc] init]; [dict setObject:(__bridge id)kSecClassGenericPassword forKey:(__bridge id)kSecClass]; NSData *encodedKey = [key dataUsingEncoding:NSUTF8StringEncoding]; [dict setObject:encodedKey forKey:(__bridge id)kSecAttrGeneric]; [dict setObject:encodedKey forKey:(__bridge id)kSecAttrAccount]; [dict setObject:@"VPN" forKey:(__bridge id)kSecAttrService]; [dict setObject:(__bridge id)kSecAttrAccessibleAlwaysThisDeviceOnly forKey:(__bridge id)kSecAttrAccessible]; [dict setObject:(__bridge id)kSecMatchLimitOne forKey:(__bridge id)kSecMatchLimit]; [dict setObject:(id)kCFBooleanTrue forKey:(__bridge id)kSecReturnPersistentRef]; CFTypeRef result = NULL; OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)dict,&result); if( status != errSecSuccess) { NSLog(@"Unable to fetch item for key %@ with error:%d",key,(int)status); return nil; } NSData *resultData = (__bridge NSData *)result; return resultData; }