Reputation: 3143
Okay, I know that there are many question about it, but they are all from many time ago.
So. I know that it is possible because the Map app does it.
In the Map app if I turn off the localization for this app, it send me a message, and if I press okay, the "Settings App" will be open. And my question is, how is this possible? How can I open the "Setting app" from my own app?
Basically I need to do the same thing, if the user turn off the location for my app, then I'll show him a message saying something that will open the "Setting app"
Upvotes: 228
Views: 222349
Reputation: 1
I’ve spent the past two days testing different approaches, and here’s what I found. Apple officially supports two methods:
1.Opening your app’s settings via UIApplication.openSettingsURLString
.
2.Navigating to the Notifications settings page via UIApplication.openNotificationSettingsURLString (iOS 16+)
.
For navigating to specific system settings pages, you can use:
Bluetooth settings: App-Prefs:Bluetooth
Camera settings: App-Prefs:Privacy&path=CAMERA
I noticed that many older answers suggested using like App-Prefs:root=Bluetooth
, but this did not work for me. Removing root= and using just App-Prefs:Bluetooth
did the trick!
Additionally, no changes to Info.plist are required—this works without adding any custom URL schemes.
⚠️ NOTE: Most discussions mention that using these App-Prefs URLs may lead to App Store rejection, so use them cautiously and review Apple’s latest guidelines before implementation.
There is my all code for navigate the most of the settings page:
// SettingsHelper.swift
import UIKit
class SettingsHelper {
static let shared = SettingsHelper()
private init() {}
enum SettingsType {
case appSettings
case notificationSettings
case microfonSettings
case cameraSettings
case locationSettings
case photosSettings
case siriSettings
case wifiSettings
case bluetoothSettings
case cellularSettings
case batterySettings
case privacySettings
var urlString: String {
switch self {
case .appSettings: return UIApplication.openSettingsURLString
case .notificationSettings:
if #available(iOS 16.0, *) {
return UIApplication.openNotificationSettingsURLString
} else {
return UIApplication.openSettingsURLString
}
case .microfonSettings: return "App-Prefs:Privacy&path=MICROPHONE"
case .cameraSettings: return "App-Prefs:Privacy&path=CAMERA"
case .locationSettings: return "App-Prefs:Privacy&path=LOCATION"
case .photosSettings: return "App-Prefs:Privacy&path=PHOTOS"
case .siriSettings: return "App-Prefs:SIRI"
case .wifiSettings: return "App-Prefs:WIFI"
case .bluetoothSettings: return "App-Prefs:Bluetooth"
case .cellularSettings: return "App-Prefs:MOBILE_DATA_SETTINGS_ID"
case .batterySettings: return "App-Prefs:BATTERY_USAGE"
case .privacySettings: return "App-Prefs:Privacy"
}
}
}
func openSettings(_ type: SettingsType, completion: @escaping (Bool) -> Void) {
guard let url = URL(string: type.urlString) else {
print("Invalid settings URL")
completion(false)
return
}
UIApplication.shared.open(url) { success in
if success {
print("Successfully opened settings: \(type)")
} else {
print("Failed to open settings: \(type)")
}
completion(success)
}
}
}
⚠️ To test your code, I suggest using a real device instead of the simulator. It didn’t work for me in the simulator.
Upvotes: 0
Reputation: 48085
From iOS 16, you can use openSettingsURLString
if let url = URL(string: UIApplication. openSettingsURLString) {
await UIApplication.shared.open(url)
}
Upvotes: 1
Reputation: 6893
As openURL(_:)
is deprecated after iOS 10.0, use open(_:options:completionHandler:)
instead.
if let settingsUrl = URL(string: UIApplication.openSettingsURLString) {
UIApplication.shared.open(settingsUrl, options: [:]) { completed in
if !completed {
print("Failed opening")
}
}
}
Upvotes: 3
Reputation: 57179
As mentioned by Karan Dua this is now possible in iOS8 using UIApplicationOpenSettingsURLString
see Apple's Documentation.
Example:
Swift 4.2
UIApplication.shared.open(URL(string: UIApplication.openSettingsURLString)!)
In Swift 3:
UIApplication.shared.open(URL(string:UIApplicationOpenSettingsURLString)!)
In Swift 2:
UIApplication.sharedApplication().openURL(NSURL(string:UIApplicationOpenSettingsURLString)!)
In Objective-C
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]];
Prior to iOS 8:
You can not. As you said this has been covered many times and that pop up asking you to turn on location services is supplied by Apple and not by the App itself. That is why it is able to the open the settings application.
Here are a few related questions & articles:
is it possible to open Settings App using openURL?
Programmatically opening the settings app (iPhone)
How can I open the Settings app when the user presses a button?
iPhone: Opening Application Preferences Panel From App
Open UIPickerView by clicking on an entry in the app's preferences - How to?
iOS: You’re Doing Settings Wrong
Upvotes: 359
Reputation: 9703
Seems like you can use the prefs:<area>
URL to open the settings and go to specific areas. Apple could change these and break your app so always check if you can open them first.
From this article they have listed some of them for iOS 13.1:
Settings URLs
iCloud
prefs:root=CASTLE
prefs:root=CASTLE&path=BACKUP
Wireless Radios
prefs:root=WIFI
prefs:root=Bluetooth
prefs:root=MOBILE_DATA_SETTINGS_ID
Personal Hotspot
prefs:root=INTERNET_TETHERING
prefs:root=INTERNET_TETHERING&path=Family%20Sharing
prefs:root=INTERNET_TETHERING&path=Wi-Fi%20Password
VPN
prefs:root=General&path=VPN
Notifications
prefs:root=NOTIFICATIONS_ID
prefs:root=NOTIFICATIONS_ID&path=Siri%20Suggestions
Sounds
prefs:root=Sounds
prefs:root=Sounds&path=Ringtone
Do Not Disturb
prefs:root=DO_NOT_DISTURB
prefs:root=DO_NOT_DISTURB&path=Allow%20Calls%20From
Screen Time
prefs:root=SCREEN_TIME
prefs:root=SCREEN_TIME&path=DOWNTIME
prefs:root=SCREEN_TIME&path=APP_LIMITS
prefs:root=SCREEN_TIME&path=ALWAYS_ALLOWED
General
prefs:root=General
prefs:root=General&path=About
prefs:root=General&path=SOFTWARE_UPDATE_LINK
prefs:root=General&path=CARPLAY
prefs:root=General&path=AUTO_CONTENT_DOWNLOAD
prefs:root=General&path=MULTITASKING
prefs:root=General&path=DATE_AND_TIME
prefs:root=General&path=Keyboard
prefs:root=General&path=Keyboard/KEYBOARDS
prefs:root=General&path=Keyboard/Hardware%20Keyboard
prefs:root=General&path=Keyboard/USER_DICTIONARY
prefs:root=General&path=Keyboard/ReachableKeyboard
prefs:root=General&path=INTERNATIONAL
prefs:root=General&path=DICTIONARY
prefs:root=General&path=ManagedConfigurationList
prefs:root=General&path=Reset
Control Center
prefs:root=ControlCenter
prefs:root=ControlCenter&path=CUSTOMIZE_CONTROLS
Display
prefs:root=DISPLAY
prefs:root=DISPLAY&path=AUTOLOCK
prefs:root=DISPLAY&path=TEXT_SIZE
Accessibility
prefs:root=ACCESSIBILITY
Wallpaper
prefs:root=Wallpaper
Siri
prefs:root=SIRI
Apple Pencil
prefs:root=Pencil
Face ID
prefs:root=PASSCODE
Emergency SOS
prefs:root=EMERGENCY_SOS
Battery
prefs:root=BATTERY_USAGE
prefs:root=BATTERY_USAGE&path=BATTERY_HEALTH
Privacy
prefs:root=Privacy
prefs:root=Privacy&path=LOCATION
prefs:root=Privacy&path=CONTACTS
prefs:root=Privacy&path=CALENDARS
prefs:root=Privacy&path=REMINDERS
prefs:root=Privacy&path=PHOTOS
prefs:root=Privacy&path=MICROPHONE
prefs:root=Privacy&path=SPEECH_RECOGNITION
prefs:root=Privacy&path=CAMERA
prefs:root=Privacy&path=MOTION\
App Store
prefs:root=STORE
prefs:root=STORE&path=App%20Downloads
prefs:root=STORE&path=Video%20Autoplay
Wallet
prefs:root=PASSBOOK
Passwords & Accounts
prefs:root=ACCOUNTS_AND_PASSWORDS
prefs:root=ACCOUNTS_AND_PASSWORDS&path=FETCH_NEW_DATA
prefs:root=ACCOUNTS_AND_PASSWORDS&path=ADD_ACCOUNT
prefs:root=MAIL
prefs:root=MAIL&path=Preview
prefs:root=MAIL&path=Swipe%20Options
prefs:root=MAIL&path=NOTIFICATIONS
prefs:root=MAIL&path=Blocked
prefs:root=MAIL&path=Muted%20Thread%20Action
prefs:root=MAIL&path=Blocked%20Sender%20Options
prefs:root=MAIL&path=Mark%20Addresses
prefs:root=MAIL&path=Increase%20Quote%20Level
prefs:root=MAIL&path=Include%20Attachments%20with%20Replies
prefs:root=MAIL&path=Signature
prefs:root=MAIL&path=Default%20Account
Contacts
prefs:root=CONTACTS
Calendar
prefs:root=CALENDAR
prefs:root=CALENDAR&path=Alternate%20Calendars
prefs:root=CALENDAR&path=Sync
prefs:root=CALENDAR&path=Default%20Alert%20Times
prefs:root=CALENDAR&path=Default%20Calendar
Notes
prefs:root=NOTES
prefs:root=NOTES&path=Default%20Account
prefs:root=NOTES&path=Password
prefs:root=NOTES&path=Sort%20Notes%20By
prefs:root=NOTES&path=New%20Notes%20Start%20With
prefs:root=NOTES&path=Sort%20Checked%20Items
prefs:root=NOTES&path=Lines%20%26%20Grids
prefs:root=NOTES&path=Access%20Notes%20from%20Lock%20Screen
Reminders
prefs:root=REMINDERS
prefs:root=REMINDERS&path=DEFAULT_LIST
Voice Memos
prefs:root=VOICE_MEMOS
Phone
prefs:root=Phone
Messages
prefs:root=MESSAGES
FaceTime
prefs:root=FACETIME
Maps
prefs:root=MAPS
prefs:root=MAPS&path=Driving%20%26%20Navigation
prefs:root=MAPS&path=Transit
Compass
prefs:root=COMPASS
Measure
prefs:root=MEASURE
Safari
prefs:root=SAFARI
prefs:root=SAFARI&path=Content%20Blockers
prefs:root=SAFARI&path=DOWNLOADS
prefs:root=SAFARI&path=Close%20Tabs
prefs:root=SAFARI&path=CLEAR_HISTORY_AND_DATA
prefs:root=SAFARI&path=Page%20Zoom
prefs:root=SAFARI&path=Request%20Desktop%20Website
prefs:root=SAFARI&path=Reader
prefs:root=SAFARI&path=Camera
prefs:root=SAFARI&path=Microphone
prefs:root=SAFARI&path=Location
prefs:root=SAFARI&path=ADVANCED
News
prefs:root=NEWS
Health
prefs:root=HEALTH
Shortcuts
prefs:root=SHORTCUTS
Music
prefs:root=MUSIC
prefs:root=MUSIC&path=com.apple.Music:CellularData
prefs:root=MUSIC&path=com.apple.Music:OptimizeStorage
prefs:root=MUSIC&path=com.apple.Music:EQ
prefs:root=MUSIC&path=com.apple.Music:VolumeLimit
TV
prefs:root=TVAPP
Photos
prefs:root=Photos
Camera
prefs:root=CAMERA
prefs:root=CAMERA&path=Record%20Video
prefs:root=CAMERA&path=Record%20Slo-mo
Books
prefs:root=IBOOKS
Game Center
prefs:root=GAMECENTER
Upvotes: 42
Reputation: 4751
To add to accepted answer: (from apple developer documentation) "When you open the URL built from this string (openSettingsURLString), the system launches the Settings app and displays the app’s custom settings, if it has any." So, if you want to open settings for your app, create your own Settings.bundle.
Upvotes: 0
Reputation: 35783
YES!! you can launch Device Settings screen, I have tested on iOS 9.2
Step 1. we need to add URL schemes
Go to Project settings --> Info --> URL Types --> Add New URL Schemes
Step 2. Launch Settings programmatically Thanks to @davidcann
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"prefs://"]];
Also we can launch sub-screens like Music, Location etc. as well by just using proper name
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"prefs:root=MUSIC"]];
See this full name list here shared by Henri Normak
Update:
As per the comment everyone wants to know what happens after this change to my application submission status?
So YES!! I got successful update submission and application is available on store without any complain.
Just to confirm, I Just downloaded this morning and disabled Location services, and then started the app, which asked me for location permission and then my alert popup was there to send me on settings -> location services page --> Enabled --> That's it!!
![NOTICE: Your app might be rejected ... even if it's approved it can be rejected in future version if you use this method...]4
Upvotes: 60
Reputation: 2411
From @Yatheeshaless's answer:
You can open settings app programmatically in iOS8, but not in earlier versions of iOS.
Swift:
UIApplication.sharedApplication().openURL(NSURL(string:UIApplicationOpenSettingsURLString)!)
Swift 4:
if let url = NSURL(string: UIApplicationOpenSettingsURLString) as URL? {
UIApplication.shared.openURL(url)
}
Swift 4.2 (BETA):
if let url = NSURL(string: UIApplication.openSettingsURLString) as URL? {
UIApplication.shared.open(url, options: [:], completionHandler: nil)
}
Objective-C:
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]];
Upvotes: 135
Reputation: 40156
Swift 4
I prefer to open setting in a safer way,
if let settingUrl = URL(string:UIApplicationOpenSettingsURLString) {
UIApplication.shared.open(settingUrl)
}
else {
print("Setting URL invalid")
}
Upvotes: 1
Reputation: 2896
SWIFT 4.0
'openURL' was deprecated in iOS 10.0: Please use openURL:options:completionHandler: instead
UIApplication.shared.open(URL.init(string: UIApplicationOpenSettingsURLString)! , options: [:], completionHandler: nil)
Upvotes: 1
Reputation: 31
Tested with iOS 10. Working
NSArray* urlStrings = @[@"prefs:root=WIFI", @"App-Prefs:root=WIFI"];
for(NSString* urlString in urlStrings){
NSURL* url = [NSURL URLWithString:urlString];
if([[UIApplication sharedApplication] canOpenURL:url]){
[[UIApplication sharedApplication] openURL:url];
break;
}
}
Happy Coding :)
Upvotes: 1
Reputation: 51
Swift 3:
guard let url = URL(string: UIApplicationOpenSettingsURLString) else {return}
if #available(iOS 10.0, *) {
UIApplication.shared.open(url, options: [:], completionHandler: nil)
} else {
// Fallback on earlier versions
UIApplication.shared.openURL(url)
}
Upvotes: 5
Reputation: 106
In Swift 3 all I needed is this (here for example redirect to my app notifications):
if let url = URL(string: "App-Prefs:root=NOTIFICATIONS_ID&path=your app bundleID") {
if #available(iOS 10.0, *) {
UIApplication.shared.open(url, completionHandler: .none)
} else {
// Fallback on earlier versions
}
}
Source: phynet gist.
This worked with me only when settings is in background. It will redirect you to your app notification settings but if settings wasn't running in the background it will just redirect you to notification settings in general.
Upvotes: 5
Reputation: 12890
In Swift 3 / iOS 10+ this now looks like
if let url = URL(string: "App-Prefs:root=LOCATION_SERVICES") {
UIApplication.shared.open(url, completionHandler: .none)
}
Upvotes: 7
Reputation: 2857
Swift You can use following function to open Settings App with Bluetooth Page
func openSettingsApp(){
if let settings = NSURL(string: "prefs:root=Bluetooth") {
UIApplication.sharedApplication().openURL(settings)
}
}
Again this would not open the App's Settings. This would open settings app with Bluetooth as this is deep linking to bluetooth.
Upvotes: 0
Reputation: 27050
UIApplicationOpenSettingsURLString
this will only work if you have previously allowed for any permission. For example Location, Photo, Contact, Push notification access. So if you have not such permission(s) from the user:
If iOS 10 or above,
It will open the Settings but then crash it. The reason, there's nothing in settings for your app.
Below code will open your application settings inside the iOS Setting.
NSURL *url = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
if ([[UIApplication sharedApplication] canOpenURL:url]) {
[[UIApplication sharedApplication] openURL:url];
}
Due to device unavailability, I couldn't check this on iOS < 10.
Also, I could find below code from some gist and it works fine on iOS 10 as well. But I am not sure if this will approve by Apple review team or not.
https://gist.github.com/johnny77221/bcaa5384a242b64bfd0b8a715f48e69f
Upvotes: 3
Reputation: 811
iOS 10 update
Apple changed the method to open async on the main thread. However, from now it is only possible to open the app settings in native settings.
[[UIApplication sharedApplication] openURL:url options:@{} completionHandler:nil];
iOS 9 update
It is now possible to go directly to sub-settings menu. However, a URL scheme has to be created. It can be done using two ways:
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>CFBundleURLSchemes</key>
<array>
<string>prefs</string>
</array>
</dict>
</array>
Then the code:
Swift
UIApplication.sharedApplication().openURL(NSURL(string:"prefs:root=General&path=Keyboard")!)
Objective-c
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"prefs:root=General&path=Keyboard"]];
Upvotes: 14
Reputation: 16820
Add this to your class,
public class func showSettingsAlert(title:String,message:String,onVC viewController:UIViewController,onCancel:(()->())?){
YourClass.show2ButtonsAlert(onVC: viewController, title: title, message: message, button1Title: "Settings", button2Title: "Cancel", onButton1Click: {
if let settingsURL = NSURL(string: UIApplicationOpenSettingsURLString){
UIApplication.sharedApplication().openURL(settingsURL)
}
}, onButton2Click: {
onCancel?()
})
}
public class func show2ButtonsAlert(onVC viewController:UIViewController,title:String,message:String,button1Title:String,button2Title:String,onButton1Click:(()->())?,onButton2Click:(()->())?){
dispatch_async(dispatch_get_main_queue()) {
let alert : UIAlertController = UIAlertController(title: title, message: message, preferredStyle: UIAlertControllerStyle.Alert)
alert.addAction(UIAlertAction(title: button1Title, style:.Default, handler: { (action:UIAlertAction) in
onButton1Click?()
}))
alert.addAction(UIAlertAction(title: button2Title, style:.Default, handler: { (action:UIAlertAction) in
onButton2Click?()
}))
viewController.presentViewController(alert, animated: true, completion: nil)
}
}
Call like this,
YourClass.showSettingsAlert("App would like to access camera", message: "App would like to access camera desc", onVC: fromViewController, onCancel: {
print("canceled")
})
Upvotes: -1
Reputation: 128
You can use the below code for it.
[[UIApplication sharedApplication]openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]];
Upvotes: 2
Reputation: 1419
You can use this on iOS 5.0 and later: This no longer works.
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"prefs://"]];
Upvotes: 17