развертывание необязательного значения - PullRequest
0 голосов
/ 13 сентября 2018

Я пытаюсь войти в систему с помощью macbook, используя код, но продолжаю получать эту ошибку:

Тема 1: Неустранимая ошибка: неожиданно обнаружен ноль при развертывании необязательного значения

// API to log an user in
func login(userType: String, completionHandler: @escaping (NSError?) -> Void) {

    let path = "api/social/convert-token/"
    let url = baseURL!.appendingPathComponent(path)
    let params: [String: Any] = [
        "grant_type": "convert_token",
        "client_id": CLIENT_ID,
        "client_secret": CLIENT_SECRET,
        "backend": "facebook",
        "token": FBSDKAccessToken.current().tokenString,
        "user_type": userType
    ]

    Alamofire.request(url!, method: .post, parameters: params, encoding: URLEncoding(), headers: nil).responseJSON { (response) in

        switch response.result {
        case .success(let value):

            let jsonData = JSON(value)

            self.accessToken = jsonData["access_token"].string!
            self.refreshToken = jsonData["refresh_token"].string!
            self.expired = Date().addingTimeInterval(TimeInterval(jsonData["expire_in"].int!))

            completionHandler(nil)
            break

        case .failure(let error):
            completionHandler(error as NSError?)
            break
        }
    }

}

Ошибка относится к этой строке:

self.accessToken = jsonData["access_token"].string!

, а это код LoginViewController:

import UIKit
import FBSDKLoginKit

class LoginViewController: UIViewController {
    @IBOutlet weak var bLogin: UIButton!
    @IBOutlet weak var bLogout: UIButton!

    var fbLoginSuccess = false
    var userType: String = USERTYPE_CUSTOMER

    override func viewDidLoad() {
        super.viewDidLoad()

        if (FBSDKAccessToken.current() != nil) {
            bLogout.isHidden = false
            FBManager.getFBUserData(completionHandler: {

                self.bLogin.setTitle("Continue as \(User.currentUser.email!)", for: .normal)
                // self.bLogin.sizeToFit()
            })
        }
    }

    override func viewDidAppear(_ animated: Bool) {
        if (FBSDKAccessToken.current() != nil && fbLoginSuccess == true) {
            performSegue(withIdentifier: "CustomerView", sender: self)
        }
    }

    @IBAction func facebookLogout(_ sender: AnyObject) {
        APIManager.shared.logout { (error) in
            if error == nil {
                FBManager.shared.logOut()
                User.currentUser.resetInfo()

                self.bLogout.isHidden = true
                self.bLogin.setTitle("Login with Facebook", for: .normal)
            }
        }
    }

    @IBAction func facebookLogin(_ sender: AnyObject) {
        if (FBSDKAccessToken.current() != nil) {
            APIManager.shared.login(userType: userType, completionHandler:  { (error) in
                if error == nil {
                    self.fbLoginSuccess = true
                    self.viewDidAppear(true)
                }
            })
        } else {
            FBManager.shared.logIn(
                withReadPermissions: ["public_profile", "email"],
                from: self,
                handler: { (result, error) in
                    if (error == nil) {
                        FBManager.getFBUserData(completionHandler: {
                            APIManager.shared.login(userType: self.userType, completionHandler:  { (error) in
                                if error == nil {
                                    self.fbLoginSuccess = true
                                    self.viewDidAppear(true)
                                }
                            })
                        })
                    }
            })
        }
    }
}

Swift 3 Xcode 9 iOS 10.2

IПрочитайте несколько текстов, чтобы выяснить причины ошибок такого типа, но безуспешно.

Ответы [ 2 ]

0 голосов
/ 13 сентября 2018

Эта ошибка возникает, когда у вас есть символ ! ( принудительное развертывание ), то есть вы уверены, что данные будут там;но на самом деле данных там нет - это nil.

Попробуйте использовать оператор guard.Например:

guard let self.accessToken = jsonData["access_token"].string else {
    // log error message, if desired; then exit the function
    return
}

В качестве альтернативы вы могли бы использовать оператор if let:

if let self.accessToken = jsonData["access_token"].string {
    // do stuff if 'jsonData["access_token"].string' is valid
}
else {
    // do other stuff if 'jsonData["access_token"].string' is nil
}

Теперь, почему данные отсутствуют (nil) - это другой вопрос.Возможно, проверьте вашу JSON функцию, чтобы убедиться, что она правильно обрабатывает ответ JSON.Кроме того, убедитесь, что вы получаете действительный ответ:

guard let statusCode = (response as? HTTPURLResponse)?.statusCode, statusCode == 200 else {
    // handle a bad response code
    return
}

// handle the good response code stuff after the guard statement

Узнайте об использовании if let для обработки возможных значений nil в Руководстве по языку программирования Swift (Swift 4.2) в разделе Дополнительное связывание в разделе Основы .

Узнайте о guard утверждениях в Ранний выход в Control Flow раздел Руководства, а также в Заявления Справочник.

0 голосов
/ 13 сентября 2018

Прежде всего, это плохая практика - везде использовать принудительную развёртку (!).Старайтесь избегать этого, пока вам это действительно не понадобится и / или не узнаете, что вы делаете.Здесь вы используете SwiftyJSON.Это поможет вам извлечь данные из JSON удобным способом.Но вы не должны полагаться, что вы всегда получите правильный JSON из бэкэнда.Есть много причин, по которым он может вернуть неправильный JSON, и не было бы необходимого значения.Есть два варианта:

  1. Вы можете использовать .stringValue вместо .string - вместо nil

Вот хорошая статья, чтобы понять распаковку силы: https://blog.timac.org/2017/0628-swift-banning-force-unwrapping-optionals/

...