Is there an equivalent of openSettingsURLString in SwiftUI?
Asked Answered
R

3

27

I want to create an alert that redirects the user to Settings App after they denied camera usage for the first time, but the only way that I've seen so far uses UIKit and

let settingsAction = UIAlertAction(title: "Settings", style: .default, handler: {action in
        UIApplication.shared.open(URL(string: UIApplication.openSettingsURLString)!, options: [:], completionHandler: nil)
    })

In SwiftUI, there is an actions option within alert, how would I be able to correctly open settings through SwiftUI's version of alert?

.alert(isPresented: $alertVisible) { () -> Alert in Alert (title: Text("Camera access required to take photos"), message: Text("Go to Settings?"), 
     primaryButton: .default(Text("Settings"), action: UIApplication.shared.open(URL(string: UIApplication.openSettingsURLString)), 
     secondaryButton: .default(Text("Cancel"))
Rheometer answered 3/6, 2020 at 17:1 Comment(0)
H
48

Here it is

.alert(isPresented: $alertVisible) {
     Alert (title: Text("Camera access required to take photos"),
            message: Text("Go to Settings?"),
            primaryButton: .default(Text("Settings"), action: {
                UIApplication.shared.open(URL(string: UIApplication.openSettingsURLString)!)
            }),
            secondaryButton: .default(Text("Cancel")))
        }

Harlow answered 3/6, 2020 at 17:18 Comment(2)
Your solution works fine on iOS, but on Mac with Catalyst I don't see the system preferences window: how can I fix?Pickens
This needs to be used in DispatchQueue.main.async { // here }, or Xcode will show a warningOwings
V
16

In shortest form you can use something like this:

Link("Open settings ?", destination: URL(string: UIApplication.openSettingsURLString)!)

This will create you a simple looking button that will lead directly to the Settings app. Of course, you can customize the look further using view modifiers.


Alternatively if you need more control, you can use openURL @Environment property wrapper in your view, like so:

struct SomeView: View {
    @Environment(\.openURL) var openURL

    var body: some View {
        Button(action: openSettings) {
            Label("Open settings?", systemImage: "gear")
        }
    }

    private func openSettings() {
        openURL(URL(string: UIApplication.openSettingsURLString)!)
    }
}        
Victory answered 7/12, 2021 at 17:55 Comment(0)
P
2

Here is the solution (see answer @rmaddy at [link][1]):

.alert(isPresented: $showLibraryPicker, content: {
            Alert(title: Text("Camera access required to take photos"),
                  message: Text("Go to Settings?"),
                  primaryButton: .default(Text("Settings"),
                                          action: {
                                            let url: String
                                            #if targetEnvironment(macCatalyst)
                                            url = "x-apple.systempreferences:com.apple.preference.security?Privacy_Photos"
                                            #else
                                            url = UIApplication.openSettingsURLString
                                            #endif
                                            UIApplication.shared.open(URL(string: url)!)
                                          }), secondaryButton: .default(Text("Cancel")))
        })


  [1]: https://mcmap.net/q/505462/-is-there-a-way-to-send-the-user-to-the-app-39-s-privacy-settings-under-macos-like-we-do-in-ios
Pickens answered 10/1, 2021 at 21:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.