迁移到 Swift 3 时,Facebook 登录不会返回应用程序

Posted

技术标签:

【中文标题】迁移到 Swift 3 时,Facebook 登录不会返回应用程序【英文标题】:Facebook Login not going back to App when migrated to Swift 3 【发布时间】:2016-06-19 03:21:25 【问题描述】:

我创建了一个用户使用 Facebook 登录按钮登录的示例应用程序。

登录后,我会在登录屏幕上显示用户名和电子邮件。 它正在使用 Swift 2.3。 一旦我迁移到 Swift 3,它就停止工作了。

第1步:使用Facebook登录按钮登录 第 2 步:允许电子邮件和个人资料的权限 Step3:在这里它应该回到屏幕 1。但它没有。 附上我点击“确定”按钮时得到的日志。

更新 1:应用在 ios 9.3 上运行良好。该问题仅出现在 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

这是我的代码。

视图控制器

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.
    

    //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 credential = FIRFacebookAuthProvider.credential(withAccessToken: FBSDKAccessToken.current().tokenString)
                // Do work
                print("logged in ")
                FIRAuth.auth()?.signIn(with: credential, 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.sharedInstance()
            .application(application, didFinishLaunchingWithOptions: launchOptions)
    

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

    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()
    

Login Screen

【问题讨论】:

浏览 swift 3.0 迁移文档即可。 是的,我检查过但找不到任何东西。今天我尝试在 iOS 9.3 上运行它,它运行良好。问题在于在 iOS 10 设备上运行 我们也看到了这个问题,它快把我们逼疯了! 关于这个问题的任何更新?我也有。但是当我在 iphone 5 的模拟器上运行它时......对于 iphone 8 它运行良好 【参考方案1】:

Facebook 文档需要更新。

对于 iOS 9+,而不是使用:

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

你应该使用:

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

【讨论】:

很好的发现。但这并没有改变我的这种行为。【参考方案2】:

似乎 options[UIApplicationOpenURLOptionsAnnotationKey] 不再起作用了。现在你必须这样做:options[UIApplicationOpenURLOptionsKey.sourceApplication]

这对我有用

func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool 

    return FBSDKApplicationDelegate.sharedInstance()
                                   .application(app, 
                                               open: url,
                                  sourceApplication: options[UIApplicationOpenURLOptionsKey.sourceApplication] as! String,
                                         annotation: options[UIApplicationOpenURLOptionsKey.annotation])

【讨论】:

【参考方案3】:

上面的函数需要稍微改动一下。我有同样的问题,它对我有用。请看下面的函数:

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

【讨论】:

以上是关于迁移到 Swift 3 时,Facebook 登录不会返回应用程序的主要内容,如果未能解决你的问题,请参考以下文章

使用 Facebook 应用程序时 Facebook 登录回调不起作用 - Swift

Facebook 使用 Swift 和 Parse 登录到主 ViewController

Swift - 立即解析 Facebook 登录默认为用户取消登录

无法使用 Facebook SDK IOS Swift 登录 [重复]

使用 Swift 和 Parse 获取 Facebook UserData 时出现致命错误

保存电子邮件地址 Facebook + Parse (Swift)