Skip to content

Android vs iOS — Concepts & Terminology

If you know Android development, you already understand most of the concepts in iOS development. The platforms solve the same problems — they just use different names and slightly different approaches.

App entry points

Concept Android iOS
App definition AndroidManifest.xml + Application class @main / App struct (SwiftUI)
Main entry point MainActivity ContentView (first SwiftUI view)
App lifecycle Application.onCreate() App.body scene

In SwiftUI, the app entry point is a struct conforming to the App protocol:

@main
struct SessionClickApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}

This is roughly equivalent to your Application class + MainActivity combined.

Screens and navigation

Concept Android iOS
A single screen Fragment / @Composable View (UIKit) / View struct (SwiftUI)
Navigation container NavController (Jetpack) NavigationStack (SwiftUI)
Navigate to screen navController.navigate("route") .navigationDestination + NavigationLink
Back stack Managed by NavController Managed by NavigationStack
Tab bar BottomNavigationBar TabView
Modal/bottom sheet ModalBottomSheet .sheet() modifier

UI building blocks

Concept Android (Compose) iOS (SwiftUI)
Vertical list LazyColumn List / LazyVStack
Horizontal list LazyRow LazyHStack
Text Text() Text()
Button Button() Button()
Image Image() Image()
Text input TextField() TextField()
Layout — vertical Column VStack
Layout — horizontal Row HStack
Layout — overlapping Box ZStack
Padding/spacing .padding() modifier .padding() modifier

Compose and SwiftUI are strikingly similar in philosophy — both are declarative, both use modifiers/chaining. If you're comfortable with Compose, SwiftUI will feel familiar within a few hours.

State management

Concept Android (Compose) iOS (SwiftUI)
Local UI state remember { mutableStateOf() } @State
Shared state (ViewModel) ViewModel + StateFlow @StateObject / @ObservableObject
Observe state in UI collectAsState() @ObservedObject / @EnvironmentObject
Side effects LaunchedEffect .task {} / .onAppear {}

The mental model is the same: state lives somewhere, the UI reacts to it. The wiring looks different but the idea is identical.

ViewModels

Android's ViewModel has a direct equivalent in iOS. In modern SwiftUI (iOS 17+), you use the @Observable macro:

// iOS (SwiftUI)
@Observable
class MetronomeViewModel {
    var bpm: Int = 120
    var isPlaying: Bool = false

    func togglePlay() { isPlaying.toggle() }
}
// Android (Compose)
class MetronomeViewModel : ViewModel() {
    var bpm by mutableStateOf(120)
    var isPlaying by mutableStateOf(false)

    fun togglePlay() { isPlaying = !isPlaying }
}

In a KMP project, you can put the logic in the shared module and only keep the platform-specific wiring in each ViewModel.

Lifecycle

Concept Android iOS
App comes to foreground onResume() scenePhase == .active
App goes to background onPause() scenePhase == .background
View appears LaunchedEffect(Unit) .onAppear {}
View disappears DisposableEffect cleanup .onDisappear {}
Low memory warning onLowMemory() didReceiveMemoryWarning

Permissions

Concept Android iOS
Declare permissions AndroidManifest.xml Info.plist
Request at runtime rememberLauncherForActivityResult AVAudioSession.requestRecordPermission etc.
Permission model Grouped, user can revoke Per-feature, managed by system

Data storage

Concept Android iOS
Key-value storage SharedPreferences / DataStore UserDefaults
Local database Room CoreData / SwiftData
File storage Context.filesDir FileManager / app sandbox
Keychain / secure storage EncryptedSharedPreferences Keychain

In-app purchases

Android iOS
Framework Google Play Billing Library StoreKit 2
Purchase type (one-time) ProductType.INAPP .nonConsumable
Restore purchases queryPurchasesAsync() Transaction.currentEntitlements
Sandbox testing Internal test track / license testers Sandbox Apple ID

The concepts are the same (products, purchases, entitlements) but the APIs are completely different and platform-specific. Neither can be shared via KMP.

Packaging and distribution

Android iOS
App package .apk / .aab .ipa
Store Google Play App Store
Beta testing Internal/Closed/Open tracks TestFlight
Sideloading Allowed (with settings) Restricted (EU only with DMA)
Review process Mostly automated, fast Manual review, 1-3 days

Key iOS concepts with no direct Android equivalent

  • Scenes — iOS supports multiple windows of the same app (iPad). Handled via Scene in SwiftUI.
  • App Groups — share data between your app and extensions (widgets, share extensions). No Android equivalent.
  • Entitlements — a signed list of capabilities (push notifications, iCloud, etc.) granted by Apple. Roughly equivalent to permissions, but granted at build time, not runtime.
  • Provisioning profiles — certificates that prove "this build was made by this developer for these devices." Android uses keystore signing but without the provisioning complexity.
  • Info.plist — XML config file declaring app capabilities, required permissions, URL schemes, etc. Roughly combines AndroidManifest.xml and some Gradle config.

Further reading