76

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?

Paulw11
  • 108,386
  • 14
  • 159
  • 186
Andrey Chernukha
  • 21,488
  • 17
  • 97
  • 161
  • Note that Facebook Application is open source and completely available on github. – Sulthan May 23 '14 at 08:31
  • Facebook didn't show this alert, the OS did it. It happens in certain circumstances such as Airplane Mode being turned on or WiFi being turned off, and the OS offers for you to open Settings and change it. – Guy Kogus May 23 '14 at 08:32
  • 9
    @Sulthanthe note that the Facebook Application is not open source. Only the SDK is. – MatterGoal May 13 '15 at 08:38
  • Check this: http://stackoverflow.com/questions/5655674/opening-the-settings-app-from-another-app/37439140#37439140 – guyromb May 25 '16 at 13:48
  • Visit this answer for Swift 3: [http://stackoverflow.com/a/34024467/5391914](http://stackoverflow.com/a/34024467/5391914) – Hamed Feb 28 '17 at 11:50

15 Answers15

140

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 its 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.

danronmoon
  • 3,814
  • 5
  • 34
  • 56
Vito Ziv
  • 1,631
  • 2
  • 11
  • 13
  • @BeemerFan no only your own app's settings page. – rckoenes Dec 02 '14 at 15:50
  • 3
    Does anyone know how to open just Settings app not individual settings page? Facebook opens Settings app without directing to individual settings page. – Pei Jan 29 '15 at 16:59
  • Is there any fix for IOS7?. In IOS 7 its not working. – Suresh Feb 25 '15 at 10:08
  • @Suresh , before iOS 8 you may see rckoenes's answer. – Vito Ziv Feb 26 '15 at 02:44
  • `- (void)openSettings { NSURL *url = [NSURL URLWithString:UIApplicationOpenSettingsURLString]; if (url != nil) { [[UIApplication sharedApplication] openURL:url]; } else { NSLog(@"cannot open settings, url is nil!"); } }` – Lubos Ilcik Apr 16 '15 at 09:27
  • 7
    Attention: If you don't have set your settings bundle this code still opens the App settings (with "Notifications" and "Use Cellular Data") and not the generic settings. – MatterGoal May 14 '15 at 14:53
  • 1
    how can you remove the app settings, so that it opens the general settings? Its already there in ios8 when you install the app. – vatti May 31 '15 at 10:53
  • 2
    Would you please tell me how to delete the app setting bundle at xcode ? I always goes to the app Settings instead of general settings – Jeff Bootsholz Jul 07 '15 at 10:27
  • @decodingpanda Hey, yes actually it works for phonegap, but only for iOS > 8. I had to create a plugin just for calling this feature. – MontDeska Sep 03 '15 at 21:10
  • @RajuGujarati - did you find any solution for this ? Please let me know. – Tejas K Feb 02 '16 at 05:30
  • IS POSSIBLE TO ACCESS? Storage & iCloud Usage -> Manage Storage – Markus Nov 09 '17 at 09:47
  • Is it possible to make the app that called this code not shut down or is that unavoidable after the user changes settings like camera or photo access? – app-dev Jul 17 '19 at 16:05
58

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.
}
rckoenes
  • 69,092
  • 8
  • 134
  • 166
33

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
Mihai Fratu
  • 7,579
  • 2
  • 37
  • 63
Stalin Pusparaj
  • 741
  • 9
  • 11
20

Vito Ziv's answer in Swift.

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

}
Eric
  • 16,003
  • 15
  • 87
  • 139
Anoroah
  • 1,987
  • 2
  • 20
  • 31
14

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.
Richard Venable
  • 8,310
  • 3
  • 49
  • 52
  • >>> *your app's section of the Settings app* <<< What is the behavior when you do not provide a `settings.bundle` for your app? I am finding that when launched via Xcode this URL takes me to the top level Settings page. But when via TestFlight, it goes to my (empty) app settings child page. But I did not create a `settings.bundle`, and there is not one in my `.app` product... – pkamb Sep 21 '15 at 22:21
  • As far as doing the same thing facebook does this should be the right answer. `UIRequiresPersistentWiFi` is what I was looking for to display the alert. However, does anyone know if you can programmatically trigger it during runtime instead of using the info.plist? @Richard Venable do you if there is a method that you could call so you could actually make use of this when a specific button is clicked? – user3832583 Nov 26 '16 at 20:17
11

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.

AechoLiu
  • 17,522
  • 9
  • 100
  • 118
7
 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)

Joannes
  • 2,569
  • 3
  • 17
  • 39
5

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")!)
}
user1064264
  • 51
  • 1
  • 1
  • Do not use "App-Prefs:root=General" in your apps. It apple will reject your app for using non-public url in your application. Mine got regected – Ravi Kumar May 16 '19 at 07:26
3

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

Stonz2
  • 6,306
  • 4
  • 44
  • 64
Aamir
  • 16,329
  • 10
  • 59
  • 65
2
 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) {
            }];
        }
IvanovDeveloper
  • 553
  • 5
  • 19
1

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)
}
Anvar Azizov
  • 545
  • 1
  • 6
  • 9
1

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.

Ravi Kumar
  • 313
  • 2
  • 13
0
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

Hemanshu Liya
  • 611
  • 6
  • 10
0

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

Nikola Markovic
  • 301
  • 1
  • 13
-1

SWIFT 3

UIApplication.shared.openURL(URL(string: UIApplicationOpenSettingsURLString)!)
BennyTheNerd
  • 3,930
  • 1
  • 21
  • 16
  • openURL is outdated in swift 3, you should use open(URL(string: UIApplicationOpenSettingsURLString)!, options: [:], completionHandler: { _ in }) – Damian Dudycz Jun 16 '17 at 07:16