Swift Facebook 登录在 dispatch_once 中被破坏

Posted

技术标签:

【中文标题】Swift Facebook 登录在 dispatch_once 中被破坏【英文标题】:Swift Facebook login is broken in dispatch_once 【发布时间】:2017-01-26 17:51:36 【问题描述】:

我正在尝试集成一个 facebook 登录,嗯:

我从开发者 facebook 网站下载了FacebookSDKs-ios-4.18.0 2

之后,我在info.plist 文件中添加了下一个xml:

<key>CFBundleURLTypes</key>
    <array>
        <dict>
            <key>CFBundleURLSchemes</key>
            <array>
                <string>fb21200000000000</string>
            </array>
        </dict>
    </array>
    <key>FacebookAppID</key>
    <string>21200000000000</string>
    <key>FacebookDisplayName</key>
    <string>San Miguel Digital</string>
    <key>LSApplicationQueriesSchemes</key>
    <array>
        <string>fbapi</string>
        <string>fb-messenger-api</string>
        <string>fbauth2</string>
        <string>fbshareextension</string>
    </array>
    <key>NSPhotoLibraryUsageDescription</key>
    <string>human-readable reason for photo access</string>

AppDelegate.swift

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool 
        // Override point for customization after application launch.
        return FBSDKApplicationDelegate.sharedInstance().application(application, didFinishLaunchingWithOptions: launchOptions)
    

LoginViewController.swift

import Foundation
import UIKit
//import FacebookCore
//import FacebookLogin
import FBSDKCoreKit
import FBSDKLoginKit

class LoginViewController: UIViewController, FBSDKLoginButtonDelegate 

    override func viewDidLoad()
        super.viewDidLoad()
        /*let loginButton = LoginButton(readPermissions: [ .publicProfile, .email ])
        loginButton.center = view.center

        view.addSubview(loginButton)*/

        if(FBSDKAccessToken.current() == nil)
            print("Is not logged in")
        else
            print("Currently is logged in")
        

        let loginButton = FBSDKLoginButton()
        loginButton.readPermissions = ["public_profile", "email"]
        loginButton.center = self.view.center

        loginButton.delegate = self
        self.view.addSubview(loginButton)
    

    func loginButtonDidLogOut(_ loginButton: FBSDKLoginButton!) 
        print("Logged out")
    

    func loginButton(_ loginButton: FBSDKLoginButton!, didCompleteWith result: FBSDKLoginManagerLoginResult!, error: Error!) 
        if(error == nil)
            print("Successfully logged")
        else
            print(error.localizedDescription)
        
    




当我在 iphone 设备上执行应用程序时出现 facebook 登录按钮,但在日志错误中,我得到:

未登录 libc++abi.dylib:以未捕获的异常终止 NSException 类型的警告:无法加载任何 Objective-C 类 信息。这将显着降低类型的质量 可用的信息。

我做错了什么?

【问题讨论】:

terminating with uncaught exception of type NSException 错误总是比这条消息更多。发布完整的异常日志和回溯。 你可以试试 Product->Clean 首先,发布完整的错误信息。其次,我上个月实现了这个功能。我很确定至少应该向 AppDelegate 添加 3 个功能。但是好像你只加了一个(还是在这里发一个?) @EricZhang 这就是所有错误,我试图显示更多,但 xcode 不再显示。您可以粘贴您正在使用的其他方法吗?也许我正在原谅一些事情 【参考方案1】:

您可能错过了两个功能。您可以通过谷歌“iOS Facebook 登录”找到详细信息,然后选择第一个链接。我所做的完全按照指示进行。

    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 application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool 

        return FBSDKApplicationDelegate.sharedInstance().application(app, open: url, options: options)
    

我在func loginButton 中检查了你的实现。有一个样本可能是更好的做法:

func loginButton(_ loginButton: FBSDKLoginButton!, didCompleteWith result: FBSDKLoginManagerLoginResult!, error: Error!) 
    guard error == nil else 
        print("Login Error: \(error)" )
            return
    

    if let token = FBSDKAccessToken.current()     
        if let req = FBSDKGraphRequest(graphpath: "me", parameters: ["fields":"name"], tokenString: token.tokenString, version: nil, httpMethod: "GET")         
            req.start()  
                (conn, result, err) in
                if ((err) != nil) 
                    print("Error: \(err)")
                
                else 
                    let data:[String:AnyObject] = result as! [String : AnyObject]
                    print("username: " + data["name"])
                
            
        
    

【讨论】:

问题仍然存在__FuncPtr void (*)() (FBSDKCoreKit__46+[FBSDKInternalUtility isFacebookAppInstalled]_block_invoke at FBSDKInternalUtility.m:493) 0x0000000100e9e48c` dispatch_once(&amp;onceToken, ^ [FBSDKInternalUtility checkRegisteredCanOpenURLScheme:FBSDK_CANOPENURL_FACEBOOK]; ); 这是代码...让我检查一下... 顺便问一下,你确定 fb21200000000000 是你的 CFBundleURLSchemes 吗? 好的。我检查了几个 CFBundleURLSchemes,fb21200000000000 非常奇怪...... @Eic Zhang 是一个示例 ID,请勿发布真实 ID

以上是关于Swift Facebook 登录在 dispatch_once 中被破坏的主要内容,如果未能解决你的问题,请参考以下文章

在 Swift 中使用 Parse 登录 Facebook

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

使用 Swift 登录 Facebook 后加载另一个 ViewController

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

解析 Facebook 登录 Swift 3.0

在 Swift 中登录 Facebook。 “收到未知方案:授权”