In the last article we introduced a massive controller and worked towards a more leaner design. We separated out the UITableView data sources into a designated data source and data manager classes. The refactoring moved the responsibility of providing the data to the UITableView from the ShoppingListTableViewController into separate concrete implementations. In this article we are going to look at other parts of the ShoppingListTableViewController which can be tamed into separate classes.

UIAlertController

Take a look at the addShoppingListButtonPressed function below:

@IBAction func addShoppingListButtonPressed() {

The above code is responsible for displaying an alert to the user. The alert contains a UITextField which is used to enter a new shopping list name. Once, the name is entered and the “Save” button is pressed the new shopping list is stored in the SQLite database using Core Data.

The code above works fine but we can definitely improve it by utilizing the Swift Extensions for UIAlertController.

extension UIAlertController {

There is nothing magical about the above code! We simply moved the same code into a separate function which is a Swift Extension for UIAlertController class. This refactoring results in the following code:

@IBAction func addShoppingListButtonPressed() {

Much simpler right!

NSManagedObjectContext

In the addShoppingListButtonPressed we called the self.saveShoppingList function to persist the new shopping list record into the database. The saveShoppingList function is implemented below:

private func saveShoppingList(title :String) {

The NSEntityDescription.insertNewObjectForEntityForName is quite a mouthful. Also, for some reason we are using the KVC techniques when assigning the new title to the shoppingList instance even though we have created a custom class for ShoppingList which inherits from the NSManagedObject as shown below:

class ShoppingList: NSManagedObject, ManagedObjectType {

If we utilize the ShoppingList class above our code will look something like this:

private func saveShoppingList(title :String) {

A little better but now we have to case it to the ShoppingList class before assigning it to the shoppingList variable. Also, we still have that NSEntityDescription.insertNewObjectForEntityName which look pretty ugly to type all the time.

Swift Extensions to the Rescue!

We can extend the NSManagedObjectContext class to add a function insertObject which is responsible for creating the type of object we need to be inserted.

import Foundation

Now, you can easily update your code to take advantage of the NSManagedObjectContext Extension as shown below:

private func saveShoppingList(title :String) {

Much nicer and simpler!

Segue

Segues are intregal part of your application since they allow you to navigate between different screens. Currently, if you select a shoppingList you will be taken to the grocery items screen which will display all the grocery items for the selected shopping list. The implementation of the prepareForSegue is shown below:

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {

Straight away you can see the issue! The segue.identifier is comparing against a string value. It is very easy to make a mistake and spell the string wrong and then all of a sudden the segue will stop working. To work around this issue we created a custom protocol “SegueHandlerType” which can be used on the classes who want to perform a segue.

protocol SegueHandlerType {

We also utilized the Protocol Extensions feature of the Swift language to provide the default implementation of segueIdentifierForSegue as shown below:

extension SegueHandlerType where Self :UIViewController, SegueIdentifier.RawValue == String {

Now our ShoppingListTableViewController class can conform to the SegueHandlerType class as shown below:

class ShoppingListTableViewController3: UITableViewController, SegueHandlerType {

And we can use the segueIdentifierForSegue function inside the prepareForSegue function:

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {

Much better and looks nicer!

In this post we looked at different pieces of code contained inside the ShoppingListTableViewController and moved it to their designated places. This resulted in more readable and maintainable code which can provide greater benefits in the future.

References

iOS Developer, speaker and educator. Top Udemy and LinkedIn instructor. Lead instructor at DigitalCrafts. https://www.udemy.com/user/mohammad-azam-2/

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store