Reputation:
I am facing the issue of passing the data from HomeViewController to PostDetailViewController, I have checked the classes connected to the View Controllers are correct, class connected to the XIB file is PostTableViewCell,
and still getting this error of
'NSUnknownKeyException', reason: '[ setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key description
upon clicking the tablecell
HOMEVIEWCONTROLLER
class HomeViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
var tableView:UITableView!
var posts = [Post]()
var db: Firestore!
var postKey:String = ""
private var documents: [DocumentSnapshot] = []
//public var posts: [Post] = []
private var listener : ListenerRegistration!
override func viewDidLoad() {
super.viewDidLoad()
db = Firestore.firestore()
self.navigationController?.navigationBar.isTranslucent = false
tableView = UITableView(frame: view.bounds, style: .plain)
let cellNib = UINib(nibName: "PostTableViewCell", bundle: nil)
tableView.register(cellNib, forCellReuseIdentifier: "postCell")
tableView.backgroundColor = UIColor(white: 0.90,alpha:1.0)
view.addSubview(tableView)
var layoutGuide:UILayoutGuide!
if #available(iOS 11.0, *) {
layoutGuide = view.safeAreaLayoutGuide
} else {
// Fallback on earlier versions
layoutGuide = view.layoutMarginsGuide
}
tableView.leadingAnchor.constraint(equalTo: layoutGuide.leadingAnchor).isActive = true
tableView.topAnchor.constraint(equalTo: layoutGuide.topAnchor).isActive = true
tableView.trailingAnchor.constraint(equalTo: layoutGuide.trailingAnchor).isActive = true
tableView.bottomAnchor.constraint(equalTo: layoutGuide.bottomAnchor).isActive = true
tableView.delegate = self
tableView.dataSource = self
tableView.reloadData()
retrieveAllPosts()
//checkForUpdates()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
@IBAction func handleLogout(_ sender:Any) {
try! Auth.auth().signOut()
self.dismiss(animated: false, completion: nil)
}
func retrieveAllPosts(){
let postsRef = Firestore.firestore().collection("posts").limit(to: 50)
postsRef.getDocuments { (snapshot, error) in
if let error = error {
print(error.localizedDescription)
} else {
if let snapshot = snapshot {
for document in snapshot.documents {
let data = document.data()
// self.postKey = document.documentID
let username = data["username"] as? String ?? ""
let postTitle = data["postTitle"] as? String ?? ""
let postcategory = data["postcategory"] as? String ?? ""
let postContent = data["postContent"] as? String ?? ""
let newSourse = Post( _documentId: document.documentID, _username: username, _postTitle: postTitle, _postcategory: postcategory, _postContent: postContent)
self.posts.append(newSourse)
print(self.postKey)
}
self.tableView.reloadData()
}
}
}
}
/* postsRef.getDocuments() { (querySnapshot, err) in
if let err = err {
print("Error getting documents: \(err)")
} else {
for document in querySnapshot!.documents {
print("\(document.documentID) => \(document.data())")
self.posts = querySnapshot!.documents.flatMap({Post(dictionary: $0.data())})
DispatchQueue.main.async {
self.tableView.reloadData()
}
}
}
}*/
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
tableView.reloadData()
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return posts.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "postCell", for: indexPath) as! PostTableViewCell
cell.set(post: posts[indexPath.row])
return cell
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let post = self.posts[indexPath.row]
//print("row selected: \(indexPath.row)")
//Swift.print(post._documentId!)
let postKey = post._documentId
let postName = post._username
print(postKey! + postName!)
performSegue(withIdentifier: "toDetailView", sender: indexPath)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
//segue.forward(posts, to: segue.destination)
guard let details = segue.destination as? PostDetailViewController,
let index = tableView.indexPathForSelectedRow?.row
else {
return
}
details.detailView = posts[index]
}
}
POSTTABLEVIEWCELL
class PostTableViewCell: UITableViewCell {
@IBOutlet weak var usernameLabel: UILabel!
@IBOutlet weak var profileImageView: UIImageView!
@IBOutlet weak var subtitleLabel: UILabel!
@IBOutlet weak var postTextLabel: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
// profileImageView.layer.cornerRadius = profileImageView.bounds.height / 2
// profileImageView.clipsToBounds = true
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
func set(post:Post) {
usernameLabel.text = post._username
postTextLabel.text = post._postTitle
subtitleLabel.text = post._postcategory
}
}
POST DETAIL VIEW CONTROLLER
class PostDetailViewController: UIViewController {
@IBOutlet var usernamelabel: UILabel!
@IBOutlet var posttitlelabel: UILabel!
@IBOutlet var postIdlabel: UILabel!
// @IBOutlet var description: UILabel!
@IBOutlet var postcategorylabel: UILabel!
var detailView: Post?
var postId:String = ""
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
postIdlabel?.text = detailView?._documentId
posttitlelabel?.text = detailView?._postTitle
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using segue.destination.
// Pass the selected object to the new view controller.
}
*/
}
Upvotes: 1
Views: 71
Reputation: 2916
This situations usually happens when you have already set IBOutlet in your XIB file and you comment out it's connecting outlets in code.
Here in your case, In your PostDetailViewController
// @IBOutlet var description: UILabel!
You have commented the description Label, but IBOutlet is still connected in your XIB file.
So, Look for your XIB file and checkout for active IBOutlet Connections and remove it for description label, Clean, Build and Run.
Hope it helps.
Upvotes: 0