How to Disable the Network in the iOS Simulator

How to Disable the Network in the iOS Simulator

Written by

in

Quick answer: There is no per-simulator network switch: the Simulator runs your app as a macOS process and shares the Mac’s network stack, so it has no Airplane Mode and no way to cut connectivity for one app. To reproduce offline behaviour you either cut the Mac’s connection (Network Link Conditioner’s 100% Loss profile), point the system proxy at a dead port, or stub the network in code with a URLProtocol that fails every request.

Why this happens

The iOS Simulator is not an emulator. Your app is compiled for the Mac’s architecture and runs as an ordinary macOS process, drawing its networking from the host’s network stack. There is no virtual network interface, no radio, and no Airplane Mode toggle in the Simulator’s Settings app.

That means there is no supported way to say “this one app, in this one simulator, has no internet”. Xcode has no such switch, and simctl has no network subcommand. Whatever you do has to happen either at the Mac level (which the Simulator inherits) or inside your app’s networking code.

This is also why a bug that only shows up on a real device is hard to chase in the Simulator: the Simulator never sees a flaky cell connection, a captive portal, or a handover between Wi-Fi and cellular. You have to fake those conditions deliberately.

How to fix it

1. Use Network Link Conditioner with a 100% Loss profile

This is the closest thing to a real “network off” switch, and it is the standard answer for reproducing bad connectivity in the Simulator.

  1. Download Additional Tools for Xcode from the Apple Developer downloads page (it is a separate download from Xcode itself).
  2. Open the DMG and install Network Link Conditioner. On current macOS it appears as a pane in System Settings; on older systems it lands in System Preferences.
  3. Open the pane, pick a profile, and edit it. Set Packet Loss to 100% and apply.
  4. Run your app in the Simulator. Every request now fails as if the device had no signal.
  5. Switch the profile back to None (or turn the toggle off) when you are done — the setting applies to the whole Mac, so your browser and Xcode’s own traffic are affected too.

The same tool ships profiles for Edge, 3G, high latency and DNS delay, which are often more useful than a hard cut: they let you watch your loading states and retry logic behave realistically.

On a physical device, the equivalent lives under Settings › Developer › Network Link Conditioner once Developer Mode is enabled and the device has been connected to Xcode.

2. Point the system proxy at a dead port

If you cannot install extra tools, the Simulator reads the Mac’s system proxy settings, so you can break HTTP and HTTPS traffic without touching the network interface.

  1. Open System Settings › Network, select the active interface, and click Details.
  2. Go to Proxies and enable Web Proxy (HTTP) and Secure Web Proxy (HTTPS).
  3. Set the server to 127.0.0.1 and the port to something nothing is listening on, for example 1.
  4. Apply, then relaunch the app in the Simulator.

Requests made through URLSession will now fail to connect. Two caveats: apps that ignore system proxy settings (raw sockets, some third-party SDKs) are unaffected, and every other Mac app that honours the proxy breaks too. Turn the proxies off as soon as you have your reproduction.

3. Fail every request in code with a URLProtocol

When you want a repeatable offline state that does not depend on the Mac’s configuration — in unit tests, or behind a debug toggle — intercept the requests yourself.

swift
import Foundation

final class OfflineURLProtocol: URLProtocol {
override class func canInit(with request: URLRequest) -> Bool { true }
override class func canonicalRequest(for request: URLRequest) -> URLRequest { request }

override func startLoading() {
    let error = NSError(
        domain: NSURLErrorDomain,
        code: NSURLErrorNotConnectedToInternet,
        userInfo: [NSLocalizedDescriptionKey: "Simulated offline"]
    )
    client?.urlProtocol(self, didFailWithError: error)
}

override func stopLoading() {}

}

Register it on the session configuration your app uses:

swift
let configuration = URLSessionConfiguration.ephemeral
configuration.protocolClasses = [OfflineURLProtocol.self]
let session = URLSession(configuration: configuration)

Now every task on that session fails with NSURLErrorNotConnectedToInternet, which is exactly the error your UI has to handle. Because the failure is synchronous and local, tests run fast and never touch the network.

This only covers traffic that goes through URLSession with that configuration. WKWebView and SDKs that use their own networking stack are not intercepted.

4. Reproduce radio conditions on real hardware

The original complaint — behaviour that only appears on the device — usually is not about “no network” but about a weak or unstable one. The Simulator cannot model that at all.

Use a real device: enable Airplane Mode, or move away from the router until the signal drops. If you need a hard RF block, a Faraday bag or a foil-wrapped box works, and the physics is simple: the openings need to be smaller than the wavelength of the service you are blocking. 800 MHz is roughly a 37 cm wavelength; 1900 MHz is about 16 cm. That trick is for hardware, not for the Simulator — you cannot put a Mac inside a cage and keep working on it.

5. Detect the state properly in the app

Whatever method you use, make sure the app reacts instead of hanging. NWPathMonitor tells you when connectivity disappears, and waitsForConnectivity keeps a task alive until the network returns rather than failing instantly.

swift
import Network

let monitor = NWPathMonitor()
monitor.pathUpdateHandler = { path in
print(path.status == .satisfied ? “online” : “offline”)
}
monitor.start(queue: DispatchQueue(label: “network.monitor”))

How to prevent it

  • Put all networking behind a small protocol or client type so a failing implementation can be injected in tests and in a debug menu.
  • Add a debug-only “Simulate offline” switch that swaps in the URLProtocol above, so QA does not need to reconfigure the Mac.
  • Exercise the Network Link Conditioner profiles (Edge, 3G, 100% loss, DNS delay) as part of your manual test pass, not just once during a bug hunt.
  • Handle NSURLErrorNotConnectedToInternet and NSURLErrorTimedOut explicitly, and show a retry affordance instead of an empty screen.
  • Remember that a Simulator pass proves nothing about radio behaviour — keep at least one real device in the loop for connectivity work.

FAQ

Does the iOS Simulator have Airplane Mode?

No. The Simulator’s Settings app has no Airplane Mode or cellular controls, because there is no radio to switch off. The app simply uses the Mac’s connection.

Can I disable the network for a single app in the Simulator?

Not with any built-in Xcode or simctl option. The practical alternatives are intercepting requests in code with a URLProtocol, or routing the app through a proxy you control and blocking traffic there.

Does Network Link Conditioner affect the whole Mac?

Yes. It throttles and drops packets at the system level, so the Simulator, Safari and Xcode all see the same conditions. Apply the profile for the duration of your test and switch it back to None afterwards.

Sources & credits

Parts of this guide are adapted from content licensed under CC BY-SA 4.0; this article is shared under the same license.