iOS Essentials
(intermediate to senior)
Module 1
System design
See here about iOS system-design interviews.
Module 2
Swift, Data structures, and performance
Performance:
Understanding Swift Performance, WWDC 2016 talk:
Allocation (heap vs. stack; note that Strings longer than the size of pointer are allocated on the heap, not the stack, which means that for lengthy Dictionary keys it would be more performant to use something else, e.g. an enum.)
Reference-counting overhead
Method dispatch (dynamic vs. static)
Module 3
From Git to the App Store
Material drawn from here.
Module 4
Introduction to Connectivity and offline mode
Google published an Android document called “Connectivity for billions”. What does it mean for iOS development?
What matters in a network connection
Assets already on disk
Being smart about downloading images
Deduplicating vs. retrying requests (e.g. idempotency, interceptors)
Offline-first architecture
Reachability and network interfaces
Module 6
Networking: Talking to the backend
Tooling: Proxyman/Charles, curl/grpcurl, throttling your connection using Link Conditioner (e.g. with 100% packet loss; and why that’s important).
try Data(contentsOf: url) vs. URLSession vs. Alamofire. Using enums to organize your networking code.
Feature vs. platform: request adapters, request retriers
Partial updates: JSON Patch and Field Masks
Streaming instead of request-response. Sample use case: live updates (e.g. for your order or your friends’ location or online status). For example, a “server push” with either a Websocket or gRPC (http/2), or Server-Sent Event (SSE) if you want to use an HTTP GET. Anything but polling.
Push notifications: APNs and using pushes to wake up the app and/or avoid polling
Some common patterns: e.g. pagination vs. streaming
MTCP and the Multipath Entitlement. (For academic ideas inspired by MTCP, see https://web.eecs.umich.edu/~zmao/Papers/MPBond2020.pdf and https://web.eecs.umich.edu/~zmao/Papers/mobicom19.pdf)
Module 7
mobile cybersecurity
Concepts and mindset: blast radius, TTL, PII, encryption at rest vs. in transit
Checksums and dependency management
Helping the user login: password autofill, social logins, magin links, passkeys
Onboarding: e.g. permission priming
Certificate pinning
Keychain and Shared Keychain
Deeplinks
Authentication and Authorization
SHA, rainbow tables, and salt
http headers
Access tokens vs. refresh tokens, centralizing http-header logic, TTLs
Session tokens vs. OAuth2 (with JWTs)
A blog post: https://mas.owasp.org/MASTG/tests/ios/MASVS-STORAGE/MASTG-TEST-0058/
Module 8
mobile machine learning (ML)
Your workflow vs. user’s workflow:
using LLMs at work (e.g. GPT or other)
greenfield: https://github.com/Pythagora-io/gpt-pilot
user’s workflow: e.g. Semantic Kernel
Deploying an ML model: in the cloud vs. on device
Training an ML model: on a cluster (e.g. in the cloud) vs. on device?!
Reducing training time: e.g. transfer learning
ML is expensive if you have to train your model, etc. But not everything needs ML. There are other types of AI. You might, for example, have an analytic solution to a problem (e.g. for a convex optimization problem).
Removal of reflections from images as a convex optimization problem:
Using n-grams to predict text (e.g. for autofill) and capture context. (N-grams as a precursor to LLMs.)
A quick overview of different types of machine learning:
Supervised vs. unsupervised
Neural nets / deep learning vs. Bayesian vs. Support Vector Machines
caching
The in-memory caches of UserDefaults and CoreData
Key-value stores
Collections: Dictionary vs. Set vs. Array; Sequence and Iterator
Transient/transitory data and eviction policies
NSCache vs. URLCache
URLCache vs. Nuke/SDWebImage/Kingfisher
The /Caches folder in the file system
Opportunitistic caching
/Caches (opportunitistic caching) -> /Application Support (important caching)
Bounded caching: LRU cache
Module 9
Module 10
Persistence
Key-value stores
UserDefaults, UbiquitousKeyValueStore, CoreData, SQLite, Keychain
File system: /Documents, /Application Support, /CloudKit, /tmp
Apple’s video: https://developer.apple.com/videos/play/tech-talks/204NSURLIsExcludedFromBackupKey
User-visible data. (The relevant distinction isn’t always “user data” vs. “app data”.)
Module 11
UI/ux, presentation patterns
Frameworks: SwiftUI vs. UIKit
Three different types of UIKit approaches found in legacy code:
Nibs / xibs
Storyboards. (One giant storyboard vs. multiple; motivation: eliminate merge conflicts.)
programmatic subclassing of UIView and activating constraints
What’s new in iOS 17—big changes
UIKit: MVC -> Coordinators and Presenters. Storyboards, nibs, or a programmatic UIView
A view model != MVVM and some simple patterns
Redux, Unidirectional Flow (UDF), and Testable Composable Architecture (TCA)
Scroll hitch rate and table views / lists
Apple’s Human Interface Guidelines
Redux, Unidirectional Flow (UDF), and Testable Composable Architecture (TCA)
Bottom-up design vs. user-centered design vs. human in the loop
Module 12
UI/UX, Localization (“i18n & l10n”)
Locale
Metric vs. imperial
Languages
Specifying in your test scheme / test plan
LocalizableStrings
Pluralization: SwiftUI vs. UIKit
Why export localizations?
Formatters:
dates (plus Date vs. TimeInterval type), currency, etc.
Module 13
Data-driven decision making
“Improved performance by 50%”. Define “performance”.
Monitoring: Crashlytics, Embrace, Firebase, Apple’s tooling.
PII
A/B testing
Module 14
Multithreading: concurrency and thread safety
Watchdog terminations: Code 0x8badf00d
GCD and deadlocks, async vs. sync
How to make objects shared between threads threadsafe? (Also, remember value types?)
Structured concurrency: why async-await is better than completion handlers
Processes vs. threads (same as “coroutines”?)
Concurrency vs. parallelism. For example, DispatchQueue.concurrentPerform function
DispatchGroup (GCD) and TaskGroup (structured concurrency)
Dispatch queues vs. threads. For example, is “main dispatch queue” synonymous with “main thread”?
Priority inversion and the Thread Performance Checker.
Apple docs: developer.apple.com/.../diagnosing-performance-issues-earlyYou probably don’t need an OperationQueue or DispatchSemaphores; when a DispatchQueue is not enough and you either need a lock or an actor.
CoreData crashes: thread containment
Module 15
Intra-App communication: When “return” isn’t enough
Communication inside an app. For example, between modules or threads, inter-thread or just decoupled.
One to one vs. one to many (a broadcast / “pub-sub”)
Combine (bye bye RxSwift)
One to one:
A callback vs. delegation
A callback vs. completion handler
A completion handler vs. async-await
SwiftUI and a view model
One to many (a broadcast / “pub-sub”):
Callbacks and delegates. (Yes, it’s possible.)
NSNotificationCenter
Module 16
App Launch
The app-launch spectrum: from warm launch to cold launch
iOS POV: foreground applications need RAM to run
Examples of cold launches: iOS evicts a memory-intensive game from RAM, from disk, from background
Tooling for measuring it: “Launch Time” pane in Xcode Organizer
Profiling it: “App Launch” template in Instruments
Improving it:
Third-party embedded frameworks / external dependencies and dylibs (dyld).
“Linked Frameworks & Libraries” in Xcode
Keep your initial view hierarchy simple
Avoid custom drawing—do not override draw (use standard views instead)
If you need custom drawing, do not render outsider the rectangle passed to draw func.
Tooling: “Static Initializer Calls” in Instruments
AppDelegate: initialize nonview functionality lazily rather than on app launch
Apple docs: developer.apple.com/documentation/.../reducing-your-app-s-launch-time
Module 17
Battery
Settings > Battery
Polling
Setting > General > Background App Refresh
Push notifications
Location services / GPS
Streaming?
Avoid cellular, download on wifi if possible
Module 18
modularization
Dependency management: SPM vs. CocoaPods vs. Carthage
Dependency graph (+ strongly coupled vs. loosely copuled)
Engineering principles:
IoC
Extensibility
SOLID principles of [OO]D. (For example: stackexchange.com/…/what-are-the-examples-of-breaking-liskov-substitution-principle)
The call site: API design as user-centered design, where the user is another developer.
Static vs. dynamic libs, faster build times vs. faster launch times
Having modules reflect the division of labor among teams and delivery
If a framework is a module, then what is a framework anyway?