IOS vs Android app architecture similarities

Matan Cohen Abravanel
5 min readJul 29, 2018

--

My career started off as an iOS developer, and recently I started leading both iOS and Android teams. After a few weeks in, I couldn’t stop myself from noticing similarities between the two platforms, at the infrastructure level.

I believe both development teams, iOS, and Android, should share architectural decisions and terminology. At the end of the day, both apps have the same logic, capabilities, and the UI is very similar.

I’m going to target mostly iOS projects that do not use storyboards, I’m not a fan of them. Let’s start with a quick overview first:

AppDelegate vs MainActivity

Latest guidelines for Android development promotes using one activity class and multiple fragments (Yes, I know not all applications are built this way, but it does seem it’s the latest best practice for most cases).

AppDelegate and MainActivity are very similar, they both are apps “entry point”, and the place you should normally allocate your first app instances, or in case you are using dependency injection (And you should) this is the place you would normally start it.


iOS: AppDelegate
class AppDelegate: UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions
launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
//Entry point (In case you do not use storyboards)
}
}
Android: MainActivitypublic abstract class MainActivity extends AppCompatActivity {
protected void onCreate(Bundle savedInstanceState) {
//Entry point
}
}

UIViewController vs Fragment

Both classes act as a screen UI representative (Or some portion of it) receives app lifecycle events and response to user interaction.

Note: I’m taking for granted you are using MVVM design pattern, so both classes contain only UI elements and are bonded to some ViewModel for being updated by app state changes.

The purpose of life cycle events are very similar yet UIViewController has much more of them. For example, ViewWillAppear will trigger whenever the view is going to be presented on screen, ViewDidAppear will trigger when the view is presented. Fragments do not have this ability, instead, you would have to hack your way around this in veritas ways.

Android: Fragmentclass MyFragment: DialogFragment {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,savedInstanceState: Bundle?): View? {
//First allocations/inflate
//View setup will happen on "onViewCreated"

}
}
iOS: UIViewControllerclass ViewController: UIViewController{
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
//First allocations
//Some programmers would use "ViewDidLoad" for this purpose

}
}

UITableView vs RecycleView

In the early days, iOS was known for Its high performance compared to Android.
It has a lot to do with re-using views for faster scrolling (60fps).
iOS is using UITableView since its the first launch. To be more specific iOS 2 (Which was the first iOS to support third-party application via AppStore).
UITableView re-uses its cells (Platform specific name for row items) because it’s considered a time-consuming task creating new ones, one for each scroll.
On CellForRawAtIndexPath you will get a new or recycled instance of the current cell per index and can customize its presentation.

Android, on the other hand, started off, at first, with a component named “ListView”, which suffered from no re-use mechanism and low performance.

“RecycleView” came to the rescue at Google I/O 2014. Its name implies it recycles views.
RecycleView uses an Adaptor (Model–view–adapter) which decides on how many items will be displayed, what types of items, inflating(creating views from XML), and setting/binding items with new scroll data presented.

RecycleView uses a “ViewHolder” to keep a reference to items created, instead of creating new instances (inflating them) it re-uses ones that already exist.

iOS: UITableViewclass MyViewController: UIViewController, UITableViewDelegate, UITableViewDataSource
{
let tableView = UITableView.init()
override func viewDidLoad() {
super.viewDidLoad()
self.tableView.delegate = self
self.tableView.dataSource = self
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
//You will get passed a recycle cell, or a new one.
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int{
//Number of rows displayed
}
}
Android: RecycleViewclass MyFragment : DialogFragment {
var adapter: MyAdaptor
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
homeRecycler.layoutManager = LinearLayoutManager(activity, LinearLayoutManager.VERTICAL, false)
homeRecycler.adapter = this.adapter
}
}
class MyAdaptor : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
var items: List<HomeFeedItem> = listOf()
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
// Bind ViewHolder to current item props
if (holder is MyViewHolder) {
holder.bindViews(items[position])
return
}
}
override fun getItemViewType(position: Int): Int {
return items[position].itemType().intValue()
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
// This is the magic. Inflating will happen only once to improve performance
val inflate: CardView = LayoutInflater.from(context).inflate(R.layout.myLayout, parent, false) as CardView
return MyViewHolder(inflate)
}
fun setFeed(items: List<HomeFeedItem>) {
//Reload list modals
this.items = items
this.notifyDataSetChanged()
}
override fun getItemCount() = items.size
}

Layout: XML VS Constraints

First I will say this, I was surprised by the Android layout, because of how good it works. Easy to jump in (Especially if you have some Web development background).

Android Interface builder works great too, reflecting the exact XML state, saves a lot of time compiling.

iOS uses constraint layout, so-called “expressed” way of defining layout by code (Or Storyboard). It has a big learning curve since it does not work like any other layout framework (At least that I have used in the past) and has some big topics as priorities, content hugging, compression resistance and more, that are quite hard to get your head around at first.

Basically, constraints are objects that define relationships between user interface objects and can be added by code or Interface Builder.

Android, on the other hand, uses XML layout, very similar to some popular Web frameworks, and works with your IDE like a charm. Would you like some padding/margin/background color? Not sure about the syntax? Just start typing and Android Studio will autocomplete with just what you wished for.

Next blog post I’m going to cover the following topics:

Dagger vs Swinject
App Navigation
Implementing MVVM

More where this came from

This story is published in Noteworthy, where thousands come every day to learn about the people & ideas shaping the products we love.

Follow our publication to see more product & design stories featured by the Journal team.

--

--

Matan Cohen Abravanel

The man who does not read has no advantage over the man who cannot read