El inicio de session en Facebook no vuelve a la aplicación cuando se migró a Swift 3

Soy nuevo en Swift e iOS. Había creado una aplicación de ejemplo donde el usuario inicia session usando el button de inicio de session de Facebook.

Una vez conectado, muestro Nombre del usuario y correo electrónico en la pantalla de inicio de session. Estaba trabajando con Swift 2.3. Una vez que migré a Swift 3, dejó de funcionar.

  • Paso 1: iniciar session con el button de inicio de session de Facebook
  • Paso 2: Permitir permissions para correo electrónico y perfil
  • Paso 3: Aquí debería volver a la pantalla 1. Pero no es así. Adjuntando el logging que obtengo cuando hago clic en el button "Aceptar".

Actualización 1: la aplicación funciona bien en iOS 9.3. El problema se produce solo en dispositivos iOS 10.

2016-06-19 08:30:09.300070 MyApp[13942:1214112] [] nw_endpoint_handler_start [4 graph.facebook.com:443 initial path (null)] 2016-06-19 08:30:09.300484 MyApp[13942:1214112] [] nw_connection_endpoint_report [4 graph.facebook.com:443 initial path (null)] reported event path:start 2016-06-19 08:30:09.301255 MyApp[13942:1214112] [] nw_connection_endpoint_report [4 graph.facebook.com:443 waiting path (satisfied)] reported event path:satisfied 2016-06-19 08:30:09.302664 MyApp[13942:1214112] [] nw_connection_endpoint_report [4 graph.facebook.com:443 in_progress resolver (satisfied)] reported event resolver:start_dns 2016-06-19 08:30:09.348956 MyApp[13942:1214130] [] nw_endpoint_resolver_update [4 graph.facebook.com:443 in_progress resolver (satisfied)] Adding endpoint handler for 31.13.79.246:443 2016-06-19 08:30:09.349570 MyApp[13942:1214130] [] nw_connection_endpoint_report [4 graph.facebook.com:443 in_progress resolver (satisfied)] reported event resolver:receive_dns 2016-06-19 08:30:09.350027 MyApp[13942:1214130] [] nw_endpoint_resolver_start_next_child [4 graph.facebook.com:443 in_progress resolver (satisfied)] starting child endpoint 31.13.79.246:443 2016-06-19 08:30:09.350564 MyApp[13942:1214130] [] nw_host_stats_add_src recv too small, received 24, expected 28 2016-06-19 08:30:09.351022 MyApp[13942:1214130] [] nw_endpoint_resolver_start_next_child [4 graph.facebook.com:443 in_progress resolver (satisfied)] starting next child endpoint in 250ms 2016-06-19 08:30:09.351479 MyApp[13942:1214130] [] nw_endpoint_handler_start [4.1 31.13.79.246:443 initial path (null)] 2016-06-19 08:30:09.351862 MyApp[13942:1214130] [] nw_connection_endpoint_report [4.1 31.13.79.246:443 initial path (null)] reported event path:start 2016-06-19 08:30:09.352596 MyApp[13942:1214130] [] nw_connection_endpoint_report [4.1 31.13.79.246:443 waiting path (satisfied)] reported event path:satisfied 2016-06-19 08:30:09.352915 MyApp[13942:1214130] [] __nwlog_err_simulate_crash_libsystem libsystem simulate crash unavailable, [libsystem_network.dylib: nw_endpoint_get_hostname :: incorrect endpoint type 1] 2016-06-19 08:30:09.353524 MyApp[13942:1214130] [] nw_endpoint_get_hostname incorrect endpoint type 1, dumping backtrace: [x86_64] libnetcore-805.0.0.2.2 0 libsystem_network.dylib 0x000000011186037f __nw_create_backtrace_string + 123 1 libsystem_network.dylib 0x000000011186246e nw_endpoint_get_hostname + 75 2 libnetwork.dylib 0x0000000112bc4be7 nw_endpoint_proxy_handler_should_use_proxy + 125 3 libnetwork.dylib 0x0000000112bd204f nw_endpoint_handler_path_change + 1509 4 libnetwork.dylib 0x0000000112bd18a2 nw_endpoint_handler_start + 570 5 libnetwork.dylib 0x0000000112be8026 nw_endpoint_resolver_start_next_child + 2050 6 libdispatch.dylib 0x00000001115b91e8 _dispatch_call_block_and_release + 12 7 libdispatch.dylib 0x00000001115e5dee _dispatch_client_callout + 8 8 libdispatch.dylib 0x00000001115c0a1d _dispatch_queue_serial_drain + 239 9 libdi 2016-06-19 08:30:09.357989 MyApp[13942:1214130] [] nw_connection_endpoint_report [4.1 31.13.79.246:443 in_progress socket-flow (satisfied)] reported event flow:start_connect 2016-06-19 08:30:09.468327 MyApp[13942:1214130] [] nw_endpoint_flow_protocol_connected [4.1 31.13.79.246:443 in_progress socket-flow (satisfied)] Output protocol connected 2016-06-19 08:30:09.469541 MyApp[13942:1214130] [] nw_endpoint_flow_connected_path_change [4.1 31.13.79.246:443 ready socket-flow (satisfied)] Connected path is satisfied 2016-06-19 08:30:09.470103 MyApp[13942:1214130] [] nw_connection_endpoint_report [4.1 31.13.79.246:443 ready socket-flow (satisfied)] reported event flow:finish_connect 2016-06-19 08:30:09.470858 MyApp[13942:1214130] [] nw_connection_endpoint_report [4 graph.facebook.com:443 ready resolver (satisfied)] reported event flow:finish_connect 2016-06-19 08:30:09.471427 MyApp[13942:1214130] [] nw_connection_endpoint_report [4.1 31.13.79.246:443 ready socket-flow (satisfied)] reported event flow:changed_viability 2016-06-19 08:30:09.471870 MyApp[13942:1214130] [] nw_connection_endpoint_report [4 graph.facebook.com:443 ready resolver (satisfied)] reported event flow:changed_viability 2016-06-19 08:30:09.472479 MyApp[13942:1214112] [] nw_endpoint_start_tls_while_connected [4.1 31.13.79.246:443 ready socket-flow (satisfied)] 2016-06-19 08:30:09.473243 MyApp[13942:1214112] [] nw_connection_endpoint_report [4.1 31.13.79.246:443 in_progress socket-flow (satisfied)] reported event flow:start_secondary_connect 2016-06-19 08:30:09.473685 MyApp[13942:1214112] [] nw_connection_endpoint_report [4 graph.facebook.com:443 in_progress resolver (satisfied)] reported event flow:start_secondary_connect 2016-06-19 08:30:09.474206 MyApp[13942:1214112] [] nw_connection_endpoint_report [4.1 31.13.79.246:443 in_progress socket-flow (satisfied)] reported event flow:start_connect 2016-06-19 08:30:09.474740 MyApp[13942:1214112] [] nw_connection_endpoint_report [4 graph.facebook.com:443 in_progress resolver (satisfied)] reported event flow:start_connect 2016-06-19 08:30:09.475123 MyApp[13942:1214112] [] nw_endpoint_flow_protocol_connected [4.1 31.13.79.246:443 in_progress socket-flow (satisfied)] Transport protocol connected 2016-06-19 08:30:09.475502 MyApp[13942:1214112] [] nw_connection_endpoint_report [4.1 31.13.79.246:443 in_progress socket-flow (satisfied)] reported event flow:finish_transport 2016-06-19 08:30:09.475834 MyApp[13942:1214112] [] nw_connection_endpoint_report [4 graph.facebook.com:443 in_progress resolver (satisfied)] reported event flow:finish_transport 2016-06-19 08:30:09.586843 MyApp[13942:1214130] [] nw_endpoint_flow_protocol_connected [4.1 31.13.79.246:443 in_progress socket-flow (satisfied)] Output protocol connected 2016-06-19 08:30:09.588117 MyApp[13942:1214130] [] nw_endpoint_flow_connected_path_change [4.1 31.13.79.246:443 ready socket-flow (satisfied)] Connected path is satisfied 2016-06-19 08:30:09.588724 MyApp[13942:1214130] [] nw_connection_endpoint_report [4.1 31.13.79.246:443 ready socket-flow (satisfied)] reported event flow:finish_connect 2016-06-19 08:30:09.589299 MyApp[13942:1214130] [] nw_connection_endpoint_report [4 graph.facebook.com:443 ready resolver (satisfied)] reported event flow:finish_connect 

