Tours

The iOS app, in depth

13 min readView as markdown ↗

This is the deep dive: every screen of URnetwork on iPhone and iPad, the settings with their shipped defaults, and the troubleshooting knowledge that usually lives in a support engineer's head. For the install-to-connected path, see getting started on iOS; for the network design behind it all, the overview.

How the app is built

One Xcode project produces both the iOS and macOS apps. On your device it runs as two processes:

  • The app (bundle network.ur) is the interface you see.
  • The tunnel extension (network.ur.extension) is a Network Extension (NEPacketTunnelProvider) that iOS itself starts and supervises. Your traffic moves through this process, not the app: it wraps what your phone sends in encryption (the "tunnel") before it leaves the device. Four things stay outside it by configuration, as on any well-behaved iOS VPN: your local network (printers, AirPlay, home devices), Apple push notifications, carrier services like Wi-Fi calling, and traffic to your own nearby Apple devices.

The two talk over a local device RPC, so after a relaunch the app adopts the live tunnel instead of tearing it down and starting over. This split is why the VPN keeps working when you swipe the app away, and why iOS asks you to approve a VPN configuration the first time: the extension is a system-managed component. That approval is Apple's standard consent step for any VPN app. It grants no other control over your phone, and it stays visible, and revocable, in Settings → General → VPN & Device Management.

The app needs iOS 16.6 or later, and everything is open source at github.com/urnetwork. No independent audit covers the protocol or the operator's server code, where the privacy claims live. Two 2025 third-party assessments cover other surfaces: a penetration test of the web application and API, and a Leviathan Security Group MASA AL2 assessment of the Android app, which passed. Neither covers the iOS app. The threat model records both and their limits.

The four tabs

The app is four tabs: Connect, Account, Leaderboard, and Support.

Connect

The main screen, top to bottom:

  • The globe. A live picture of your session. When connected, it shows the locations your traffic is exiting from: where the internet sees you. Your client holds several providers at once, commonly three to eight, in two windows side by side (a quality window that HTTPS prefers and a speed window for the rest), and pins each site to one. The picture is plural on purpose while any single website still sees one steady address. The overview explains the provider window in full.
  • The connect button. One tap to connect or disconnect.
  • The drawer. A collapsible sheet under the button holding your selected location, Connect options, live traffic charts, and the Block ads and trackers switch. Drag it up for the full content; tapping the Connect tab while you are already on it collapses the drawer back down. Provide mode is not here. It lives in Account → Settings.

Tap the location card to open the Available providers sheet. It opens on your own devices, "Best available provider", and countries with a live count of providers online. Type a place name into "Search providers" and the results grow a Cities section: searching is how you reach city-level targeting, not scrolling. A location is listed only while a member's device is online in it, and the platform derives the city from the connection it observes rather than trusting a provider's own claim; an address that looks like a datacenter or a VPN is demoted rather than trusted. "Best available" picks the highest-scored providers near you; a specific location makes you appear there (nearby exits are usually fastest, since distance costs latency). Providers are other members sharing spare bandwidth. Your traffic reaches them already encrypted, because the web is HTTPS before it ever enters the tunnel, so a provider sees where the traffic it carries is going, like an ISP does, but not its contents, and not your real address.

Further down the drawer sit four Connect options:

SettingDefaultEffectMain cost
Connection ModeAutoAuto runs both provider windows and routes each packet to the fitting oneWeb or Streaming commit to a single window
Fixed IPOffNarrows the window to one provider, so every site sees one steady addressGives up the plural exit
Strong AnonymizationOnForbids a direct client-to-provider path, so the provider never sees your real IPSlower than the direct path
Post Quantum EncryptionOnSeals the session end to end to the provider, so the operator carries ciphertextSkips providers it cannot seal to
  • Fixed IP is selectable outside Auto.
  • Turning Strong Anonymization off is how you opt into direct mode: the anonymization hop drops out, your client talks straight to the provider, throughput rises, and that provider now sees your real address. The default protects your identity; spend it for speed only if you mean to.
  • Block ads and trackers, in the same drawer, is off until you turn it on and filters everything the tunnel carries.
  • Between the two On defaults, a provider never learns who you are and the operator never reads what you send. Both are true without touching a setting, so no single party holds both your identity and your activity.

Those two switches and the shipped default are the whole picture:

ModeOperator seesProvider seesDefault and availability
Relayed sealedyour account and source connection, which providers you are on, and ciphertext with its timing and volumedestinations it egresses and a device/contract id, not your real IPthe shipped default: Post Quantum Encryption, on in the connect drawer
Relayed standardyour account and source connection, which providers you are on, and the destinations and packet bytes insidedestinations it egresses and a device/contract id, not your real IPopt-in: switch off Post Quantum Encryption
Directless relay involvementyour real IP and the destinations it egressesopt-in: switch off Strong Anonymization

