Opening app's notification settings in the settings app
Asked Answered
T

8

39

In the case that a user may accidentally declines to receive notifications and wants to turn notifications later, how can I use an NSURL to open the IOS Settings App to my app's notification page where they can select Allow Notifications?

Triphthong answered 17/3, 2017 at 3:9 Comment(3)
UIApplication.shared.openURL(URL(string: UIApplicationOpenSettingsURLString)!)Pulsimeter
Possible duplicate of Opening the Settings app from another appPulsimeter
@Triphthong did you ever find a solution for this?Airfoil
J
76

Updated 8 Dec, 2021:

This method will open Settings > Your App. It will show all available privacy toggles like camera, photos, notifications, cellular data, etc.

After a comment from @Mischa below, tested and updated the answer to this (more succinct):

if let appSettings = URL(string: UIApplication.openSettingsURLString), UIApplication.shared.canOpenURL(appSettings) {
    UIApplication.shared.open(appSettings)
}

Previous answer:

I found the answer to this question (albeit helpful) has a bit too much assumed logic. Here is a plain and simple Swift 5 implementation if anyone else stumbles upon this question:

if let bundleIdentifier = Bundle.main.bundleIdentifier, let appSettings = URL(string: UIApplication.openSettingsURLString + bundleIdentifier) {
    if UIApplication.shared.canOpenURL(appSettings) {
        UIApplication.shared.open(appSettings)
    }
}
Jeromejeromy answered 8/4, 2020 at 9:15 Comment(5)
Perfect! Most succinct answer I have seen to achieve thisMerritt
This opens the app settings, but not the app notification settings. I wonder if there's an Apple approved way to do that.Conducive
@Conducive No, there is no (public) way to access subpages of your app's settings page. But your users will understand as they immediately see the "Notifications" option on the main page.Cream
I wonder why this answer appends the bundleIdentifier to the actual settings URL. Is there an actual reason for that? The URL created from UIApplication.openSettingsURLString opens the app settings as well and it seems obsolete. In other words: The simplest solution is Eric Yuan's answer. Apple's documentation of the property states the same: "When you open the URL built from this string, the system launches the Settings app and displays the app’s custom settings, if it has any. Use this string with open(_:options:completionHandler:)."Cream
Mischa, you are probably right, it might have been the case that back when I wrote this answer it needed the bundle identifier, but possibly not anymore. I'll give it a check in a moment and update my answer if that's the case. Thanks for pointing it out!Jeromejeromy
P
27

For Swift 3, use UIApplicationOpenSettingsURLString to go to settings for your app where it shows the Notifications status and "Cellular Data"

let settingsButton = NSLocalizedString("Settings", comment: "")
let cancelButton = NSLocalizedString("Cancel", comment: "")
let message = NSLocalizedString("Your need to give a permission from notification settings.", comment: "")
let goToSettingsAlert = UIAlertController(title: "", message: message, preferredStyle: UIAlertControllerStyle.alert)

goToSettingsAlert.addAction(UIAlertAction(title: settingsButton, style: .destructive, handler: { (action: UIAlertAction) in
    DispatchQueue.main.async {
        guard let settingsUrl = URL(string: UIApplicationOpenSettingsURLString) else {
            return
        }

        if UIApplication.shared.canOpenURL(settingsUrl) {
            if #available(iOS 10.0, *) {
                UIApplication.shared.open(settingsUrl, completionHandler: { (success) in
                    print("Settings opened: \(success)") // Prints true
                })
            } else {
                UIApplication.shared.openURL(settingsUrl as URL)
            } 
        }
    }
}))

logoutUserAlert.addAction(UIAlertAction(title: cancelButton, style: .cancel, handler: nil))
Prothrombin answered 14/7, 2017 at 22:31 Comment(3)
It opens Setting's page. But the question is asking for App's notification's page.Hammered
@ChanchalRaj, yea there is no way to do that. Settings is close as you are going to get.Prothrombin
In Swift 4 this has become UIApplication.openSettingsURLString.Gantline
A
11

