用户使用 Facebook 登录后应用程序崩溃

App crashes after user logs in with Facebook

我将我的应用程序放到了 App Store。在我这边一切都很好,显然在审稿人这边。

应用上线后,一些用户反映在使用 Facebook 登录后立即崩溃。这是我认为崩溃的代码(运行 用户使用 Facebook 登录后):

import UIKit
import FBSDKCoreKit
import FBSDKLoginKit

protocol getUserDataDelegate {
    func gotData()
}

public var userEmailForMixpanel = ""
public var userNameForInvites = ""

class GetUserData: NSObject {

var facebookid:String = ""
var userEmail:String = ""
var userFirstName:String = ""
var userLastName: String = ""
var userGender:String = ""
var userBirthday:String = ""
var delegate = getUserDataDelegate?()

func returnUserData() {
    let graphRequest : FBSDKGraphRequest = FBSDKGraphRequest(graphPath:  "me", parameters: ["fields": "id, email, first_name, last_name, gender, birthday"])
    graphRequest.startWithCompletionHandler({ (connection, result, error) -> Void in

        if ((error) != nil)
        {
            print("Error: \(error)")
        }
        else
        {
            self.facebookid = (result.valueForKey("id") as? String)!
            self.userEmail = (result.valueForKey("email") as? String)!
            self.userFirstName = (result.valueForKey("first_name") as? String)!
            self.userLastName = (result.valueForKey("last_name") as? String)!
            self.userGender = (result.valueForKey("gender") as? String)!
            //self.userBirthday = (result.valueForKey("birthday") as? String)!

            userEmailForMixpanel = self.userEmail
            userNameForInvites = self.userFirstName

            NSUserDefaults.standardUserDefaults().setValue(userEmailForMixpanel, forKey: "userEmail")
            NSUserDefaults.standardUserDefaults().setValue(userNameForInvites, forKey: "userName")
            NSUserDefaults.standardUserDefaults().synchronize()

            Mixpanel.sharedInstanceWithToken("abdc")
            let mixpanel = Mixpanel.sharedInstance()
            mixpanel.registerSuperProperties(["Gender":self.userGender])

            print(self.facebookid)
            print(self.userEmail)
            print(self.userFirstName)
            print(self.userLastName)
            print(self.userGender)
            //print(self.userBirthday)

            self.checkIfUserExists()
        }
    })
}

func checkIfUserExists() {

    showTutorial = true

    let url:NSURL = NSURL(string: "url")!

    let task:NSURLSessionDataTask = NSURLSession.sharedSession().dataTaskWithURL(url) { (data:NSData?, response:NSURLResponse?, error:NSError?) -> Void in

        let userTokenDataDictionary:NSDictionary = (try! NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers)) as! NSDictionary

        if userTokenDataDictionary ["token"] != nil {
            userAccessToken = (userTokenDataDictionary["token"] as? String)!
            NSUserDefaults.standardUserDefaults().setValue(userAccessToken, forKey: "userAccessToken")
            NSUserDefaults.standardUserDefaults().synchronize()
            print("Token for Existing User:\(userAccessToken)")
            self.finishedGettingData()
        }

        if userTokenDataDictionary ["error"] != nil {
            userAccessToken = (userTokenDataDictionary["error"] as? String)!
            print(userAccessToken)
            print("User needs to be created")
            self.createNewUserFromFacebook()
        }
    }
    task.resume()
}

func createNewUserFromFacebook() {

    let url:NSURL = NSURL(string: "url")!

    print(url)

    let task:NSURLSessionDataTask = NSURLSession.sharedSession().dataTaskWithURL(url) { (data:NSData?, response:NSURLResponse?, error:NSError?) -> Void in

        let userTokenDataDictionary:NSDictionary = (try! NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers)) as! NSDictionary

        if userTokenDataDictionary ["token"] != nil {
            userAccessToken = (userTokenDataDictionary["token"] as? String)!
            NSUserDefaults.standardUserDefaults().setValue(userAccessToken, forKey: "userAccessToken")
            NSUserDefaults.standardUserDefaults().synchronize()
        }

        if userTokenDataDictionary ["error"] != nil {
            userAccessToken = (userTokenDataDictionary["error"] as? String)!
            print(userAccessToken)
        }

        print("Token for New User:\(userAccessToken)")
        self.finishedGettingData()
    }
    task.resume()
}

func checkIfUserHasUsedListenerApp() {

    let accessToken = NSUserDefaults.standardUserDefaults().stringForKey("userAccessToken")!

    let url:NSURL = NSURL(string: "url")!

    print(url)

    let task:NSURLSessionDataTask = NSURLSession.sharedSession().dataTaskWithURL(url) { (data:NSData?, response:NSURLResponse?, error:NSError?) -> Void in

        let adDataDict:NSDictionary = (try! NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers)) as! NSDictionary

        if adDataDict ["used_ListenerApp"] != nil {
            let responseCode = adDataDict.valueForKey("used_ListenerApp") as! Bool
            print(responseCode)
            if responseCode == false {
                Mixpanel.sharedInstanceWithToken("abc")
                let mixpanel = Mixpanel.sharedInstance()
                mixpanel.track("New User Signed Up", properties: ["distinct_id":userEmailForMixpanel])
            }
            if responseCode == true {
                return
            }
        }
    }
    task.resume()
}

func finishedGettingData() {
    self.checkIfUserHasUsedListenerApp()

    Mixpanel.sharedInstanceWithToken("abc")
    let mixpanel = Mixpanel.sharedInstance()
    mixpanel.track("User Logged In", properties: ["distinct_id":userEmailForMixpanel])

    if let actualdelegate = self.delegate {
        actualdelegate.gotData()
    }
  }
}

这只是部分用户崩溃,并非全部。我什至尝试创建一个循环,通过这段代码生成一堆用户数据 运行,但我无法复制崩溃。

如有任何建议,我们将不胜感激。

更新

看来这与 Facebook 未返回电子邮件地址有关。不过我会继续寻找的。

我明白了。部分问题是 Facebook 没有 return 某些用户的电子邮件地址,所以我检查了一下,如果它没有 return 电子邮件,我就用他们的 Facebook ID 创建了一个让他们通过登录过程 (fbid@facebook.mywebsite.com).

问题的另一部分是一些用户使用同样分配给他们 Facebook 帐户的电子邮件地址登录我的网站,并尝试在应用程序上使用 Facebook 登录。如果找到现有帐户,我通过在授权过程中将他们的 Facebook 信息与现有帐户合并来解决此问题。