A crash component in subview

Jerry PM
3 min readJul 23, 2023

--

When I use the VIP pattern.

Source: Author

A crash component in subview refers to a problem that occurs when implementing the VIP (View-Interactor-Presenter) pattern in software development. The VIP pattern is a design pattern commonly used in building iOS applications. It promotes separation of concerns and modular development by dividing the application into three main components: the View, Interactor, and Presenter.

In the VIP pattern, the View component is responsible for displaying the user interface and handling user interactions. The Interactor component contains the business logic and serves as the intermediary between the View and Presenter. The Presenter component handles the presentation logic and communicates with both the View and Interactor.

However, sometimes when implementing the VIP pattern, developers may encounter a crash

How to Solve the Crash:

Flow crash is when I navigate, and use a route to `FilesViewController`.
crash if I add a component like `UILabel` and else, the crash can be any component.

Solution 1:

I tried to create programmatically the page and then fix issue crash.

class MyViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

var tableView: UITableView!
var data: [String] = ["Item 1", "Item 2", "Item 3"]

override func viewDidLoad() {
super.viewDidLoad()

// Inisialisasi UITableView
tableView = UITableView(frame: view.bounds, style: .plain)
tableView.delegate = self
tableView.dataSource = self
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "Cell")

// Menambahkan UITableView ke dalam view
view.addSubview(tableView)
}

// MARK: - UITableView Data Source

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return data.count
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
cell.textLabel?.text = data[indexPath.row]
return cell
}

// MARK: - UITableView Delegate

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
// Aksi yang akan dilakukan ketika baris di tabel dipilih
let selectedItem = data[indexPath.row]
print("Selected item: \(selectedItem)")
}
}

Solution 2:

After a lot of testing and I found the error because missing `nibName`

// Before

class FilesViewController: DefaultViewController {
@IBOutlet weak var tableView: UITableView!
var newData: FilesModel?

init(parameters: [String: Any]) {
super.init(nibName: nil, bundle: nil) //<-- wrong(make crash if using `.xib))
guard let data = parameters["data_files"] as? ReksadanaFilesModel else {
return
}
newData = data
}

required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

override func viewDidLoad() {
super.viewDidLoad()
title = newData?.navTitle
setupTable()
tableView.reloadData()
}

override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
setBackButton()
}

private func setupTable() {
tableView.delegate = self
tableView.dataSource = self
tableView?.rowHeight = UITableView.automaticDimension
tableView?.registerNibFromBundle(AnnouncementTableViewCell.self)
view.addSubview(tableView)
}
}
.
.
.

// After

class FilesViewController: DefaultViewController {
@IBOutlet weak var tableView: UITableView!
var newData: FilesModel?

init(parameters: [String: Any]) {
// fixing in here
let type = type(of: self)
super.init(nibName: String(describing: type), bundle: Bundle(for: type))
guard let data = parameters["data_files"] as? ReksadanaFilesModel else {
return
}
newData = data
}

required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}

override func viewDidLoad() {
super.viewDidLoad()
title = newData?.navTitle
setupTable()
tableView.reloadData()
}

override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
setBackButton()
}

private func setupTable() {
tableView.delegate = self
tableView.dataSource = self
tableView?.rowHeight = UITableView.automaticDimension
tableView?.registerNibFromBundle(AnnouncementTableViewCell.self)
view.addSubview(tableView)
}
}
.
.
.

--

--