The Per Rewrite Diary: Day 6

This post is part of a series about rewriting my iOS app, Per. Per is a price per unit comparison app with a bunch of neat convenience figures, but it hasn’t been updated in years, so I’m rewriting it from scratch to eliminate a bunch of technical debt. Just because it’s not an open-source app doesn’t mean I can’t share what I learn as I go!

See the rest of the series here.

Building the UITableView in code

If you try to simply add var productTableView: UITableView = UITableView() as a property and then set its delegate and dataSource as self without touching the other boilerplate methods, you’ll crash the app with this error:

*** Assertion failure in -[UITableView _dequeueReusableCellWithIdentifier:forIndexPath:usingPresentationValues:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKitCore_Sim/UIKit-3901.4.2/UITableView.m:8624
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'unable to dequeue a cell with identifier customcell - must register a nib or a class for the identifier or connect a prototype cell in a storyboard'

This makes sense! The commented-out tableView(cellForRowAt:) method needs to be uncommented, and I need to give this table view a UITableViewCell to work with. And it’s not too hard, I just need to add this to the table view controller’s viewDidLoad method:

productTableView.register(UITableViewCell.self, forCellReuseIdentifier: "productListCell")

Adding the ProductList data

Now I can create a ProductList in the table view controller, populate it with some fake data, and start working with it!

iOS Simulator showing three of rows of ProductItem data

Getting that to display just requires three lines in tableView(cellForRowAt:) :

let productItem = productList.getItems()[indexPath[1]]
let productUnits = productItem.units?.symbol ?? "units"
cell.textLabel?.text = "\(productItem.quantity) \(productUnits) for \(productItem.price) costs \(productItem.pricePerUnit) per unit"

Remember that the indexPath is collection of two values ([section, row]), so we want to specify its row value (indexPath[1]) as our index for the array returned by productList.getItems().

There’s no formatting, and it’s a static view of data that we can’t add to, but we’re slowly getting there! Tomorrow, I’ll start working on a way to add product items to the table view.

Angelo Stavrow

Montreal, Canada
Email me

Mobile/full-stack developer. Montrealer. Internet gadabout. Your biggest fan.