在展开可选值时意外发现 nil,出现这样的错误

Unexpectedly found nil while unwrapping an Optional value ,Getting error like this

我的要求:我将在 table 视图的 table view.On 顶部有一个聊天详细信息列表,将有一个使用文本的搜索功能 field.based 在用户的唯一 ID 上,搜索应该得到 done.if 没有与用户输入的唯一 ID 的聊天,然后它必须重定向到另一个名为 chatcreatepage 的屏幕。当我们搜索聊天时,我们将使用一个名为 FIND API 的 api 并且在该 FIND API 中有一个聊天字典,如果它为空,那么创建聊天将得到 called.If 聊天词典不为零则需要在聊天列表 table 视图中显示该聊天详细信息。当聊天列表页面加载时,我们将调用聊天列表 Api.when 我们通过在文本字段中输入唯一 ID 来搜索聊天,我们将获得输入的唯一 ID 和唯一 ID 详细信息的相应详细信息我们必须在 table 视图中显示。

这是任务,我已经完成了,直到聊天列表显示在 table.FIND API 集成也是 done.When 我正在重新加载搜索结果的数据(找到 api 响应),我在 "var recepient = dict["recipient"] as! [String:Any]" 的行收到类似 "Unexpectedly found nil while unwrapping an Optional value" 的致命错误。如果有人帮助我解决它,那么 advance.I 中的 great.Thank 会提供下面的代码。

    import UIKit
        import Alamofire
        import SwiftyJSON
        import SDWebImage
        class ChatlistViewController: UIViewController{
             var pro = [[String:Any]]()
             var dict:[String:Any]!
             var idd = ""
             var id = ""
            var chatt:Dictionary = [String:Any]()
            var searchActive : Bool = false
            var filtered:[String] = []
            var data:[String] = []

            @IBOutlet weak var searchtext: UITextField!
            @IBOutlet weak var chatlisttable: UITableView!
            override func viewDidLoad() {
                super.viewDidLoad()

                       apicall()

            }



            func apicall(){

                let acce:String = UserDefaults.standard.string(forKey: "access-tokenn")!
                        print(acce)

                        let headers:HTTPHeaders = ["Authorization":"Bearer \(acce)","Content-Type":"application/X-Access-Token"]

                Alamofire.request(Constants.Chatlist, method: .get, encoding: URLEncoding.default, headers: headers).responseJSON {  response in
                    switch response.result {
                    case .success:
                        print(response)
                        if response.result.value != nil{
                            var maindictionary = NSDictionary()
                            maindictionary = response.result.value as! NSDictionary
                            print(maindictionary)

                            var userdata = NSDictionary()
                            userdata = maindictionary.value(forKey: "data") as! NSDictionary

                            var productsdetails = [[String:Any]]()
                            productsdetails = userdata.value(forKey: "chat") as! [[String:Any]]
                            self.pro = productsdetails
                                 print(self.pro)
                                   self.chatlisttable.reloadData()

                        }else{
                            let Alertcontroller = UIAlertController(title: "Alert", message: "No data found ", preferredStyle: .alert)
                            let CancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
                            Alertcontroller.addAction(CancelAction)
                            self.present(Alertcontroller, animated: true, completion: nil)
                        }
                                break
                            case .failure(let error):

                                print(error)
                            }
                        }


            }

            func searchapicall(){
                idd = searchtext.text!
               let acce:String = UserDefaults.standard.string(forKey: "access-tokenn")!
                print(acce)

                let headers:HTTPHeaders = ["Authorization":"Bearer \(acce)","Content-Type":"application/X-Access-Token"]
                print((Constants.Chatlistsearch)+(idd))
                Alamofire.request((Constants.Chatlistsearch+idd), method: .get, encoding: URLEncoding.default, headers: headers).responseJSON {  response in
                    switch response.result {
                    case .success:
                        //print(response)
                        if response.result.value != nil{
                            var maindictionary = NSDictionary()
                            maindictionary = response.result.value as! NSDictionary

                            var chat:Dictionary = maindictionary.value(forKey: "data") as! [String:Any]

                            var chattt:Dictionary = chat["chat"] as! [String:Any]

                            if (chattt != nil) {

                               // print("Find Action")

                                self.chatt = chat["user"] as! [String:Any]
                                print(self.chatt)
                                self.pro = [self.chatt]
                               // print(self.pro)
                             self.chatlisttable.reloadData()

                            }else{
                                let viewc = UIStoryboard.init(name: "Main", bundle: Bundle.main).instantiateViewController(withIdentifier: "ChatViewController") as? ChatViewController
                                self.navigationController?.pushViewController(viewc!, animated: true)
                            }

                        }else{
                            let Alertcontroller = UIAlertController(title: "Alert", message: "No data found on this unique id", preferredStyle: .alert)
                            let CancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)
                            Alertcontroller.addAction(CancelAction)
                            self.present(Alertcontroller, animated: true, completion: nil)
                        }
                        break
                    case .failure(let error):

                        print(error)
                    }
                }

            }




        }


        extension ChatlistViewController: UITextFieldDelegate{

            func textFieldShouldReturn(_ textField: UITextField) -> Bool {

                self.searchapicall()

                return true
            }

        }

        extension ChatlistViewController: UITableViewDataSource,UITableViewDelegate {

            func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
                if (searchActive == false){
                return self.pro.count
                }else{
                    return 1
                }
            }

            func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

                var cell = chatlisttable.dequeueReusableCell(withIdentifier: "ChatlistTableViewCell", for: indexPath) as! ChatlistTableViewCell

                if (searchActive == false){

                dict = pro[indexPath.row]
                var recepient = dict["recipient"] as! [String:Any]
                print(recepient)

                var name = recepient["name"] as! String
                print(name)
                id = recepient["unique_id"] as! String
                print(id)
                var image = recepient["avatar"] as! String
                print(image)
                cell.namelbl.text = name
                cell.idlbl.text = id
                cell.imageView!.sd_setImage(with: URL(string:image), placeholderImage: UIImage(named: "Mahi.png"))

                }else{

                    cell.namelbl.text = chatt["name"] as! String
                    cell.idlbl.text = chatt["unique_id"] as! String
                }

                return cell
               self.chatlisttable.reloadData()

            }

        }

    //Response format

    {
        "success": 1,
        "status": 200,
        "data": {
            "user": {
                "id": 3,
                "unique_id": "10002",
                "name": "nani",
                "avatar": "https://www.planetzoom.co.in/storage/user/avatar/AkgcUFF3QIejMhZuLF4OXnSFHjxNAOo4FuXV3Mgi.jpeg"
            },
            "chat": null
        }
    }


