Intermediate concepts in Mobile Dev, page 16
Writing React Native iOS Modules in Swift
React Native speaks Objective-C on iOS, so Swift needs an Objective-C wrapper to join. Write logic in Swift, expose it via an Objective-C class, and register with RCT_EXPORT_MODULE. Skip the bridging header and the compiler never sees your Swift code.
Custom Rendering with draw(_:)
draw(_:) is the callback where UIKit asks your view for pixels. Override it to render custom shapes or text with Core Graphics when stock views fall short. The footgun is calling it directly or doing non-drawing work inside; use setNeedsDisplay() instead.

BLoC Pattern: Separating UI from Business Logic
The BLoC pattern treats app state as a stream: events go in, states come out. Use it in Flutter for complex state like user auth or data fetching. The footgun is overusing it for simple UI state, which creates unnecessary boilerplate.

Android Overdraw: Stop Painting Pixels Twice
Overdraw is wasted GPU work, painting the same pixel multiple times in one frame. It causes UI stutter and drains battery. Fix it by removing unneeded backgrounds and flattening your UI layouts.
Fabric Native Components
Fabric Native Components are host platform views exposed to React under the New Architecture. They use JSI and a C++ rendering core so the shadow tree, layout, and view updates run synchronously without the legacy async bridge, reducing latency and tearing.
MatchedGeometryEffect: Shared Element Hero Transitions
MatchedGeometryEffect lets two views share one spatial identity, so a thumbnail can appear to fly into a detail sheet across view hierarchies. It only works if both views exist simultaneously during a withAnimation block; otherwise the transition snaps.

StateNotifierProvider: Manage Immutable State
StateNotifierProvider bundles immutable state with the logic to change it. It's ideal for managing complex objects like a todo list by exposing methods like addTodo.

Android Work Chaining: An Assembly Line for Tasks
Chaining work in Android is like an assembly line for background tasks, ensuring one task finishes successfully before the next begins. It's used for multi-step operations like fetching, processing, and saving data.
Native Module Threading Model
Native modules run on their own threads, not the JS thread or main UI thread. Heavy work stays off the JS event loop, but UI mutations must be manually dispatched to the main thread. Assuming they are main-thread safe causes crashes and ANRs.
XCTestCase: One Fresh Instance Per Test
A XCTestCase subclass is a lab bench for isolated experiments. Each test method is a fresh invocation checked by the runner. The silent killer is shared mutable state on the case: without setUp, tests flake because execution order is never guaranteed.

ProGuard Keep Rules: A "Do Not Remove" List for Your Code
ProGuard keep rules are a "do not remove" list for Android's code shrinker, telling it what to spare when it can't detect usage. This is crucial for code accessed via reflection or JNI.
Test Plans (XCTestPlan)
A Test Plan is an Xcode configuration file decoupling which tests run from how they run, letting one scheme execute many configurations: localizations, sanitizers, randomized order, and repetition, all without editing the scheme.
React Native's Legacy Bridge: The Async Bottleneck
The legacy bridge is an async JSON queue between JavaScript and native threads. You see it stutter when a FlatList scrolls or native events flood the pipe. Teams often optimize JavaScript when the real bottleneck is bridge saturation from redundant native…
Gradle Build Scripts: The Recipe for Your App
Gradle build scripts are your app's recipe, using a declarative DSL to define dependencies and build variants. They manage libraries and create versions like debug vs. release.
Choosing a Flutter Local Persistence Strategy
Flutter offers three main ways to persist data locally. Your options are simple key-value pairs for settings, direct file I/O for blobs like images, or a full SQLite database for complex, structured data. The main footgun is picking the wrong tool for the job.
Enabling React Native's New Architecture
Enabling React Native's New Architecture swaps the async bridge for direct JSI calls. Set build flags to use Fabric and TurboModules. It is not a drop-in upgrade; legacy libraries often break without interop support or proper codegen types.
Dependency Resolution in iOS Package Managers
Dependency resolution finds one version of every library that satisfies all transitive requirements. It runs when SPM, CocoaPods, or Carthage builds your graph. The footgun is tight upper bounds; they multiply unresolvable diamond conflicts.
OkHttp Interceptors: Middleware for Your Network Stack
OkHttp Interceptors act as middleware for your network stack, letting you observe, modify, or short-circuit requests and responses. Use them to automatically add auth tokens or log traffic. The main footgun is order: application interceptors run once per call.
Flutter Shaders: GPU Power for Custom Graphics
Shaders are small programs running on the GPU to create custom visual effects. Use them for high-performance graphics like frosted glass or animated gradients that standard widgets can't handle.
New Shadow Tree: Async Layout Engine
The New Shadow Tree is React Native's C++ layout engine that runs off the JS thread. It calculates Yoga flexbox asynchronously before mounting native views.
We are hiring for this. Every open role lists the topics its interview covers, so you can prepare for the real thing rather than guessing.
See open roles