This should keep you covered for all iOS versions, including iOS 15 and iOS 16.

extension UIApplication {
  private static let notificationSettingsURLString: String? = {
    if #available(iOS 16, *) {
      return UIApplication.openNotificationSettingsURLString
    }

    if #available(iOS 15.4, *) {
      return UIApplicationOpenNotificationSettingsURLString
    }

    if #available(iOS 8.0, *) {
      // just opens settings
      return UIApplication.openSettingsURLString
    }

    // lol bruh
    return nil
  }()

  private static let appNotificationSettingsURL = URL(
    string: notificationSettingsURLString ?? ""
  )

  func openAppNotificationSettings() -> Bool {
    guard
      let url = UIApplication.appNotificationSettingsURL,
      self.canOpen(url) else { return false }
    return self.open(url)
  }
}

Usage:

Button {
  let opened = UIApplication.shared.openAppNotificationSettings()
  if !opened {
    print("lol fail")
  }
} label: {
  Text("Notifications")
}
Aswan answered 29/10, 2022 at 23:38 Comment(4)
Awesome, thanks! Should be the new accepted answer!Archibaldo
this does not work on iOS 16.0 simulatorOverlook
This is working in iOS 16.4 simulator for me, but it's not working in an iOS 17.2 simulator (it is working on a physical iOS 17.2 device though). Any ideas here? Want to make sure it'll work in production.Holiness
How can i detect back when the user navigates from settings to the app again to refresh my VC ?Tibiotarsus
P
10

Swift 5:

if let url = URL(string: UIApplication.openSettingsURLString) {
    UIApplication.shared.open(url)
}
Pupillary answered 28/6, 2021 at 22:44 Comment(0)
L
5

Since iOS 15.4 we can deeplink to the notif settings screen directly using UIApplicationOpenNotificationSettingsURLString:

https://developer.apple.com/documentation/uikit/uiapplicationopennotificationsettingsurlstring?language=objc

Lori answered 16/8, 2022 at 16:11 Comment(1)
For 16.0 they replaced it with openNotificationSettingsURLStringAswan
K
2

UPDATE: This will be rejected by Apple.

To open notifications part of settings use this

UIApplication.shared.open(URL(string:"App-Prefs:root=NOTIFICATIONS_ID")!, options: [:], completionHandler: nil)
Kinshasa answered 1/3, 2018 at 2:27 Comment(5)
This will be rejected by Apple: "Your app uses the "prefs:root=" non-public URL scheme, which is a private entity. The use of non-public APIs is not permitted on the App Store because it can lead to a poor user experience should these APIs change."Alpenhorn
@Alpenhorn We've had an app in the App Store for 2 years which uses "prefs:root="Proudfoot
This just brings me to my app's settings page; not the notifications page. Does this still work for you? For me it's the same as using UIApplicationOpenSettingsURLString. iOS 12.something, Xcode 10.something.Reinhard
@DarrenBlack Correct I don't believe this is possible anymore on iOS 12.Kinshasa
@Kinshasa Oh but it should be! ;)Reinhard
G
1

you can use this

if #available(iOS 16.0, *)  {
                    if let appSettings = URL(string: UIApplication.openNotificationSettingsURLString), UIApplication.shared.canOpenURL(appSettings) {
                        UIApplication.shared.open(appSettings)
                    }
                } else {
                    if let appSettings = URL(string: UIApplication.openSettingsURLString), UIApplication.shared.canOpenURL(appSettings) {
                        UIApplication.shared.open(appSettings)
                    }
                }
Gaal answered 5/4 at 15:33 Comment(1)
This is already covered in another answer.Abide
E
0

You can navigate to the Notification settings in macOS using this function. However, please note that you will need to manually scroll to locate your app within the settings: func openNotificationsSettings() { UIApplication.shared.open(URL(string:"x-apple.systempreferences:com.apple.preference.notifications")!, options: [:], completionHandler: nil) }

Elledge answered 23/7 at 4:24 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.