10

So we are creating an iOS app that with the push of a button opens up the device's settings app. I have seen that the method has slightly changed with iOS 10 and Swift 3 so I am using a conditional to check which iOS version the user is on before executing the code.

if let settingsUrl = URL(string: UIApplicationOpenSettingsURLString) {

    if #available(iOS 10.0, *) {

        // iOS 10.0.

        UIApplication.shared.open(settingsUrl, options: [:], completionHandler: nil)

    } else {

        // Fallback on earlier versions.

        UIApplication.shared.openURL(settingsUrl)
    }
}

This works perfectly fine on an iOS 9 device, but not on an iOS 10 one. The problem is that whilst the app will send the user to the settings app in iOS 10, it immediately crashes with no crash logs. If I use this same method to open up a website like Google it works perfectly fine on both iOS 9 and 10. I have done a lot of research and it appears they have changed some things with the URL schemes, but can't find any fixes / workarounds.

BenSDConway
  • 199
  • 1
  • 12
  • I have tested the app independently on the device when it's not running through Xcode if thats what you mean? I still get the same behaviour. – BenSDConway Sep 30 '16 at 13:39
  • It's for a custom keyboard extension so within the container app we are simply showing a button that when clicked sends them straight to the settings app instead of having to navigate there themselves. It crashes before the user has a chance to do anything in the settings app. It's mainly a UX thing but pretty vital we believe. – BenSDConway Sep 30 '16 at 13:45
  • If your app still supports iOS 9, why not use the older `openURL` method regardless of iOS version? That's perfectly valid and safe. – rmaddy Sep 30 '16 at 14:00
  • I just gave that a try and has the same issue again. I'm thinking it's something to do with iOS 10 rather than swift 3. – BenSDConway Sep 30 '16 at 14:03
  • Was discussed here http://stackoverflow.com/q/8246070/1040347 In the answers/comments people say that on iOS 10 it is not working. – Aleksey Potapov Sep 30 '16 at 14:34
  • @BenSDConway, Did you got solution for this? – Sunil Targe Oct 17 '16 at 15:13
  • No unfortunately, we had to take the button out. – BenSDConway Oct 17 '16 at 17:29
  • Fixed in iOS 10.2. – Mesbah Jan 09 '17 at 07:40
  • Thanks I'll take a look. – BenSDConway Jan 09 '17 at 08:12

3 Answers3

5

I found a way to open settings app in iOS by adding a setting bundle to my project and using this code:

    let settingsUrl = NSURL(string:UIApplicationOpenSettingsURLString) as! URL
    UIApplication.shared.open(settingsUrl, options: [:], completionHandler: nil)

It looks like this is the only way that you can use in order to open native settings application if your application doesn't have a custom keyboard.

  • 1
    It is not relevant with any keyboard settings. This code snippet doesn't prevent the settings app crash on iOS 10. Settings is crashing while opened from any app, regardless of simulator or real device. I created a fresh project with a single button, just to open the settings. And opening settings from the app causing the crash in iOS 10. Just for reference, relevant thread: http://stackoverflow.com/questions/39659720/open-phone-settings-when-button-is-clicked-in-my-app-ios-10-swift-3-issue – Mesbah Oct 02 '16 at 12:40
5

Custom URL scheme is not officially documented by Apple. It won’t work in iOS 10 any more. The app is allowed to bring users to Your App Own settings page only. Your App will crash if it dosen't have a settings page in iOS 10.

You can try to open Settings page by "gray area" API as follows. But I haven't been succeed in Swift. Good luck!

The "prefs" URL Scheme not woring in iOS 10 (Beta 1 & 2)

Community
  • 1
  • 1
DàChún
  • 4,751
  • 1
  • 36
  • 39
0

Opening UIApplicationOpenSettingsURLString crashes the application.

I am using "App-Prefs:root=WIFI" URL and it works fine.

let settingsUrl = URL(string: "App-Prefs:root=WIFI")
        if UIApplication.shared.canOpenURL(settingsUrl!) {
            if #available(iOS 10.0, *) {
                UIApplication.shared.open(settingsUrl!, options: [:], completionHandler: {(success) in debugPrint("Successfully opened settings")})
            } else {
                UIApplication.shared.openURL(settingsUrl!)
            }
    }