Reputation: 525
I'm a beginner, so sorry if it's a dumb issue. I'm trying to create a table view that loads data from the Firebase Realtime DB API. I think I set it up right, it doesn't throw any errors or crash. However, it is also not calling the cellsForRowAt
method. Thus, it's not displaying any cells. It shows the line, and they can kind of be scrolled and they spring around, but they are the default width. It does call the numberOfRowsInSection
method though, I've verified this through console logs. Here is the entire view controller...
class UpcomingTableViewController: UITableViewController {
var upcomingPosts = [upcomingPost]()
override func viewDidLoad() {
super.viewDidLoad()
print("loaded")
let ref: DatabaseReference
ref = Database.database().reference()
let dbref = ref.child("auctionHandler").child("upcoming")
dbref.queryOrderedByKey().observe(DataEventType.childAdded, with: { (snapshot) in
let snapshot = snapshot.value as! NSDictionary
let shoe = snapshot["name"] as! String
let colorway = snapshot["colorway"] as! String
let date = snapshot["date"] as! String
let newPost = upcomingPost(shoe: shoe, colorway: colorway, date: date)
self.upcomingPosts.insert(newPost, at: 0)
//print(self.upcomingPosts)
self.tableView.reloadData()
})
}
override func viewDidAppear(_ animated: Bool) {
self.tableView.reloadData()
}
override func numberOfSections(in tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 0
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
print(upcomingPosts.count)
return upcomingPosts.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
print("ran")
let cell = tableView.dequeueReusableCell(withIdentifier: "upcoming", for: indexPath)
let shoe = cell.viewWithTag(1) as! UILabel
shoe.text = upcomingPosts[indexPath.row].shoe
let colorway = cell.viewWithTag(2) as! UILabel
colorway.text = upcomingPosts[indexPath.row].colorway
print(cell)
print("------")
return cell
}
}
Thanks in advance for any help!
UPDATE: I've removed numberOfSections
, it throws this crash
(
0 CoreFoundation 0x00007fff23c4f02e __exceptionPreprocess + 350
1 libobjc.A.dylib 0x00007fff50b97b20 objc_exception_throw + 48
2 CoreFoundation 0x00007fff23c4ebf9 -[NSException raise] + 9
3 Foundation 0x00007fff256f2ef3 -[NSObject(NSKeyValueCoding) setValue:forKey:] + 325
4 UIKitCore 0x00007fff47d3410f -[UIView(CALayerDelegate) setValue:forKey:] + 171
5 UIKitCore 0x00007fff474b9a32 -[UIRuntimeOutletConnection connect] + 109
6 CoreFoundation 0x00007fff23c3b052 -[NSArray makeObjectsPerformSelector:] + 242
7 UIKitCore 0x00007fff474b6bda -[UINib instantiateWithOwner:options:] + 2190
8 UIKitCore 0x00007fff47a3a229 -[UITableView _dequeueReusableViewOfType:withIdentifier:] + 610
9 UIKitCore 0x00007fff47a3a865 -[UITableView _dequeueReusableCellWithIdentifier:forIndexPath:usingPresentationValues:] + 496
10 UIKitCore 0x00007fff47a3a641 -[UITableView dequeueReusableCellWithIdentifier:forIndexPath:] + 91
11 Sole Club 0x000000010e306031 $s9Sole_Club27UpcomingTableViewControllerC05tableE0_12cellForRowAtSo07UITableE4CellCSo0lE0C_10Foundation9IndexPathVtF + 577
12 Sole Club 0x000000010e3068c5 $s9Sole_Club27UpcomingTableViewControllerC05tableE0_12cellForRowAtSo07UITableE4CellCSo0lE0C_10Foundation9IndexPathVtFTo + 165
13 UIKitCore 0x00007fff47a5468e -[UITableView _createPreparedCellForGlobalRow:withIndexPath:willDisplay:] + 781
14 UIKitCore 0x00007fff47a1d667 -[UITableView _updateVisibleCellsNow:] + 3081
15 UIKitCore 0x00007fff47a3d78b -[UITableView layoutSubviews] + 194
16 UIKitCore 0x00007fff47d34d01 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 2478
17 QuartzCore 0x00007fff2b138d41 -[CALayer layoutSublayers] + 255
18 QuartzCore 0x00007fff2b13ef33 _ZN2CA5Layer16layout_if_neededEPNS_11TransactionE + 517
19 QuartzCore 0x00007fff2b14a86a _ZN2CA5Layer28layout_and_display_if_neededEPNS_11TransactionE + 80
20 QuartzCore 0x00007fff2b0917c8 _ZN2CA7Context18commit_transactionEPNS_11TransactionEd + 324
21 QuartzCore 0x00007fff2b0c6ad1 _ZN2CA11Transaction6commitEv + 643
22 QuartzCore 0x00007fff2b0c743a _ZN2CA11Transaction17observer_callbackEP19__CFRunLoopObservermPv + 76
23 CoreFoundation 0x00007fff23bb1617 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 23
24 CoreFoundation 0x00007fff23bac0ae __CFRunLoopDoObservers + 430
25 CoreFoundation 0x00007fff23bac72a __CFRunLoopRun + 1514
26 CoreFoundation 0x00007fff23babe16 CFRunLoopRunSpecific + 438
27 GraphicsServices 0x00007fff38438bb0 GSEventRunModal + 65
28 UIKitCore 0x00007fff4784fb48 UIApplicationMain + 1621
29 Sole Club 0x000000010e3236bb main + 75
30 libdyld.dylib 0x00007fff51a1dc25 start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
UPDATE: Error message header
*** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<UITableViewCell 0x7fdc62e847f0> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key colorway.'
*** First throw call stack:
Upvotes: 0
Views: 583
Reputation: 362
First of call it's not a good practice to access cell views by tags, other is not needed to reload tableView in 'viewDidAppear' method also you should call 'super.viewDidAppear(animated)' when you override 'viewDidAppear' method.
Cell identifier should be same like you set in Storyboard when you want to dequeue the cell from tableView.
TableView should return at least one section, or you can remove numberOfSections default is one.
class UpcomingTableViewController: UITableViewController {
//MARK: - Private properties
private var upcomingPosts = [upcomingPost]() //Name convention of swift for models is CamelCase so upcomingPost should be UpcomingPost
private var ref: DatabaseReference!
override func viewDidLoad() {
super.viewDidLoad()
initializeFirebaseDatabase()
fetchUpCommingPostsFromFirebase()
}
func initializeFirebaseDatabase() {
ref = Database.database().reference()
}
private func fetchUpCommingPostsFromFirebase() {
let dbref = ref.child("auctionHandler").child("upcoming")
dbref.queryOrderedByKey().observe(DataEventType.childAdded, with: { (snapshot) in
let snapshot = snapshot.value as! NSDictionary
let shoe = snapshot["name"] as! String
let colorway = snapshot["colorway"] as! String
let date = snapshot["date"] as! String
let newPost = upcomingPost(shoe: shoe, colorway: colorway, date: date)
self.upcomingPosts.insert(newPost, at: .zero)
self.tableView.reloadData()
})
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return upcomingPosts.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: "upcoming", for: indexPath) as? UPComingPostsCell else { return UITableViewCell() }
cell.updateViews(withUpcomingPost: upcomingPosts[indexPath.row])
return cell
}
}
Also tableView cell can be like this:
class UPComingPostsCell: UITableViewCell {
@IBOutlet weak var shoeLabel: UILabel! //Connect labels from storyboards
@IBOutlet weak var colorWayLabel: UILabel!
func updateViews(withUpcomingPost post: UpcomingPost) {
shoeLabel.text = post.shoe
colorWayLabel.text = post.colorway
}
}
Hope this helps. :)
Upvotes: 1
Reputation: 100503
Remove this
override func numberOfSections(in tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 0
}
you tell the table that num of sections will be 0 , then how you expect it to display anything
Try
var once = true // add this as an instance var
self.upcomingPosts.insert(newPost, at: 0)
if once {
DispatchQueue.main.asyncAfter(deadline: .now() + 1.0 ) {
self.tableView.reloadData()
self.once = false
}
}
Upvotes: 2