无法将类型为"NSNull"(0×106a4f520) 的值强制转换为"NSDictionary"



这是我在github上的项目:https://github.com/alshfu86/Recipes

我有一个问题。如果我从 Firebase 数据库中删除某些内容,则会收到此错误:

无法将类型为"NSNull"(0×106a4f520)的值强制转换为"NSDictionary"(0×106a4ef58)。

在方法中:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "CategoryCell", for:indexPath) as! CategoryTableViewCell
    let rowData = self.data[indexPath.row] as! NSDictionary
    let title = rowData["title"] as! String
    cell.recipeLabel.text = title.uppercased()
    let imageUrl = rowData["youtubeID"] as! String
    let imageQuality = rowData["imageQuality"] as! String
    let urlPath = youtubeBaseImageURL + imageUrl + "/" + imageQuality + ".jpg"
    let url = URL(string: urlPath)
    cell.recipeImageView.kf.setImage(with: url)
    print("uString(describing: rl )path = (String(describing: url))")
    return cell
}

这是所有类:

import UIKit
import Kingfisher
class CategoryViewController: UIViewController,UITableViewDataSource,UITableViewDelegate {
    var data = [Any]()
    var categoryTitle = ""
    let youtubeBaseImageURL = "http://img.youtube.com/vi/"
    @IBOutlet weak var tableView: UITableView!
    //is the device landscape or portrait
    var isPortraid = true
    override func viewDidLoad() {
        super.viewDidLoad()
        let backButton = UIBarButtonItem(image: UIImage(named:"chevron"), style: UIBarButtonItemStyle.plain, target: self, action: #selector(back))
        self.navigationItem.leftBarButtonItem = backButton
        self.tableView.delegate = self
        self.title = categoryTitle
        print("data: (self.data)")
        //  loadAdmobBanner()
        NotificationCenter.default.addObserver(self, selector: #selector(MainViewController.orientationChanged), name: NSNotification.Name.UIDeviceOrientationDidChange, object: nil)
        if UIDevice.current.orientation.isLandscape {
            isPortraid = false
        }
    }
    func orientationChanged(){
        if UIDevice.current.orientation.isLandscape {
            isPortraid = false
        } else {
            isPortraid = true
        }
        tableView.reloadData()
    }
    @objc func back(){
        self.navigationController?.popViewController(animated: true)
    }
    func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return data.count
    }
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "CategoryCell", for:indexPath) as! CategoryTableViewCell
        let rowData = self.data[indexPath.row] as! NSDictionary
        let title = rowData["title"] as! String
        cell.recipeLabel.text = title.uppercased()
        let imageUrl = rowData["youtubeID"] as! String
        let imageQuality = rowData["imageQuality"] as! String
        let urlPath = youtubeBaseImageURL + imageUrl + "/" + imageQuality + ".jpg"
        let url = URL(string: urlPath)
        cell.recipeImageView.kf.setImage(with: url)
        print("uString(describing: rl )path = (String(describing: url))")
        return cell
    }
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        let storyboard = UIStoryboard(name: "Main", bundle: Bundle.main)
        let playerViewController = storyboard.instantiateViewController(withIdentifier: "PlayerViewController") as! PlayerViewController
        let rowData = self.data[indexPath.row] as! NSDictionary
        let youtubeUrl = rowData["youtubeID"] as! String
        playerViewController.urlPath = youtubeUrl
        let ingredients = rowData["ingredients"] as! String
        playerViewController.about = ingredients
        self.navigationController?.pushViewController(playerViewController, animated: true)
    }
    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        if isPortraid {return UIScreen.main.bounds.height/5
        } else {
            return UIScreen.main.bounds.height/5.2
        }
    }
    @IBAction func unwindToCategory(sender: UIStoryboardSegue){
    }

错误必须在此行:

let rowData = self.data[indexPath.row] as! NSDictionary

错误是数组包含一些空值(表示为 NSNull )。您可能应该进行条件转换,即:

if let rowData = self.data[indexPath.row] as? NSDictionary { 
    // do stuff here
}

或者,将data声明为字典数组:

var data = [NSDictionary]() 

然后在将它们分配给data之前过滤掉空值:

self.data = yourdatasource.filter { $0 is NSDictionary }

然后稍后只需检索元素:

let rowData = self.data[indexPath.row]  // do stuff here

最新更新