The most underused feature in mobile development might be the Settings deep link. Both iOS and Android expose a way to send the user directly from your app to your app's Settings page, where they can flip permission toggles in two taps. Most apps do not use it. The user gets a screen that says "Permission denied. Open Settings to fix," and the user gives up because they do not know which of the twenty pages in Settings has the toggle.
This guide walks through how to wire up the deep link on both platforms, what to put around it in the UI, and the recovery-rate gain you get from doing it well.

Photo by Matheus Bertelli on Pexels
Why the deep link matters
A user who denied a permission and now wants to use the feature has three possible paths.
The first is the long way: close your app, open Settings, scroll to your app's section, tap into Permissions, toggle the right switch, come back. Five to seven taps depending on the OS. The drop-off at each step is high.
The second is the deep link: tap a button in your app, land on your app's Settings page, toggle the switch, come back. Three taps total.
The third is doing nothing and abandoning the feature. This is what happens by default when your deny-state UI is silent.
Adding the deep link moves users from the third path to the second. Recovery rates that were 5 percent quietly become 20 percent. Same users, same denial. The only thing that changed is the friction on the recovery side.
iOS implementation
On iOS, the API is straightforward. From any view, open the app's settings URL.
import UIKit
if let url = URL(string: UIApplication.openSettingsURLString) {
if UIApplication.shared.canOpenURL(url) {
UIApplication.shared.open(url)
}
}
That is the entire implementation. The UIApplication.openSettingsURLString constant resolves to a URL that opens the Settings app at your app's section. The user lands directly on the page with the permission toggles for your app.
A few notes.
The URL is stable across iOS versions; you do not need to special-case anything. The behavior of "what page do they land on" has occasionally shifted (some versions of iOS land on a slightly higher-level page than others), but the user is always within one or two taps of the toggle.
You cannot deep-link to a specific permission toggle. The Settings URL drops you on your app's section, and the user navigates the rest. This is by design.
For the official reference, Apple's developer documentation has the UIApplicationOpenSettingsURLString constant documented with examples.
Android implementation
On Android, the equivalent is an intent that opens the application details page in Settings.
import android.content.Intent
import android.net.Uri
import android.provider.Settings
val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).apply {
data = Uri.fromParts("package", context.packageName, null)
flags = Intent.FLAG_ACTIVITY_NEW_TASK
}
context.startActivity(intent)
The ACTION_APPLICATION_DETAILS_SETTINGS action lands the user on your app's details screen, where they tap into Permissions and flip the toggle. The total tap count is comparable to iOS.
A few notes.
Android has more permission-specific intents than iOS (you can sometimes link directly to certain permission flows in newer OS versions), but ACTION_APPLICATION_DETAILS_SETTINGS is the most compatible and works across the install base.
The FLAG_ACTIVITY_NEW_TASK flag is required if you are launching the intent from a non-Activity context. Forgetting it produces a runtime error.
Google's Android developer site has the canonical reference for these intents and the permission model around them.

Photo by İclal Çapoğlu Cinal on Pexels
The UI around the deep link
The deep link by itself does not solve the problem. The deny-state UI that points to it does.
Every screen in your app where a permission-denied feature lives needs a visible state that explains what happened and offers the recovery. A few patterns that work.
The persistent banner. When the user opens a screen where the feature does not work because of a denied permission, show a thin banner at the top. "Camera access is off. Tap to fix." The banner is dismissible for the session but persistent across launches until the permission is granted.
The inline placeholder. Where the feature would have rendered, show a placeholder that explains what is missing. "Allow location to see hikes near you. [Open Settings]." This is the most user-friendly pattern because the explanation and the action are at the point of need.
The empty state with action. For screens that are otherwise empty without the permission (a contacts-based "Find Friends" screen, for example), the empty state itself is the explanation. Make sure the deep link is the primary call-to-action.
Avoid the popup pattern. A modal that fires every time the user opens a denied-permission screen is annoying within one session. Use the banner or inline pattern instead.
Copy patterns for the deny state
The copy on a deny-state UI follows roughly the same shape as the pre-prompt copy, with one extra job: it has to explain that the permission was previously denied so the user knows what they are about to flip.
Three patterns.
The matter-of-fact one. "Location is off. Hikes near you will show once you turn it on. [Open Settings]." The user understands what happened and what to do.
The value-restated one. "Turn on location to see hikes near you. [Open Settings]." Useful when the user might not remember the original pre-prompt context.
The "we know what you tried" one. "You tried to start a hike without tracking turned on. [Open Settings] to enable, or continue without tracking." Useful right at the moment the user attempted the feature.
All three are short. All three label the button by what it does. None of them apologize. None of them guilt the user.
For UX research on how users perceive and respond to error states and recovery prompts, Nielsen Norman Group has practical studies that translate well to mobile.
Measuring recovery
The metrics that matter on the recovery side are simple.
Deny-state UI impressions. How often does a user see the deny-state UI? If this is zero or near-zero, the deny state is hidden somewhere in your app and the user is just hitting a broken feature.
Deep-link tap rate. Of users who saw the deny-state UI, what percent tapped the Settings deep link? This is your UI-effectiveness metric.
Toggle-flip rate. Of users who tapped the deep link, what percent actually flipped the toggle? Track this through the app's resume event (the user comes back from Settings) and the permission check that runs on resume.
Recovery rate. Of users who ever denied the permission, what percent eventually granted it? This is the long-term outcome metric.
A healthy recovery flow shows non-trivial numbers across all four. A broken one has a high deny-state UI impression count and zero deep-link taps, which means the call-to-action is invisible.
When this is not enough
The deep link is the right tool when the user actively wants the feature back. It does not help when the user has decided they do not want the feature, and it cannot replace a well-timed initial prompt.
If your initial acceptance rate is below 60 percent and your deny rate is high, the deep link will recover some users but not most of them. The bigger gain is upstream: fix the trigger moment, rewrite the pre-prompt, stage the permissions. The deep link is the cleanup at the end of the funnel, not the start of it. The full lifecycle is laid out in the 137Foundry article on mobile permission flows, which walks through this approach end to end.
For the broader context on app development work and the kinds of mobile engagements where this kind of detail matters, the 137Foundry homepage and services list cover where this fits.
Closing implementation note
The deep link is a few lines of code on each platform. The UI around it is a single component reused across every permission-dependent screen. The total engineering investment is under a sprint, including testing.
The result is a permission flow that is no longer a one-way trap. Users who change their minds can act on the change in three taps. Users who initially denied because of poor timing can recover when the feature becomes relevant. The retention curve responds within a release.
If your app does not have this today, it is the lowest-effort, highest-impact thing on the permission-flow backlog. Ship it next sprint.
Top comments (0)