这是我在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){
}
答案 0 :(得分:0)
错误必须在这一行:
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