React Native should automatically fallback to using the offline bundle, which it saves on the first run, if it cannot find a running packager. This is mentioned in Running react-native app on iOS device using offline bundle.
However, in my case, after disconnecting the phone from the WiFi and launching the app, it just hangs on a pre-cached page (or image of a page), and it's often the last loaded page (i.e. the last page that was loaded when the app was connected to the packager). This one is counter-intuitive because you'd think that after closing the app, it wouldn't persist any local state.
I'm not sure why this happens in my case. Here is the relevant log-trace from my device and it's crashing in isPackagerRunning which seems to be attempting to make some sort request to a URL. Should it even be attempting to do this? I can try logging the URL it's trying to connect to I suppose.
Thread 0 name: Dispatch queue: com.apple.main-thread
Thread 0 Crashed:
0 libsystem_kernel.dylib 0x0000000186eaf260 semaphore_wait_trap + 8
1 libdispatch.dylib 0x0000000186d9d5e8 _os_semaphore_wait + 24
2 libdispatch.dylib 0x0000000186d9cca0 _dispatch_semaphore_wait_slow + 140
3 CFNetwork 0x000000018858eb9c CFURLConnectionSendSynchronousRequest + 284
4 CFNetwork 0x00000001885bb154 +[NSURLConnection sendSynchronousRequest:returningResponse:error:] + 120
5 resiShare 0x00000001003d4334 -[RCTBundleURLProvider isPackagerRunning:] (RCTBundleURLProvider.m:76)
6 resiShare 0x00000001003d45e4 -[RCTBundleURLProvider guessPackagerHost] (RCTBundleURLProvider.m:92)
7 resiShare 0x00000001003d47f4 -[RCTBundleURLProvider packagerServerHost] (RCTBundleURLProvider.m:106)
8 resiShare 0x00000001003d49b8 -[RCTBundleURLProvider jsBundleURLForBundleRoot:fallbackResource:] (RCTBundleURLProvider.m:123)
9 resiShare 0x00000001000cad6c -[AppDelegate application:didFinishLaunchingWithOptions:] (AppDelegate.m:23)
10 UIKit 0x000000018e0732dc -[UIApplication _handleDelegateCallbacksWithOptions:isSuspended:restoreState:] + 380
11 UIKit 0x000000018e27f800 -[UIApplication _callInitializationDelegatesForMainScene:transitionContext:] + 3452
12 UIKit 0x000000018e2852a8 -[UIApplication _runWithMainScene:transitionContext:completion:] + 1684
13 UIKit 0x000000018e299de0 __84-[UIApplication _handleApplicationActivationWithScene:transitionContext:completion:]_block_invoke.3151 + 48
14 UIKit 0x000000018e28253c -[UIApplication workspaceDidEndTransaction:] + 168
15 FrontBoardServices 0x0000000189a7b884 __FBSSERIALQUEUE_IS_CALLING_OUT_TO_A_BLOCK__ + 36
16 FrontBoardServices 0x0000000189a7b6f0 -[FBSSerialQueue _performNext] + 176
17 FrontBoardServices 0x0000000189a7baa0 -[FBSSerialQueue _performNextFromRunLoopSource] + 56
18 CoreFoundation 0x0000000187e81424 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 24
19 CoreFoundation 0x0000000187e80d94 __CFRunLoopDoSources0 + 540
20 CoreFoundation 0x0000000187e7e9a0 __CFRunLoopRun + 744
21 CoreFoundation 0x0000000187daed94 CFRunLoopRunSpecific + 424
22 UIKit 0x000000018e06c45c -[UIApplication _run] + 652
23 UIKit 0x000000018e067130 UIApplicationMain + 208
24 resiShare 0x00000001000cb1d0 main (main.m:16)
25 libdyld.dylib 0x0000000186dbd59c start + 4