iOS - Deep Linking
Overview
Deep linking enables direct navigation to specific screens or content within Q2MobileApp.
This allows external entry points and partner modules to route users to existing app
screens without requiring manual navigation.
For built-in FI app screens, iOS deep linking is route-based. In practice, you identify the route you want to open, then construct either:
- a built-in Custom URL Scheme deeplink, or
- a built-in Universal Link deeplink
If your module owns the link format and wants to inspect and handle the link itself, use
ContinuityLifecycleModule instead of the built-in FI app deeplink contract.
Push notifications are a separate entry point. If your module receives a remote notification and then decides to navigate to a route, see Push Notifications.
Supported Deep Linking Methods
The Q2 Mobile App supports three primary deeplink approaches on iOS:
- Custom URL Scheme - Built-in app deeplink routing using
urlScheme://open?targetPage=... - Universal Links - Built-in app deeplink routing using
https://{associated-domain}/.../{targetPageName}#/route - Module-managed continuity links - Module-owned link handling through
ContinuityLifecycleModule
Using Custom URL Scheme
Use a custom URL scheme when:
- the target is an existing FI app screen or UUX route
- you want the built-in app deeplink contract
- the FI app is configured with the expected
urlScheme
URL Format
Built-in Q2MobileApp format:
urlScheme://open?targetPage={EncodedRoute}
The targetPage value must be URL-encoded and should represent the route in #/route
form.
Example:
q2mob://open?targetPage=%23%2Fmessages
Using Universal Links
Use a Universal Link when:
- the target is an existing FI app screen or UUX route
- the FI supports Associated Domains and Apple App Site Association
- you want a standard HTTPS entry point into the app
For production Universal Links setup, domain onboarding, and Apple App Site Association ownership, see Universal Links Setup Guide.
URL Format
Built-in Q2MobileApp format:
https://{associated-domain}/.../{targetPageName}#/route
Example:
https://demo.q2.com/experimental/uux.aspx#/messages
Built-in Universal Link matching requires all of the following:
- the host matches
universalAndAppLinkAssociatedDomain - the path contains
targetPageName - the full URL contains a
#/...fragment
Built-in Universal Link parsing is fragment-based. If #/ is missing, Q2MobileApp
will not treat the link as a built-in FI app deeplink.
Route Format Requirements
For built-in FI app deeplinks, the route is the content after #/.
Example:
https://stack.q2developer.com/sdk/native/ardent/uux.aspx#/settings/profile
The route is:
settings/profile
Q2MobileApp will attempt to navigate that route as follows:
- try a native module route first
- if no native module handles it, fall back to loading the UUX route
Valid Examples
q2mob://open?targetPage=%23%2Fmessages
q2mob://open?targetPage=%23%2Fsettings%2Fprofile
https://demo.q2.com/experimental/uux.aspx#/messages
https://demo.q2.com/experimental/uux.aspx#/settings/profile
Invalid Examples
q2mob://open?targetPage=#/messages
https://demo.q2.com/experimental/uux.aspx
https://wrong-host.q2.com/experimental/uux.aspx#/messages
https://demo.q2.com/experimental/dashboard.aspx#/messages
https://demo.q2.com/messages
https://demo.q2.com/experimental/uux.aspx?targetPage=messages
How to Find the Correct Route
If you are unsure about the correct route for a specific page:
- navigate to the target location in a browser
- copy the URL
- locate the content after
#/ - use that value as the route
- URL-encode
#/routewhen building a custom URL scheme deeplink
Example Route Conversion
Full URL: https://host/uux.aspx#/settings/profile
Route: settings/profile
Custom URL Scheme: q2mob://open?targetPage=%23%2Fsettings%2Fprofile
Universal Link: https://host/uux.aspx#/settings/profile
Authentication Behavior
If a built-in FI app deeplink is accepted while the user is unauthenticated:
- the app stores the navigation request
- login proceeds normally
- navigation is executed after the landing page is reached
This means "the app opened" does not always mean "navigation already happened".
When to Use Module-managed Continuity Links
Use ContinuityLifecycleModule when:
- the link is module-owned
- the link should not use the built-in FI app deeplink contract
- your module needs custom parsing or custom side effects
For module-managed continuity links:
- custom URL schemes are offered through
application(_:shouldOpenURL:withOptions:) - Universal Links are offered through
application(_:continue:restorationHandler:) - built-in FI app deeplinks get the first chance to consume the link
For implementation details and examples, see ContinuityLifecycleModule.
Prerequisites
For deeplinking to work in Q2MobileApp or Q2DevApp, confirm all applicable
prerequisites:
urlSchemeis configured for custom URL scheme testingtargetPageNameis configured for built-in Universal Link matchinguniversalAndAppLinkAssociatedDomainmatches the target host- Associated Domains entitlement includes
applinks:{domain} - provisioning profile includes Associated Domains capability
- Apple App Site Association file includes the exact app ID and supported paths
For production Universal Links setup and AASA ownership, see Universal Links Setup Guide.
Common Failure Modes
- wrong
urlScheme - wrong
universalAndAppLinkAssociatedDomain - missing
targetPageNamein the URL path - missing
#/fragment for built-in Universal Link deeplinks - unencoded
targetPagevalue for custom URL scheme deeplinks - full base URL passed into
targetPageinstead of an encoded route - missing Associated Domains entitlement
- provisioning profile missing associated-domain capability
- AASA file missing the exact app ID or path
- link opens the app while unauthenticated, but navigation is deferred until after login
Testing Deep Links
- test built-in custom URL scheme deeplinks with valid and invalid
targetPagevalues - test built-in Universal Links with valid and invalid hosts, paths, and fragments
- verify behavior in both authenticated and unauthenticated states
- confirm invalid links fail gracefully
- verify module-owned links are handled by
ContinuityLifecycleModulewhen they should not use the built-in FI app contract
Best Practices
- prefer the built-in FI app deeplink contract for existing FI app screens
- use
ContinuityLifecycleModuleonly when your module owns the link format - treat the route after
#/as the source of truth for built-in FI app navigation - URL-encode
targetPagefor custom URL scheme deeplinks - test deep links thoroughly in the same FI configuration used by your target app