How to open Settings programmatically like in Facebook app?

I need to open Settings programmatically from within my app. I searched across SO but everywhere people say that it's impossible. But today I saw that it's implemented in Facebook app. There's a button on an UIAlertView and when you click it you open the Settings. So indeed this is possible to open Settings, I have witnessed this myself. But how to do that? Does anyone know how Facebook does that?

76802 次浏览

You can't, there is no API call to do this.

Only system dialogs, dialogs from Apple Frameworks, can open the settings app. In iOS 5 there was a app url scheme to open the system dialog but Apple removed it later.


With the coming of iOS 8 you can open the settings dialog on your apps page.

if (&UIApplicationOpenSettingsURLString != NULL) {
NSURL *url = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
[[UIApplication sharedApplication] openURL:url];
}
else {
// Present some dialog telling the user to open the settings app.
}

On iOS 8 you can open Settings programmatically!

Here is the code:

- (void)openSettings
{
BOOL canOpenSettings = (&UIApplicationOpenSettingsURLString != NULL);
if (canOpenSettings) {
NSURL *url = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
[[UIApplication sharedApplication] openURL:url];
}
}

If your app has it’s own settings bundle, the settings will be opened showing your app’s settings. If your app does not have a setting bundle, the main settings page will be shown.

The alert in the Facebook app that this question refers to is a standard alert which iOS displays itself when you set UIRequiresPersistentWiFi to YES in your Info.plist files and the user launches your app without a network connection.

To summarize the discussion here:

  • There is no URL you can use to get to the root level of the Settings app.
  • You can send the user to your app's section of the Settings app using UIApplicationOpenSettingsURLString in iOS 8.
  • Your app can display the same alert as Facebook, which does open the root level of the Settings app, by setting UIRequiresPersistentWiFi to YES.

Vito Ziv's answer in Swift.

func openSettings() {
UIApplication.shared.open(URL(string: UIApplicationOpenSettingsURLString)!, completionHandler: nil)


}
 if (&UIApplicationOpenSettingsURLString != NULL) {
UIAlertView_Blocks *alertView = [[UIAlertView_Blocks alloc] initWithTitle:NSLocalizedString(@"Camera Access Denied", nil)
message:NSLocalizedString(@"You must allow camera access in Settings", nil)
delegate:nil
cancelButtonTitle:NSLocalizedString(@"Cancel", nil)
otherButtonTitles:NSLocalizedString(@"Open Settings", nil), nil];
[alertView showWithDissmissBlock:^(NSInteger buttonIndex) {
if (alertView.cancelButtonIndex != buttonIndex) {
NSURL *url = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
[[UIApplication sharedApplication] openURL:url];
}
}];
}
else {
UIAlertView_Blocks *alertView = [[UIAlertView_Blocks alloc] initWithTitle:NSLocalizedString(@"Camera Access Denied", nil)
message:NSLocalizedString(@"You must allow camera access in Settings > Privacy > Camera", nil)
delegate:nil
cancelButtonTitle:NSLocalizedString(@"OK", nil)
otherButtonTitles:nil, nil];
[alertView showWithDissmissBlock:^(NSInteger buttonIndex) {
}];
}

To open settings of our own application in iOS 8 and later, use following code.

- (void) openSettings
{
if(&UIApplicationOpenSettingsURLString != nil)
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]];
else
NSLog(@"UIApplicationOpenSettingsURLString is not available in current iOS version");
}

For reference and detailed description please follow

Opening the Settings app programmatically in iOS 8

On iOS 8 you can open Settings programmatically!

Here is the list of currently known URLs in the Settings app:

