Standardisation has a positive impact on any business. In the Software Industry too, there are certain coding standards that are needed for successful software development. For most organisations, the seamless functioning of software programs is essential for their growth.
Creating good quality software and code is not as easy as pie. It requires consistent efforts of the software development team to meet code quality goals and follow team programming best practices to collaborate successfully. This is an essential thing for the software project. The developers are often seen side-stepping the quality standards when they are required to complete their tasks in a short span of time.
They are a series of procedures that can be defined for a particular programming language specifying a programming style, the methods, & different procedures. These procedures can be for various aspects of the program written in that language. They can be considered essential attributes of software development.
A coding standard makes sure that all the developers working on the project are following certain specified guidelines. The code can be easily understood and proper consistency is maintained.
Consistency has a positive impact on the quality of the program and one should maintain it while coding. Also, it should be taken care that coding rules are homogeneously followed across different levels of the system and they do not contradict each other. The finished program code should look like that it has been written by a single developer, in a single session.
Let’s look at the list of coding standards in mobile apps.
1. General guidelines:
String Resource : Instead of hardcoding, strings should be defined as resources.
Preferred Third Party Libraries : Use third party libraries via Gradle dependencies(Android) and Cocoa pods, cartage(iOS) instead of manually copy pasting the code from library.
Indentation : All the code should be properly indented. For Android Studio Reformat Code tool can be used and for iOS select all code followed by cmd+I shortcut can be used.
Wherever possible, the use of loops should be minimal.
Less Static/global variables:
Android: Instead of storing variables statically or globally use local variable whenever possible or use intent to pass data to next activity/screen.
iOS: Instead of storing variables statically or globally use local variable whenever possible or use method request parameters and return types.
Cyclomate complexity: Use inbuilt functions instead of nested loops. Use SortDescriptors, Set to remove duplicate entries, Use of HashSet to avoid duplications, Use system defined functions to perform operations on collections. E.g. to get last object of ArrayList, use ArrayList.lastObject().
LOC should be less. Methods and classes should be short.
Code should be segregated functionality wise
2. Naming convention:
Outlet / View References : ex. lblUsername, tblProductView, etc.
Variable : arrCountryList, dictPincode, etc.
Methods : ex. checkInternetConnection, callLogUserIntoApp, getHostName, etc. (start with verb prefix)
Class name : NSObject, AppDelegate, Context, EditText, etc.
Constant : CONNECT_TIMEOUT, REQUEST_CODE, BASE_URL, etc.
Boolean : isSelected, isConnected, isLoggedIn, isEnabled, etc.
Package name(android) : lowercase
Names : all variable names should be meaningful.
File names (Android only): XML: layout_activity_main.xml/layout_product_list_item.xml,menu_activity_main.xml, Kotlin/Java file: TitleCase.java/TitleCase.kt.
Asset file names : IcSend, IcCancel, ImgLoginBackground, ImgSelected, ImgShowPassword, etc.
3. Performance best practices:
Preferred faster development language. For e.g. Swift over Objective C or Kotlin over Java, etc.
Restrict minimum OS version. For e.g. for iOS, 3 lower versions than latest version in market. For Android, 5 lowers version than latest version in market.
Use more language defined functions than custom own logic.
Preferred minimum customisation in system’s default controls.
Lighter & faster database uses. For iOS preferred core data or similar. For Android use Room database or similar, etc.
Lighter cloud base web API : Use of cache at servers for bigger but non-frequently changing data. Adopt to proper coding style for handling huge parallel request. For loading images preferred image caching.
Preferred API Pagination for loading bigger data. Preferred small data uploading / downloading data api than bigger data fetching.
Use of background app refresh / preferred asynchronous task /avoid blocking main thread.
More use of lazy loading concepts : Lazy loading is a design pattern commonly used in computer programming to defer initialisation of an object until the point at which it is needed. It can contribute to efficiency in the program's operation if properly and appropriately used.
Avoid continuous background operation : Background operations definitely have performance issues. Therefore it’s better if developers avoid them whenever not necessary.
Pull to refresh : Pull-to-refresh is a touchscreen gesture that consists of touching the screen of a computing device with a finger or pressing a button on a pointing device, dragging the screen downward with the finger or pointing device, and then releasing it, as a signal to the application to refresh the contents of the screen. Instead of auto refreshing app’s data repeatedly, this feature will provide manual refresh control to user.
Keeping low consumption of memory : avoid memory leaks. Avoid using static context class. Avoid global variable / collection object declaration. Use tools (like instruments for iOS & memory profiler for android) to find leaks & memory allocation.
Adding language supported default security : Adding external security frameworks or libraries may increase performance issues. Therefore it’s better to apply language defined easy solutions for securities.
Use of low size image assets : Image assets are one of the most important elements, which influence app performances drastically. Therefore implementing them in correct way is necessary, even sizes of images have significant impact on performance. Keeping low sizes of assets help to improve performance of app.
Prefer opaque layer / native animation whenever possible : Generally animations are run on main tread, therefore they have direct impact on performance of app. Complex & looping animation logic influence app performance. Therefore using simpler animation library is always better. Even if animations are not required, then avoid them, as that will significantly improve performances.
4. Debugging & error handling best practices:
break-point / debugger: For debugging use proper syntax for logs, use break-point / debugger. For android, print logs, based on build config file.
Error handling : To handle null values, preferred optional unwrapping over force unwrapping. Use optional binding, optional chaining, guard statement. To handle errors, preferred try…catch blocks, finally block. Preferred break-point exception, Edit scheme - zombies in iOS.
Write proper comments wherever possible as it will help during debugging
Thread safety : For Swift, pick right solution from operation queue, GCD, Threads, timers, broadcast-receiver, base on situation & business logic. For android, , pick right solution from queue, work manager, job schedular, etc.
Corner case handling : Preferred writing test cases prior development.
Crash-reporting libraries: Preferred crash-lytics, test-fairy, mix-panel, firebase analytics, etc.
5. Architecture best practices
Separation of concerns : Separation of concerns is a core principle when it comes to designing architectures and systems that are easy to maintain. It’s the idea that each object or type should only know enough about its surroundings to do its work, and no more. In swift use protocol, extension, blocks (callback) to interact in different classes. In Kotlin, preferred interface, callbacks, nested classes, etc.
Design patterns: Preferred MVP, MVVM or MVC, etc.
Modularity : Segregate app’s code module base on features. Like registration, chat, payment, checkout, setting modules, etc.
Open/Closed Principle: This principle states "software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification”. that is, such an entity can allow its behaviour to be extended without modifying its source code.
Single Responsibility Principle : A class should have one, and only one, reason to change.
Liskov Substitution Principle : The principle defines that objects of a superclass shall be replaceable with objects of its subclasses without breaking the application. That requires the objects of your subclasses to behave in the same way as the objects of your superclass.
Interface Segregation Principle : “Clients should not be forced to depend upon interfaces that they do not use.”
Dependency Inversion : The general idea of this principle is as simple as it is important: High-level modules, which provide complex logic, should be easily reusable and unaffected by changes in low-level modules, which provide utility features. To achieve that, you need to introduce an abstraction that decouples the high-level and low-level modules from each other.
6. Database related best practices:
Naming conventions (Table, column, Row)
Table Names - Avoid prefix, space or suffix, preferred Singular names)
Use encryption for sensitive data
Use proper data type, dependent on data
Avoid use of var char column indexing
Use an ORM framework
Use disaster recovery and security services like failover clustering, auto backups, replication etc.
Document your database design with ER schemas and instructions
Normalisation must be used as required, to optimise the performance
Have proper check on number of tables & Size of tables
Joins, operation queues (begin transaction, open DB, commit DB, Close DB) should be properly organised
Preferred async operations than sync operations
Database migration mechanism should be consider properly
7. Security best practices:
Avoid storage of sensitive data
Use secured built-in key-chains / key store
Manage access permissions properly
Implement proper TLS by ensuring HTTPS is always used
Don’t hardcore data inside app
Manage user session properly
Implement TLS/SSL Pinning to avoid MiTM attack
Define trust boundaries
Restrict app to install on non-rooted device
Try to include all in-build security protections
If necessary, use MDM solutions for enterprise apps
Restrict paste control
Restrict keypad auto suggestion
Preferred post apis over get apis
Enable secure property / input type for sensitive data fields
Don’t log sensitive data or show on alert
In Muti-tasking, During app swiping hide visible content
Developing a mobile app isn’t easy. You’re going to encounter some speed bumps along the way. However, it’s definitely helpful if you have some guidelines as a reference. So I hope that you can use this guide to help make your life as a developer much easier. Follow these best practices for development if you want your app to be successful.
Remember that you’re not working in a vacuum. You’re part of a team, and when you work together, everyone benefits.
Coding best practices are about writing readable code, being consistent, and saving everything to version control. But they’re also about collaboration and enjoying the process of what you’re doing. When you do that, you may find that you are writing better code than ever before.
What is the most challenging part of your app development process?