//Response with chat dictionary data

{
    "success": 1,
    "status": 200,
    "data": {
        "user": {
            "id": 8,
            "unique_id": "10007",
            "name": "Mahitha",
            "avatar": "https://www.planetzoom.co.in/storage/user/avatar/cZt9yQlBzIEewOdQ1lYZhl3dFiOv2k3bxG7HLOzR.jpeg"
        },
        "chat": {
            "id": 4,
            "status": 0,
            "created_at": "2019-02-27 12:26:24",
            "updated_at": "2019-02-27 12:26:24"
        }
    }
}

由于我在您的回复中看到 chat 为零,因此您应该如下更新代码以获取聊天详细信息

if var productsdetails = userdata.value(forKey: "chat") as? [[String:Any]] {
    // Code to display chat
} else {
    // Code to display nil error
}

希望这能解决您的问题。

我想向您提供两个反馈:

  1. 请尽量养成避免forced castingforced unwrap的习惯。

  2. 使用驼峰命名规则

因此,您可以更改

var recepient = dict["recipient"] as! [String:Any]

 guard let recepient = dict["recipient"] as? [String:Any] else {return cell}

在加载 tableView 之前你可以有一个条件的类似方法

if let productsDetails = userdata.value(forKey: "chat") as? [[String:Any]] {
    // write code 
} else {
    // write code to handle else
}

根据您的回复聊天为空。所以 productsdetails = userdata.value(forKey: "chat") as! [[String:Any]] 你这样做了,你在键 'chat' 的 userdefaults 中设置了一个空值,你正在检索空值 [[String : Any]]

所以你必须使用方块

来检查这个
if let productsdetails = userdata.value(forKey: "chat") as? [[String:Any]] {
    // write code that for chat
} else {
    // write code for chat is null 
}

这个叫做Optional Chaining,你可能会发现这个link

Optional chaining is a process for querying and calling properties, methods, and subscripts on an optional that might currently be nil. If the optional contains a value, the property, method, or subscript call succeeds; if the optional is nil, the property, method, or subscript call returns nil. Multiple queries can be chained together, and the entire chain fails gracefully if any link in the chain is nil.

或者您可以使用 guard 语句

来解决
guard let productsdetails = userdata.value(forKey: "chat") as? [[String:Any]] else {
    // write code for chat is null 
    return 
}

\ write code that for chat
\ you can use productsdetails variable here