Learning iOS from Android perspective

Łukasz Marczak
5 min readJan 10, 2019

--

Once upon a time, I decided to learn something about Swift and iOS mobile development. Kotlin-native becomes more and more popular and it’s very tempting to create an app for both platforms. In contrast to hybrid apps, view layer are kept native. On Android, we stick to XML, Activities and Fragments — on iOS from the other hand — we have Storyboards and UIViewControllers. Let’s review other significant differences between these ecosystems.

Audience

This post is dedicated for Android developers willing to expand their knowledge in iOS app development. This post covers several concepts existing in Android with its closest equivalent on iOS platform.

View injection

If you are familiar with Butterknife you’ll probably like the way how views are injected in iOS:

@IBOutlet looks like ButterKnife @BindView, and @IBActionis like @OnClick, but it is used for all other view interactions. In my opinion it’s much more convenient than doing the same from code, thus it has way more events than plain Android controls:

Navigation between screens

In Android, Activities and Fragments are Views, so we can either start Activities, or manage fragments by FragmentManager transactions. On iOS, the main building block for Views are UIViewControllers. ViewControllers can occupy whole screen, like Activites as well as part of them — like Fragments.
Navigating between them is done with segues. Android have in mind the following

//inside Activity
startActivity(secondScreenIntent, requestCode)

iOS guys can have something like:

//inside UIViewController
self.performSegue(withIdentifier: “SECOND_SCREEN_SEGUE”, for sender: self)

The interesting part is, Androids requestCode can be an integer value from 0 to 2¹⁶, iOS segue identifier can be a string. Navigation between one ViewController to another can be easily done from Storyboard, sometimes with no additional code. But often we need to pass some data to second View.
On Android, initial data for new screen is passed via Intent or Bundle, on iOS we can do the same using prepare()— like setting up the View before it is fully presented:

startUIViewControllerForResult?

But wait… How we can receive data from current screen to the previous one?

In Android, this concept is implemented with startActvityForResult(intent, requestCode) and corresponding onActivityResultimplementation. In general, we want to select|create|edit some data on separate screen (pick location from map, use search view, capture photo, etc) and pass it back:

In iOS this is usually done with closures, or delegates:

UI Widgets

The iOS have rich set of user interface building-blocks. Following table covers the UIKitframework counterparts of the Android views:

╔═══════════════╦═════════════════════════╗
║ Android ║ iOS ║
╠═══════════════╬═════════════════════════╣
║ TextView ║ UILabel ║
║ EditText ║ UITextField ║
║ Button ║ UIButton ║
║ Switch ║ UISwitch ║
║ RadioButton(s)║ UIPickerView ║
║ Checkbox ║ N/A ║//I guess you need Switch
║ ImageView ║ UIImageView ║
║ ProgressBar ║ UIActivityIndicatorView ║//indeterminate
║ ProgressBar ║ UIProgressView ║//determinate
║ SeekBar ║ UISlider ║
║ RecyclerView ║ UITableView ║
╚═══════════════╩═════════════════════════╝

General tip is to append your widget with UI- prefix, but it’s not the rule. Of course, the list above is not the truest. It is up to your app design what fits better. For example, we can replace UIPickerViewwith UITableViewor UISegmentedView. You can browse more widgets at .storyboard with ⌘+Shift+L

Granting permissions

On Android 6.0 and higher, sensitive permissions(like location, user contacts, dialing phone) needs to be granted by user. We need to present system dialog with appropriate explanation why particular permission is needed. Android developers have to insert additional lines in AndroidManifest.xml, and nicely show a dialog with appropriate motivation why we need permit.

iOS has its own alternative — Info.plist, which is quite similar to AndroidManifest.xml. It can be easily edited in XCode.

This xml file consists of dictionary with definitions and alternative prompt messages which will appear when permission is required:

User preferences

Sometimes we need to store some small data — on Android we usually use SharedPreferencesfor that, for example:

val sharedPreferences = getDefaultSharedPreferences(context)//writing
sharedPreferences.edit().putString(KEY, "value").commit()
//reading
val value = sharedPreferences.getString(KEY,"defaultValue")

iOS has UserDefaults:

let preferences = UserDefaults.standard//writing
preferences.set("value", forKey: KEY)
preferences.synchronize()
//reading
var value: String
if preferences.object(forKey: KEY) == nil {
value = defaultValue
} else {
value = preferences.string(forKey: KEY)
}

Main thread processing

Both on Android and iOS, when dealing with background processing, UI related work needs to be done on main thread. You may find useful doing some UI work on Android:

//posting on main thread
activity.runOnUiThread { /*ui-related code*/ }

and iOS:

DispatchQueue.main.async {
/*ui-related code*/
}

Adding external libraries

In real-life Android Application Development, we usually do not reinvent the wheel. If we can — we grab some library from GitHub, and we add corresponding dependency to build.gradle files. Then we sync project in Android Studio and we’re done!
Traditional Java libraries are packed into jarfile.
Android has aar files(AAR — Android Archive). Except source code, it can contain Android-related files, like drawables or string resources.

I was surprised that there is a diversity on iOS ecosystem: you can choose between CocoaPods, Carthage or Swift Package Manager. Just different approaches to supply .framework binaries for your project — which are equivalent of Android aar and can contain code & resources.

Summary

As you can see, from coding perspective there’s a lot in common with Android and iOS internals. I hope that this article encouraged you to try your hand at creating projects on iOS.

Having kotlin-native in mind, wrapping building-blocks presented above into more high-level abstractions could reduce writing similar code for both platforms. I’d really recommend trying it out!

Resources:

https://www.goodreads.com/book/show/22948620-migrating-to-swift-from-android

https://developer.apple.com/library/archive/referencelibrary/GettingStarted/DevelopiOSAppsSwift/

--

--