展开一个可选值 [英] unwrapping an Optional value

查看:81
本文介绍了展开一个可选值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用代码登录到macbook,但我不断遇到此错误:

I am trying to login with macbook using code but I keep on getting this error:


线程1:致命错误:意外发现nil,同时展开一个可选值

Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value



// 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代码:

and this is LoginViewController code:

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

Swift 3 Xcode 9 iOS 10.2

我读了几篇文本以找出导致这种类型错误的原因,但不能成功。

I read several texts to find out the causes of this type of error but not succeed.

推荐答案

首先,这样做是一种不好的做法在任何地方都用力打开(!)。尽量避免使用它,直到您真正需要它和/或知道您在做什么。在这里,您使用SwiftyJSON。它可以帮助您方便地从JSON提取数据。但是您不应该依赖于始终从后端获取正确的JSON。有很多原因导致它可以返回错误的JSON,并且不需要值。有两个选项:

First of all, it is a bad practice to use force unwrap (!) everywhere. Try to avoid it, until you really need it and/or know what are you doing. Here you use SwiftyJSON. It helps you to extract data from JSON in a convenient way. But you shouldn't rely, that you will always get proper JSON from the backend. There are many reasons why it can return wrong JSON and there would not be needed value. There are two options:


  1. 您可以使用 .stringValue 代替 .string -它会返回一个空字符串,而不是 nil

  2. 这样: if let token = jsonData [ access_token]。string {...} 甚至使用 guard 声明

  1. You can use .stringValue instead of .string - it will return an empty string instead of nil
  2. You can do in this way: if let token = jsonData["access_token"].string {...} or even use guard statement

这里是一篇很好的文章,可以理解强制展开:> https://blog.timac.org/2017/0628-swift-banning-force-unwrapping-optionals/

Here is a good article to understand force unwrapping: https://blog.timac.org/2017/0628-swift-banning-force-unwrapping-optionals/

这篇关于展开一个可选值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