Search This Blog

Thursday, October 12, 2017

iOS code quality. How to write good swift code.

How to write good, clean and understandable code. There are some good practices how to do that. They are simple rules following which you can make your code more quality.


1. Meaningful variable names


Don't create variables and constants with senseless names like in code below. This is bad practice.
var a = 28
var bb = "Aleksei"
var ccc = "IT"

Use meaningful names for variables. This is good practice.
var age = 28
var name = "Aleksei"
var specialisation = "IT"

2. Camel case convention (for filenames and for code)


This is simple one rule. Just use camelCase notation in naming files, variables, classes, functions and etc.
This is bad practice of naming.
var TYPE: String
var Type: String

var COUNTOFUSEDVEHICLES = 0

var countofusedvehicles = 0

class VEHICLESLISTVIEWCONTROLLER: UIViewController {
}

class vehicleslistviewcontroller: UIViewController {
}

This is good practice o naming.
var type: String

var countOfUsedVehicles = 0

class VehiclesListViewController: UIViewController {
}


3. Meaningful data types


Don't create variables with strange data types for variable's name. It can be reason of misunderstood.
This is bad practice.
var type: Int
var count: Double
var price: String

This is good practice. More obviously that count is Integer value.
var type: String
var count: Int
var price: Double

4. Meaningful name for custom classes


Don't create custom classes with senseless names. Later it can be hard to understand what this class is used for. This is bad practice.
class TableViewCell: UITableViewCell {

}

This is good practice. This class is used for displaying vehicle in cell of table.
class VehicleCell: UITableViewCell {
    
}

5. Using constants for storing identifiers


When all identifiers are just string it can be reason of crash after renaming identifier somewhere in code. Because we must change it in all places. We can forget to do it everywhere it is needed.
func configureTableView(){
    self.tableView.register(UINib.init(nibName: "VehicleCell", bundle: nil),
                                forCellReuseIdentifier: "VehicleCell")
    self.tableView.register(UINib.init(nibName: "VehicleHeader", bundle: nil),
                                forHeaderFooterViewReuseIdentifier: "VehicleHeader")
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "VehicleCell", for: indexPath)
}

Move identifiers strings into special constants. This is good practice. Because later we can change identifier string only in one place.
let vehicleCellIdentifier = "VehicleCell"
    
let vehicleHeaderIdentifier = "VehicleHeader"
    
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: vehicleCellIdentifier, for: indexPath)
}

func configureTableView(){
    self.tableView.register(UINib.init(nibName: "VehicleCell", bundle: nil),
                                forCellReuseIdentifier: vehicleCellIdentifier)
    self.tableView.register(UINib.init(nibName: "VehicleHeader", bundle: nil),
                                forHeaderFooterViewReuseIdentifier: vehicleHeaderIdentifier)
}


6. Separate things to different methods


Don't put all things in one method. For example, in code below we configure tableView and also configure navigationItem. It is logically that we can separate this configuration into two functions.

This is bad practice.
override funct viewDidLoad() {
    super.viewDidLoad()
    self.tableView.tableFooterView = UIView()
    self.tableView.rowHeight = UITableViewAutomaticDimension
    self.tableView.estimatedRowHeight = 200.0
    self.tableView.register(UINib.init(nibName: "VehicleCell", bundle: nil),
                                forCellReuseIdentifier: "VehicleCell")

    let backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: self, action: nil)
    self.navigationItem.backBarButtonItem = backBarButtonItem
        
    let favoritesImage = UIImage(named: "ic_favorite_48pt")
    let favoritesButton = UIButton(frame: CGRect(x: 0, y: 0, width: 30, height: 30))
    favoritesButton.addTarget(self, action: #selector(favoritesButtonTapped), for: .touchUpInside)
    favoritesButton.setImage(favoritesImage, for: .normal)
    let favoritesBarButton = UIBarButtonItem(customView: favoritesButton)
    self.navigationItem.rightBarButtonItem = favoritesBarButton
}


Here we separate configuration functions. This is good practice.
override func viewDidLoad() {
     super.viewDidLoad()
     self.configureNavBar()
     self.configureTableView()
}
    
func configureTableView() {
    self.tableView.tableFooterView = UIView()
    self.tableView.rowHeight = UITableViewAutomaticDimension
    self.tableView.estimatedRowHeight = 200.0
    self.tableView.register(UINib.init(nibName: "VehicleCell", bundle: nil),
                                forCellReuseIdentifier: "VehicleCell")
}
    
func configureNavBar() {
    let backBarButtonItem = UIBarButtonItem(title: "", style: .plain, target: self, action: nil)
    self.navigationItem.backBarButtonItem = backBarButtonItem
        
    let favoritesImage = UIImage(named: "ic_favorite_48pt")
    let favoritesButton = UIButton(frame: CGRect(x: 0, y: 0, width: 30, height: 30))
    favoritesButton.addTarget(self, action: #selector(favoritesButtonTapped), for: .touchUpInside)
    favoritesButton.setImage(favoritesImage, for: .normal)
    let favoritesBarButton = UIBarButtonItem(customView: favoritesButton)
    self.navigationItem.rightBarButtonItem = favoritesBarButton
}

7. Do not print useless information to console. 


It is simple. Just do not put useless print statements. Because it can be hard to find useful console log.
print("It works!!!")

8. Curly braces and new lines


When using curly braces is bad practice to move opening curly brace to new line.

Bad practice in function.
func configureTableView() 
{
    self.tableView.tableFooterView = UIView()
    self.tableView.rowHeight = UITableViewAutomaticDimension
    self.tableView.estimatedRowHeight = 200.0
    self.tableView.register(UINib.init(nibName: "VehicleCell", bundle: nil),
                                forCellReuseIdentifier: "VehicleCell")
}

It is good practice to leave opening curly brace on the same line.
func configureTableView() {
    self.tableView.tableFooterView = UIView()
    self.tableView.rowHeight = UITableViewAutomaticDimension
    self.tableView.estimatedRowHeight = 200.0
    self.tableView.register(UINib.init(nibName: "VehicleCell", bundle: nil),
                                forCellReuseIdentifier: "VehicleCell")
}

The same rule for "if condition" operator. This is bad practice.
let a = 10
let b = 20
if (b > a)
{
    print("This is bad code style")
}

This is good practice.
let a = 10
let b = 20
if (b > a) {
    print("This is good code style")
}

6 comments:

  1. A big shout out to you, such a useful and thought provoking article on Web Design USA straight from an intellectual mind

    ReplyDelete
  2. You've provided some really useful information; I've been looking for material like this, so please keep sharing it as much as you can. Best Custom Websites

    ReplyDelete
  3. Thank you very much for sharing this informational blog.I could not find such kind of information in any other site.I'll come back for more fantastic material.
    Best wishes, and good luck.
    Custom Website

    ReplyDelete
  4. your article is unbelievable with accurate information. I see a lot of research after that and that is more than I expectedCustom Build Website

    ReplyDelete
  5. I adore your work, and it greatly motivates me.
    SEO Services NYC

    ReplyDelete