Приложение аварийно завершает работу после входа пользователя в 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 не возвращает адрес электронной почты. Я продолжу поиски.


person Nick    schedule 04.02.2016    source источник
comment
Пожалуйста, поставьте точку останова исключения и попробуйте отладить, где на самом деле произошел сбой. Это может привести к сбою из-за какого-то нулевого значения.   -  person rushisangani    schedule 04.02.2016
comment
Вы должны иметь привычку НЕ публиковать свои токены API публично.   -  person xoudini    schedule 04.02.2016
comment
Спасибо @dzk, я исправил это.   -  person Nick    schedule 05.02.2016
comment
@iOSEnthusiatic проблема в том, что я не могу воспроизвести ошибку на своей стороне, поэтому добавление точек останова мало что даст.   -  person Nick    schedule 05.02.2016
comment
@Nick, вы всегда можете попробовать создать учетную запись на Facebook, в которой отсутствуют некоторые параметры, которые вы принудительно разворачиваете в своем коде, и войти в свое приложение с этой учетной записью. Вероятно, сбои происходят из-за отсутствия параметров в вашем вызове.   -  person xoudini    schedule 06.02.2016


Ответы (1)


Я понял. Частично проблема заключалась в том, что Facebook не возвращал адрес электронной почты для некоторых пользователей, поэтому я проверил это, и если он не возвращал электронное письмо, я создал его с их идентификатором Facebook, чтобы помочь им пройти процесс входа в систему (fbid@ facebook.mywebsite.com).

Другая часть проблемы заключалась в том, что некоторые пользователи вошли на мой веб-сайт, используя адрес электронной почты, который также был назначен их учетной записи Facebook, и попытались войти в систему через Facebook в приложении. Я исправил это, объединив их информацию Facebook с их существующей учетной записью во время процесса авторизации, если существующая учетная запись найдена.

person Nick    schedule 15.02.2016