Aquí está mi código.

ViewController

 import UIKit import FBSDKCoreKit import FBSDKLoginKit import Firebase class ViewController: UIViewController ,FBSDKLoginButtonDelegate{ //Properties @IBOutlet weak var usernameTextField: UITextField! @IBOutlet weak var usernameLabel: UILabel! @IBOutlet weak var submitButton: UIButton! @IBOutlet weak var fbLoginBtn: FBSDKLoginButton! var ref:FIRDatabaseReference! private let dataurl = "https://project-URL/“ override func viewDidLoad() { super.viewDidLoad() self.ref = FIRDatabase.database().reference() fbLoginBtn.delegate = self fbLoginBtn.readPermissions = ["email"] // Do any additional setup after loading the view, typically from a nib. } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } //Actions @IBAction func onSubmitBtnPressed(_ sender: UIButton) { usernameLabel.text = usernameTextField.text; } func loginButton(_ loginButton: FBSDKLoginButton!, didCompleteWith result: FBSDKLoginManagerLoginResult!, error: NSError!) { print("User Logged In") if ((error) != nil) { // Process error print("error") } else if result.isCancelled { // Handle cancellations print("cancelled") } else { // If you ask for multiple permissions at once, you // should check if specific permissions missing if result.grantedPermissions.contains("email") { let cnetworkingential = FIRFacebookAuthProvider.cnetworkingential(withAccessToken: FBSDKAccessToken.current().tokenString) // Do work print("logged in ") FIRAuth.auth()?.signIn(with: cnetworkingential, completion: { (user, error) in if (user != nil) { let uid = user?.uid as String! self.fetchProfile(uid!); } }) } } } func loginButtonDidLogOut(_ loginButton: FBSDKLoginButton!) { print("User Logged Out") } func fetchProfile(_ uid: String) { let parameters = ["fields": "email, first_name, last_name, picture.type(large)"] var userinfo: [String:String] = [:] FBSDKGraphRequest(graphPath: "me", parameters: parameters).start(completionHandler: { (connection, user, requestError) -> Void in if requestError != nil { print(requestError) } userinfo["email"] = user?["email"] as? String userinfo["firstname"] = user?["first_name"] as? String userinfo["lastname"] = user?["last_name"] as? String self.ref.child("users").child(uid).setValue(userinfo) }) } } 

AppDelegate

 import UIKit import Firebase import FirebaseDatabase import FBSDKCoreKit import FBSDKLoginKit @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { // Override point for customization after application launch. // Use Firebase library to configure APIs FIRApp.configure() FIRDatabase.database().persistenceEnabled = true return FBSDKApplicationDelegate.shanetworkingInstance() .application(application, didFinishLaunchingWithOptions: launchOptions) } func application(_ application: UIApplication, open url:URL,sourceApplication: String?, annotation: AnyObject) -> Bool { return FBSDKApplicationDelegate.shanetworkingInstance() .application(application, open: url, sourceApplication: sourceApplication, annotation: annotation) } func applicationWillResignActive(_ application: UIApplication) { // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. } func applicationDidEnterBackground(_ application: UIApplication) { // Use this method to release shanetworking resources, save user data, invalidate timers, and store enough application state information to restre your application to its current state in case it is terminated later. // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. } func applicationWillEnterForeground(_ application: UIApplication) { // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. } func applicationDidBecomeActive(_ application: UIApplication) { // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. FBSDKAppEvents.activateApp() } func applicationWillTerminate(_ application: UIApplication) { // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. } } 

Pantalla de ingreso al sistema

Pantalla de permiso

Aquí se debe llamar a CompleteComplete, pero no ocurre nada.

Los documentos de Facebook deben actualizarse.

Para iOS 9+, en lugar de usar:

 func application(_ application: UIApplication, open url:URL, sourceApplication: String?, annotation: AnyObject) -> Bool 

Deberías estar usando:

 func application(_ app: UIApplication, open url: URL, options: [String : AnyObject] = [:]) -> Bool { return FBSDKApplicationDelegate.shanetworkingInstance().application(application, openURL: url, sourceApplication: options[UIApplicationOpenURLOptionsSourceApplicationKey] as! String, annotation: options [UIApplicationOpenURLOptionsAnnotationKey]) } 

Parece que las opciones [UIApplicationOpenURLOptionsAnnotationKey] ya no funcionan. ahora tienes que hacerlo así: opciones [UIApplicationOpenURLOptionsKey.sourceApplication]

Esto es lo que me funciona

 func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool { return FBSDKApplicationDelegate.shanetworkingInstance() .application(app, open: url, sourceApplication: options[UIApplicationOpenURLOptionsKey.sourceApplication] as! String, annotation: options[UIApplicationOpenURLOptionsKey.annotation]) } 

La function anterior tuvo que ser modificada un poco. Tuve el mismo problema y me ha funcionado. Vea la function a continuación:

 func application(_ app: UIApplication, open url: URL, options: [String : AnyObject] = [:]) -> Bool { return FBSDKApplicationDelegate.shanetworkingInstance().application(app,open: url,sourceApplication: options[UIApplicationOpenURLOptionsSourceApplicationKey] as! String,annotation: options [UIApplicationOpenURLOptionsAnnotationKey]) }