I want to bind my data of BehaviorRelay<[Data]>
from my View Model class into a UITableView
in my UIViewController
class, but unfortunately I keep getting this error:
Unexpectedly found nil while implicitly unwrapping an Optional value: file project/ResultCell.swift, line 27 2021-04-17 15:06:32.497411+0700 project[5189:936745] Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value: file project/ResultCell.swift, line 27
Here's what I did (In my View Controller class):
private func setupUI() { // Called in viewDidLoad()
resultsTv.register(ResultCell.self, forCellReuseIdentifier: ResultCell.IDENTIFIER)
}
private func setupRxBindings() { // Called in viewDidLoad()
viewModel.results.asObservable().bind(to: resultsTv.rx.items(cellIdentifier: ResultCell.IDENTIFIER, cellType: ResultCell.self)) { row, element, cell in
cell.configureData(with: element)
}.disposed(by: disposeBag)
let query = searchTf.rx.text.observe(on: MainScheduler.asyncInstance).distinctUntilChanged().throttle(.seconds(1), scheduler: MainScheduler.instance).map { $0 }
query.subscribe(onNext: { [unowned self] query in
self.viewModel.search(query ?? "") // Everytime I search something, it gives me the error
}).disposed(by: disposeBag)
}
My View Model class:
fileprivate final class SearchVM {
var results = BehaviorRelay<[ModelData]>(value: [ModelData]())
init() { }
func search(_ query: String) {
// Get the data from a server and store it in the results property
}
}
My ResultCell.swift
class:
class ResultCell: UITableViewCell {
static let IDENTIFIER = "ResultCell"
@IBOutlet weak var photoIv: UIImageView!
@IBOutlet weak var idLbl: UILabel!
@IBOutlet weak var nameLbl: UILabel!
@IBOutlet weak var miscLbl: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
}
func configureData(with data: ModelData) {
idLbl.text = "ID: \(data.id ?? "")" // The line that causes the error
nameLbl.text = data.name
miscLbl.text = "\(data.gender), \(data.height), \(data.phone)"
}
}
In more detail, I'm making a search page that can show data based on the search results (I'm using an .xib
files for both of my UIViewController
and UITableViewCell
files). Since I'm learning RxSwift I don't want to use any delegates and datasources for my UITableView
. I'm guessing the error is because the cell was not loaded properly so the IBOutlets is not yet initialized. But I'm not sure how to solve the error. Is there anyway to solve this?
You have registered the cell class against your reuse identifier. This just instantiates your cell instances without any reference to your XIB file, and so the outlets are not connected.
You need to register the XIB file against the reuse identifier.
private func setupUI() { // Called in viewDidLoad()
resultsTv.register(UINib(nibName: "yourNib", bundle: nil), forCellReuseIdentifier: ResultCell.IDENTIFIER)
}