- (void) openSettings
{
if (&UIApplicationOpenSettingsURLString != nil)
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]];
else
NSLog(@"UIApplicationOpenSettingsURLString is not available in current iOS version");
}
  • prefs:root=General&path=About
  • prefs:root=General&path=ACCESSIBILITY
  • prefs:root=AIRPLANE_MODE
  • prefs:root=General&path=AUTOLOCK
  • prefs:root=General&path=USAGE/CELLULAR_USAGE
  • prefs:root=Brightness
  • prefs:root=General&path=Bluetooth
  • prefs:root=General&path=DATE_AND_TIME
  • prefs:root=FACETIME
  • prefs:root=General
  • prefs:root=General&path=Keyboard
  • prefs:root=CASTLE
  • prefs:root=CASTLE&path=STORAGE_AND_BACKUP
  • prefs:root=General&path=INTERNATIONAL
  • prefs:root=LOCATION_SERVICES
  • prefs:root=ACCOUNT_SETTINGS
  • prefs:root=MUSIC
  • prefs:root=MUSIC&path=EQ
  • prefs:root=MUSIC&path=VolumeLimit
  • prefs:root=General&path=Network
  • prefs:root=NIKE_PLUS_IPOD
  • prefs:root=NOTES
  • prefs:root=NOTIFICATIONS_ID
  • prefs:root=Phone
  • prefs:root=Photos
  • prefs:root=General&path=ManagedConfigurationList
  • prefs:root=General&path=Reset
  • prefs:root=Sounds&path=Ringtone
  • prefs:root=Safari
  • prefs:root=General&path=Assistant
  • prefs:root=Sounds
  • prefs:root=General&path=SOFTWARE_UPDATE_LINK
  • prefs:root=STORE
  • prefs:root=TWITTER
  • prefs:root=General&path=USAGE
  • prefs:root=VIDEO
  • prefs:root=General&path=Network/VPN
  • prefs:root=Wallpaper
  • prefs:root=WIFI
  • prefs:root=INTERNET_TETHERING
 if (&UIApplicationOpenSettingsURLString != NULL)

in iOS 8+ is always TRUE. So you can edit like this

NSURL *url = [NSURL URLWithString:UIApplicationOpenSettingsURLString];


if ([[UIApplication sharedApplication] canOpenURL:url]) {
[[UIApplication sharedApplication] openURL:url options:@{} completionHandler:nil];
}

(with new openURL for iOS 10)

If you want open application settings you need write method with UIApplicationOpenSettingsURLString.

fileprivate func openSettings() {
UIApplication.shared.open(URL(string: UIApplicationOpenSettingsURLString)!)
}

If you need will open one of many settings, you need use this function

fileprivate func openSettings() {
UIApplication.shared.open(URL(string:"App-Prefs:root=General")!)
}
if #available(iOS 10.0, *) {
if let url = URL(string: "App-Prefs:root=Privacy") {
UIApplication.shared.open(url, completionHandler: .none)
}
} else {
// Fallback on earlier versions
}

Opening Privacy settings in App

SWIFT 3

UIApplication.shared.openURL(URL(string: UIApplicationOpenSettingsURLString)!)

Instead of using prefs:, just use App-Prefs:

if ([[UIApplication sharedApplication] canOpenURL: [NSURL URLWithString: @"App-Prefs:root=WIFI"]]) {
[[UIApplication sharedApplication] openURL: [NSURL URLWithString:@"App-Prefs:root=WIFI"]];
}

.

Everything is here: https://medium.com/@thanhvtrn/how-to-open-settings-wifi-in-swift-on-ios-10-1d94cf2c2e60

Here is a Swift 3 example with UIAlertController and UIAlertAction.

func showSettingsPopup() {
let alertVC = UIAlertController(title: "Notifications disabled", message: "Please, turn on notifications if you want to receive a reminder messages.", preferredStyle: .alert)


let close = UIAlertAction(title: "Close", style: .destructive, handler: { (action) in
print("close action handler")
})


let openSettings = UIAlertAction(title: "Open settings", style: .default, handler: { (action) in
guard let settingsUrl = URL(string: UIApplicationOpenSettingsURLString) else {
return
}


if UIApplication.shared.canOpenURL(settingsUrl) {
UIApplication.shared.open(settingsUrl, completionHandler: { (success) in
print("Settings are opened: \(success)")
})
}
})


alertVC.addAction(openSettings)
alertVC.addAction(close)
present(alertVC, animated: true, completion: nil)
}

A memo about prefs:root= and Prefs:root.

Yes, our App was REJECTED by Apple due to prefs:root= and App-Prefs:root URL scheme today (2018-06-29). They are private API.

Rejected by Apple


For Swift 4,

Only UIApplication.openSettingsURLString is public API to open Settings.

In many of the answers given here I see the use of "App-Prefs:root" "prefs:root" we should not use these in our apps to open settings app. As per Apple this is a non-public url scheme and if we use it our app will get rejected.