Why an iPhone PWA Fails Offline When Tested Over Local HTTP
For iPhone PWA testing, a working interface can hide a basic setup problem: the phone may never have registered the service worker. HTTPS, the manifest, the worker lifecycle, and the distinction between two caches set the groundwork for understanding why a PWA can work on a laptop but fail on an iPhone. The visible page is only one part of the system; offline behavior depends on browser security rules and on setup having completed on the device being tested.
A page that loads isn't proof of an installed PWA
Picture a familiar test: the frontend runs on a laptop, and an iPhone on the same Wi-Fi opens Safari at http://192.168.1.20:5173. The interface loads, buttons respond, and the PWA icon appears on the Home Screen. Then airplane mode goes on. Tapping the icon brings up a page error instead of the app. Chrome on the laptop still reports a registered worker and a full cache, so the team starts inspecting the manifest. But the key issue may be simpler: the phone never saw that worker.
Each of those observations proves something different. A page that renders shows that the phone could reach the development server over the local network. Responsive buttons show that the page's scripts ran while that connection was available. An icon on the Home Screen indicates that Safari offered an installation path, but it doesn't establish that the page's resources were saved for offline use. The laptop's developer tools describe the laptop's browser state, not Safari's state on the iPhone.
That distinction is easy to miss during development because the screen can look finished long before the offline path has been tested. A PWA combines a web page with browser-managed capabilities; those capabilities don't appear simply because a site resembles an app. The browser has to accept the service worker, the worker has to install and activate, and its code has to place the resources needed for a later launch into a cache.
Why the local address matters
The example address uses plain HTTP and a private network IP address. That setup is convenient: a developer can run a server on a laptop and open it from a phone on the same Wi-Fi. But service workers are restricted to secure contexts because they can intercept requests and influence what content a page receives. In ordinary deployment, HTTPS supplies that secure context. Local development has special handling for some loopback addresses, but a phone reaching a laptop through its LAN address isn't the same case.
So the laptop and phone can be testing different conditions even when they're loading the same source code. The laptop may treat its development address as a trusted local context, while Safari on the phone sees an ordinary HTTP connection to another device. If the phone declines to register the worker, the app can still appear to work online: the server continues delivering the page and its assets. Once the network disappears, there may be no installed worker to answer requests from local storage.
Here's the thing: checking the address bar and the network path belongs near the start of debugging, before changing cache logic. A manifest can describe an app's name, icons, and launch behavior, but it can't make an insecure origin eligible for service worker use. A polished manifest won't repair a missing worker registration.
The worker lifecycle and the two caches
A service worker has a lifecycle. The browser downloads its script, evaluates installation, and later activates it; code commonly uses the installation stage to pre-cache a defined set of files. That sequence can take time, and updates may leave an older worker controlling existing pages until the browser completes its lifecycle rules. A successful page load therefore doesn't tell you whether the current worker is installed, active, or controlling that page.
There are also two different kinds of cache in this story. The browser's ordinary HTTP cache can retain responses according to web caching behavior, while the Cache API lets a service worker store named responses for application use. Seeing assets load quickly—or seeing entries in one browser's developer tools—doesn't prove that the iPhone has the Cache API entries required for an offline launch. The location and owner of the evidence matter.
Offline support also depends on what the worker actually caches and how it responds when a request can't reach the network. A worker that only caches a few images may not be able to provide the app's entry page. A worker that caches the shell but not data may open the interface while showing empty or stale content. These are separate design decisions, and both should be tested on the target device.
And yet, this isn't necessarily a sign that Safari has a general PWA failure. It may be a mismatch between the development origin and the browser's security requirements, or a worker that wasn't installed before the test began. The simplest diagnosis is often to inspect registration and control status in Safari on the iPhone, then verify that the intended resources are present there.
What the test can and can't establish
Adding a site to the Home Screen and testing it offline are distinct checks. The first confirms that the browser can create a launch point; the second tests whether the app's offline strategy works under the conditions that matter. A useful test should confirm that the phone can register the worker, that the worker reaches its active state, and that the expected page and supporting assets are available after connectivity is removed.
If you're working in this space, test from the same device and origin that users will rely on. A laptop's successful registration is useful evidence about the laptop, but it can't stand in for an iPhone. Likewise, a local HTTP test may reveal interface issues while saying little about production behavior under HTTPS. Keep those test conditions explicit when reporting a failure.
Why the setup issue matters
This is more significant than it looks because service worker failures can send debugging in the wrong direction. Teams may spend time rewriting cache rules or adjusting the manifest when the browser never accepted the worker in the first place. Start with the origin and registration, then inspect lifecycle state, cached resources, and the fallback behavior.
The broader lesson is practical: an offline claim is only as strong as its device-specific test. A launch icon, a responsive page, and a laptop's cache report are clues, not a complete diagnosis. First establish that the iPhone registered and activated the worker. Then test the app with the network genuinely unavailable.
Only then does the offline behavior tell you what the PWA can actually do. A small setup check, with consequences for the whole test.