Read the first row as where you are by default. While Post Quantum Encryption is on the client is fail-closed: a provider it cannot seal a session with is skipped, not used in the clear, so what a mismatch costs you is that provider, not your confidentiality. Switching the setting off is what puts you in the second row. No app yet shows a per-connection sealed-or-not verdict, so the setting, not the session, is what tells you where you are. Limit: nothing verifies that the providers offered to you are independent of each other or of the operator, and the operator can run providers itself. The threat model works these rows against named adversaries, including a hostile operator, and is explicit about where each one fails.

Custom DNS

Under the Connect tab's details lives a full DNS control panel. DNS is the internet's phonebook, the lookup that turns a name like ur.io into a network address, and whoever answers those lookups (the resolver) sees the name of every site you visit. The default is the most secure arrangement: encrypted DNS over HTTPS, resolved through the tunnel. Everything else is a trade you can make:

  • DNS over HTTPS (remote). DoH resolved on the far side of the tunnel. The default, and the most private: the resolver sees a provider's address, not yours.
  • DNS over HTTPS (local). DoH resolved from your device directly.
  • Unencrypted DNS (remote / local). Classic UDP DNS, through the tunnel or straight from the device, for networks and resolvers that need it.
  • Local DNS fallback. Races a local resolver while the tunnel starts, so name lookups do not stall during the handshake. When it is off, DNS only ever resolves through the tunnel.

You can edit the resolver lists yourself (remote and local DoH URLs, remote and local DNS servers, IPv4 and IPv6). Two conveniences on top:

  • Per-country recommendations. The strongest settings are known not to work in some countries. When you connect somewhere with a known recommendation, the screen says so and offers a one-tap "Use recommended settings", and a one-tap restore back to the most secure defaults.
  • Suggested servers. A curated list of remote DNS servers, with the ones suggested for your connected country marked in its color. Turning one on adds it to your remote resolver list.

Split rules

Split rules let you route specific traffic outside the tunnel or pin it in place, at the domain and IP level:

  • While connected, the screen shows live routing activity. Tap a domain to route it locally (bypassing the tunnel, so that site then sees your real address), or hold it to a single provider so that site sees one stable address for longer instead of your usual plural exit. Useful for banks and logins that challenge any address change.
  • Rules apply to the whole co-associated network cluster around a domain, so related hosts and CDN traffic are caught together rather than leaking one subdomain at a time.
  • Rules persist and can be removed any time from the same screen.

Limit: per-app split tunneling is not available on iOS (Android and Windows have it). iOS does not give VPN apps a supported way to include or exclude traffic by app, so on iPhone and iPad split rules operate on domains and IPs, not apps.

Provide mode

Sharing your spare bandwidth is a four-way Provide mode picker in Account → Settings → Connections, set to Never until you change it:

ModeWhat it carries
NeverNothing. The default.
AutoPublic traffic while you are connected yourself; only your own devices when you are not
AlwaysPublic traffic, connected or not
NetworkOnly your own network's devices, unpaid. The narrowest sharing the app implements

Some ground rules. Providing uses Wi-Fi only unless you flip Allow providing on cellular network in the same section, so it never touches your data plan by surprise. It runs inside the tunnel process, so it keeps working while the phone sits idle. The traffic you carry is other people's encrypted sessions: you cannot read it, and it cannot touch your device. Abuse enforcement runs on your device at egress, where traffic leaves for the internet: BitTorrent and known attack patterns are dropped there. The drop records nothing, no destination, no domain, no contents, though a plaintext BitTorrent match also sends the operator a flag carrying the device id and a boolean, nothing more. Public traffic you carry is metered under signed contracts, and providers participate in the UR protocol. ur.xyz documents how the rewards work.

Account

Your identity and plan live here:

  • Plan. Free or Pro, the balance you have left, the Upgrade path, and a running total of what your connection has carried for the network.
  • Redeem Balance Code. A one-time data grant, no subscription required.
  • Profile, Settings, Wallet. Settings is the deep one: seedphrase, sign-in methods, device name, Connections (provide mode, the cellular allowance, the kill switch, Blocked locations: countries you never want to exit through), notifications, account deletion, and a "Uses the UR Protocol" link to ur.xyz for how providers are rewarded.
  • Check my IP. Opens ur.io/ip, the way to confirm from outside the app that your traffic really is exiting somewhere else.
  • Post Quantum Identity. The panel below, and the route to the identities of the providers you are connected to.

The post-quantum identity panel

