iOS How to debug freshly launching an app from a URL
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
Debugging a fresh iOS launch from a URL is different from debugging a URL opened while the app is already running. In a cold start, the URL arrives during app startup, so the main job is to confirm which lifecycle callback receives it and to reproduce that launch path reliably from Xcode or the simulator instead of tapping links manually and guessing.
Know the Cold-Start Entry Points
The first thing to understand is that URL handling depends on both the link type and the app lifecycle model.
Common entry points are:
- custom URL schemes through app delegate or scene delegate URL callbacks
- universal links through
NSUserActivity - scene-based apps receiving launch options through scene connection callbacks
For custom URL schemes in a scene-based app, the URL often appears in the scene connection options on cold start:
For universal links, the cold-start information may arrive through NSUserActivity:
If your app does not use scenes, the equivalent callbacks are usually in AppDelegate.
Reproduce the Launch from the Simulator or Terminal
Do not rely only on Safari taps while debugging. Reproduce the URL launch directly so you can repeat it precisely.
For the iOS simulator:
That is one of the most useful debugging commands for custom URL schemes because it triggers the same URL-opening path on demand.
For universal links, use the actual HTTPS URL:
Now you can:
- launch the app from Xcode
- set breakpoints in the expected lifecycle callback
- send the URL repeatedly from the terminal
This is much more reliable than tapping links manually and wondering whether the app was already warm, backgrounded, or freshly started.
Log the Routing Path Early
Cold-start bugs are often not about receiving the URL but about what happens immediately afterward. The app may parse it too early, before dependencies or the initial UI are ready.
A good pattern is to separate:
- URL reception
- URL parsing
- navigation or routing
For example:
If you log these stages separately, you can tell whether the failure is:
- registration not working
- callback not firing
- URL parsing failing
- navigation running before the UI is ready
That saves a lot of time compared with setting a single breakpoint deep in the routing code.
Distinguish Warm and Cold Behavior
A common source of confusion is that the URL works when the app is already open but fails from a fresh launch. That usually means the routing logic depends on app state that only exists after startup has completed.
For example:
- the root view controller may not exist yet
- the navigation stack may not be ready
- dependency injection may still be initializing
A simple fix is to buffer the route temporarily and perform navigation after the first screen is ready instead of trying to navigate immediately from the launch callback.
The important debugging step is to verify whether the URL is missing entirely or merely arriving before your app can act on it safely.
Common Pitfalls
The biggest mistake is putting breakpoints only in the warm-state callback such as openURLContexts and then concluding that cold-start URL handling is broken. Cold-start delivery may happen in the launch or scene connection options instead.
Another issue is testing universal links without verifying the associated-domain setup and the hosted apple-app-site-association file. A broken universal-link setup will never reach your app correctly.
Developers also sometimes debug only from taps in Safari. Use xcrun simctl openurl so the launch path is reproducible.
Finally, receiving the URL does not guarantee successful routing. Many bugs come from trying to navigate before the app’s UI or state container is ready.
Summary
- Cold-start URL debugging is mainly about finding the correct lifecycle callback and reproducing it reliably.
- Scene-based apps often receive cold-start URLs in scene connection options rather than only in warm callbacks.
- Use
xcrun simctl openurlto reproduce custom URL schemes and universal links on demand. - Log URL reception, parsing, and routing separately so you can see exactly where the flow breaks.
- If warm launches work and cold launches fail, the problem is often startup timing rather than URL registration.