The panel at the bottom of Account shows your device's identity as an identicon (a picture derived from the key, easier to eyeball than hex) with its key hash and client id beneath, each tapping to copy, a share sheet, and a deck of the peers you are connected to that opens the full list. It states its own purpose: if a peer's key ever looks different from the one stored locally, the operator in the middle cannot be trusted. This makes operator blindness checkable.

The encryption it names is the Post Quantum Encryption switch in the connect drawer, on by default, so your client seals traffic directly to the provider from the first connection. The session is mutually authenticated TLS 1.3 keyed with X25519MLKEM768 (a classical curve hybridized with NIST's ML-KEM), so the operator relays bytes it cannot read. The responder side is opportunistic: every current provider build enables it, so one provider can serve sealed and unsealed consumers alike. Your side is not. While the switch is on the client is fail-closed, and a provider it cannot seal a session with is skipped rather than used in the clear. No app yet shows a per-connection sealed-or-not verdict. Identities stay Ed25519.

Leaderboard

Rankings of top providers by data moved. If you provide, you can appear here, publicly or privately, your choice.

Support

Titled "Get in touch": a feedback box, a star rating, an optional Attach logs to feedback switch, and a Discord invite for live help. Plans are not here; upgrading lives on the Account tab.

Siri and Shortcuts

The app registers two App Intents: Connect URnetwork VPN and Disconnect URnetwork VPN. They appear in the Shortcuts app, work by voice ("Hey Siri, connect URnetwork"), and chain into automations, like connecting when you leave home Wi-Fi.

Starting with no email, and the phrase that keeps it

Create Instant Account on the login screen gives you a real, permanent network in one tap. No email, no phone, no password, as the screen itself says. What secures it instead is a seedphrase: a list of words the platform generates and shows you exactly once, on the screen right after creation, keeping only hashed forms of it afterwards. Save it there and then. It is the only way back in from a device that is not already signed in. While you still have one that is, Settings → Seedphrase mints a fresh phrase and retires the old one. With it saved, the account survives a reinstall or a new iPhone, plan and history intact, which a device-local identity never does. None of this is second-class: Settings → Sign-In Methods attaches an email, phone, Apple or Google sign-in, or a wallet to the very same network, keeping your data balance and history. The anonymity is in the account, not the payment: a subscription bought in the app is tied to your Apple account, a balance code to nobody.

Troubleshooting

The VPN configuration approval

The first connect asks to add a VPN configuration. If you declined it, the tunnel can never start. Approve it on the next connect attempt, or check Settings → General → VPN & Device Management, where the URnetwork configuration should be listed.

Multiple VPN profiles, and how the app manages them

iOS can accumulate more than one URnetwork VPN profile over reinstalls and upgrades. The app expects this: on connect it enumerates every profile, resets and retries any that fails to start, then moves on to the next. If a tunnel is already running it adopts that one over the device RPC instead of restarting it. Broken profiles are reset or removed, with a cap on removals so cleanup can never run away, and every profile operation is deadline-bounded so a wedged system daemon cannot hang the app. All of it is automatic. It is described here only so the profile list in Settings makes sense when you look at it.

"Failed to load VPN profiles" (error 12)

If connecting fails with "Failed to load VPN profiles" (error code 12), the system's VPN preferences store is refusing to enumerate profiles, a state the app cannot repair from inside. Fix it by hand:

  1. Open Settings → General → VPN & Device Management.
  2. Remove the URnetwork VPN configuration(s).
  3. Return to the app and connect. You'll be asked to approve a fresh configuration, and the tunnel starts clean.

How the kill switch works here

The app ships a Kill switch toggle in Account → Settings → Connections, the same SDK control every URnetwork app has, off until you turn it on. With it on, the client refuses to fall back to your local route, so traffic stops rather than leaking outside the tunnel. What iOS does not give it is OS-level enforcement. The app does not set includeAllNetworks, so if the tunnel process dies unexpectedly, iOS restores normal networking rather than blocking traffic. Supervision, retries and profile recovery keep the tunnel healthy, but the app does not ask the OS to hard-fail closed. If your threat model requires a guaranteed fail-closed network, plan for that.

Reading the tunnel's logs

The tunnel extension logs to the unified system log, not to files. To watch it:

  1. Connect the device to a Mac and open Console.app.
  2. Select the device, and in the Action menu enable Include Info Messages and Include Debug Messages. The interesting lines are at those levels.
  3. Filter by the network.ur.extension subsystem or search "URnetwork".

Sleep and background behavior

The tunnel is configured with disconnectOnSleep off: the VPN stays up across device sleep rather than re-handshaking every time the screen locks. With the two-process design it also survives the app being swiped away. Disconnecting is something you do with the button, Siri, or by removing the profile.

Where next