Wie öffne ich Telefoneinstellungen, wenn auf eine Schaltfläche geklickt wird?

159

Ich versuche, eine Funktion in einer App zu implementieren, die eine Warnung anzeigt, wenn die Internetverbindung nicht verfügbar ist. Die Warnung hat zwei Aktionen (OK und Einstellungen). Wenn ein Benutzer auf Einstellungen klickt, möchte ich sie programmgesteuert zu den Telefoneinstellungen führen.

Ich benutze Swift und Xcode.

Solomon Ayoola
quelle

Antworten:

300

Verwenden von UIApplication.openSettingsURLString

Update für Swift 5.1

 override func viewDidAppear(_ animated: Bool) {
    let alertController = UIAlertController (title: "Title", message: "Go to Settings?", preferredStyle: .alert)

    let settingsAction = UIAlertAction(title: "Settings", style: .default) { (_) -> Void in

        guard let settingsUrl = URL(string: UIApplication.openSettingsURLString) else {
            return
        }

        if UIApplication.shared.canOpenURL(settingsUrl) {
            UIApplication.shared.open(settingsUrl, completionHandler: { (success) in
                print("Settings opened: \(success)") // Prints true
            })
        }
    }
    alertController.addAction(settingsAction)
    let cancelAction = UIAlertAction(title: "Cancel", style: .default, handler: nil)
    alertController.addAction(cancelAction)

    present(alertController, animated: true, completion: nil)
}

Swift 4.2

override func viewDidAppear(_ animated: Bool) {
    let alertController = UIAlertController (title: "Title", message: "Go to Settings?", preferredStyle: .alert)

    let settingsAction = UIAlertAction(title: "Settings", style: .default) { (_) -> Void in

        guard let settingsUrl = URL(string: UIApplicationOpenSettingsURLString) else {
            return
        }

        if UIApplication.shared.canOpenURL(settingsUrl) {
            UIApplication.shared.open(settingsUrl, completionHandler: { (success) in
                print("Settings opened: \(success)") // Prints true
            })
        }
    }
    alertController.addAction(settingsAction)
    let cancelAction = UIAlertAction(title: "Cancel", style: .default, handler: nil)
    alertController.addAction(cancelAction)

    present(alertController, animated: true, completion: nil)
}
Marius Fanu
quelle
Wie setze ich das um? @ Marius Fanu
Solomon Ayoola
es mit iOS8 @Marius Fanu
Solomon Ayoola
@ AyoolaSolomon Ich habe meine Antwort aktualisiert, um eine Warnung zur viewDidAppearMethode hinzuzufügen , mit der Schaltfläche SettingsundCancel
Marius Fanu
2
Nein, das glaube ich nicht. Um zu Ihrer App zu gelangen, sollte Ihre Anwendung ein benutzerdefiniertes URL-Schema implementieren und das UIApplication.sharedApplication().openURL(yourCustomURL)von der aktuellen App aus aufrufen , aber Sie haben diesen Zugriff nicht über die Einstellungen-App
Marius Fanu
5
@PersianBlue ist in iOS 10.1.1 korrekt. Dadurch kann die Einstellungen-App nicht gestartet werden.
Michael Garito
237

⚠️ Sei vorsichtig!

Diese Antwort basiert auf undokumentierten APIs und seit kurzem (seit iOS12) lehnt Apple Apps mit diesem Ansatz ab.

Ursprüngliche Antwort unten

Swift 5

UIApplication.shared.open(URL(string: UIApplication.openSettingsURLString)!, options: [:], completionHandler: nil)

Swift 4

UIApplication.shared.open(URL(string: UIApplicationOpenSettingsURLString)!, options: [:], completionHandler: nil)

HINWEIS: Die folgende Methode funktioniert für alle Versionen unter iOS 11, für höhere Versionen wird die App möglicherweise abgelehnt, da es sich um eine private API handelt

Manchmal möchten wir einen Benutzer zu anderen Einstellungen als unseren App-Einstellungen führen. Die folgende Methode hilft Ihnen dabei:

Konfigurieren Sie zunächst die URL-Schemata in Ihrem Projekt. Sie finden es unter Ziel -> Info -> URL-Schema. Klicken Sie auf die Schaltfläche + und geben Sie die Einstellungen in URL-Schemata ein

Geben Sie hier die Bildbeschreibung ein

Swift 5

UIApplication.shared.open(URL(string: "App-prefs:Bluetooth")!)

Swift 3

UIApplication.shared.open(URL(string:"App-Prefs:root=General")!, options: [:], completionHandler: nil)

Schnell

UIApplication.sharedApplication().openURL(NSURL(string:"prefs:root=General")!)

Ziel c

[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"prefs:root=General"]];

und im Folgenden sind alle verfügbaren URLs aufgeführt

** Auf IOS <12 **

  • Einstellungen: root = Allgemein & Pfad = Info
  • Einstellungen: root = Allgemein & Pfad = ZUGÄNGLICHKEIT
  • Einstellungen: root = AIRPLANE_MODE
  • Einstellungen: root = General & path = AUTOLOCK
  • Einstellungen: root = General & path = USAGE / CELLULAR_USAGE
  • Einstellungen: root = Helligkeit
  • Einstellungen: root = Bluetooth
  • Einstellungen: root = General & path = DATE_AND_TIME
  • Einstellungen: root = FACETIME
  • Einstellungen: root = Allgemein
  • Einstellungen: root = Allgemein & Pfad = Tastatur
  • Einstellungen: root = CASTLE
  • Einstellungen: root = CASTLE & path = STORAGE_AND_BACKUP
  • Einstellungen: root = General & path = INTERNATIONAL
  • Einstellungen: root = LOCATION_SERVICES
  • Einstellungen: root = ACCOUNT_SETTINGS
  • Einstellungen: root = MUSIC
  • Einstellungen: root = MUSIC & path = EQ
  • Einstellungen: root = MUSIC & path = VolumeLimit
  • Einstellungen: root = Allgemein & Pfad = Netzwerk
  • Einstellungen: root = NIKE_PLUS_IPOD
  • Einstellungen: root = NOTES
  • Einstellungen: root = NOTIFICATIONS_ID
  • Einstellungen: root = Telefon
  • Einstellungen: root = Fotos
  • Einstellungen: root = General & path = ManagedConfigurationList
  • Einstellungen: root = Allgemein & Pfad = Zurücksetzen
  • Einstellungen: root = Sounds & path = Klingelton
  • Einstellungen: root = Safari
  • Einstellungen: root = Allgemein & Pfad = Assistent
  • Einstellungen: root = Sounds
  • Einstellungen: root = General & path = SOFTWARE_UPDATE_LINK
  • Einstellungen: root = STORE
  • Einstellungen: root = TWITTER
  • Einstellungen: root = FACEBOOK
  • Einstellungen: root = Allgemein & Pfad = USAGE Einstellungen: root = VIDEO
  • Einstellungen: root = Allgemein & Pfad = Netzwerk / VPN
  • Einstellungen: root = Wallpaper
  • Einstellungen: root = WIFI
  • Einstellungen: root = INTERNET_TETHERING
  • Einstellungen: root = Telefon & Pfad = blockiert
  • Einstellungen: root = DO_NOT_DISTURB

Auf IOS 13

  • App-Einstellungen: Allgemein & Pfad = Info
  • App-Einstellungen: AIRPLANE_MODE
  • App-Einstellungen: Allgemein & Pfad = AUTOLOCK
  • App-Einstellungen: Bluetooth
  • App-Einstellungen: Allgemein & Pfad = DATE_AND_TIME
  • App-Einstellungen: FACETIME
  • App-Einstellungen: Allgemein
  • App-Einstellungen: Allgemein & Pfad = Tastatur
  • App-Einstellungen: SCHLOSS
  • App-Einstellungen: CASTLE & path = STORAGE_AND_BACKUP
  • App-Einstellungen: Allgemein & Pfad = INTERNATIONAL
  • App-Einstellungen: MUSIK
  • App-Einstellungen: HINWEISE
  • App-Einstellungen: NOTIFICATIONS_ID
  • App-Einstellungen: Telefon
  • App-Einstellungen: Fotos
  • App-Einstellungen: Allgemein & path = ManagedConfigurationList
  • App-Einstellungen: Allgemein & Pfad = Zurücksetzen
  • App-Einstellungen: Sounds & Pfad = Klingelton
  • App-Einstellungen: Sounds
  • App-Einstellungen: Allgemein & path = SOFTWARE_UPDATE_LINK
  • App-Einstellungen: STORE
  • App-Einstellungen: Hintergrundbild
  • App-Einstellungen: WIFI
  • App-Einstellungen: INTERNET_TETHERING
  • App-Einstellungen: DO_NOT_DISTURB

    Nicht getestet

  • App-Einstellungen: TWITTER (??)

  • App-Einstellungen: FACEBOOK (??)
  • App-Einstellungen: NIKE_PLUS_IPOD (??)

Hinweis: Die Netzwerkeinstellungen werden in einem Simulator nicht geöffnet, die Verbindung funktioniert jedoch auf einem realen Gerät.

vivek takrani
quelle
7
Dies funktioniert nicht mit iOS 10. Auf iOS 9.3 wurde derselbe Code ausgeführt. und es hat funktioniert, lief auf iOS 10 und es hat nicht (unabhängig davon, welche URL verwendet wird)
Gruntcakes
18
Verwenden Sie für iOS 10 App-Prefsanstelle von prefsals Schema der URL-Zeichenfolge. zBApp-Prefs:root=WIFI
Desmond DAI
8
Vor kurzem wurde eine App überprüft, um sie im App Store zu veröffentlichen, und Apple lehnte sie aufgrund der Verwendung von "prefs: root" oder "App-Prefs: root" ab. Ich habe es verwendet, um die WLAN-Einstellungen zu öffnen, wenn der Benutzer keine Internetverbindung hat.
Marcel T
21
Seit iOS 12 bald herauskommt, lehnt Apple App ab, die solche Voreinstellungen enthält. Bitte beachten Sie dies. Sogar meine App wurde abgelehnt
Thiha Aung
8
Verwenden Sie NICHT App-Prefsoder prefs:rootda es sich um private APIs handelt. Wenn Sie kein großes Glück haben, wird Ihre App abgelehnt.
Tejas K
45

In iOS 8+ können Sie Folgendes tun:

 func buttonClicked(sender:UIButton)
    {
        UIApplication.sharedApplication().openURL(NSURL(string: UIApplicationOpenSettingsURLString))
    }

Swift 4

    let settingsUrl = URL(string: UIApplicationOpenSettingsURLString)!
    UIApplication.shared.open(settingsUrl)
Christian
quelle
16
Hiermit gelangen Sie zu den app-spezifischen Einstellungen. Wie kann ich sie zur Seite mit den allgemeinen Einstellungen oder noch besser zum Abschnitt "Gesundheit" führen?
Ace Green
2
Swift 3 -UIApplication.shared.openURL(URL(string: UIApplicationOpenSettingsURLString)!)
Aviv Ben Shabat
@AceGreen hast du es in den Gesundheitsbereich geschafft?
Saad
Wie öffnest du nur die App Einstellungen? Die "Homepage" davon
Daniel Springer
ohne "!" ZeichenURL(string: UIApplication.openSettingsURLString).map { UIApplication.shared.open($0, options: [:], completionHandler: nil) }
ober
21

Mit dem Hinweis von @ vivek entwickle ich eine Utils-Klasse, die auf Swift 3 basiert. Ich hoffe, Sie wissen das zu schätzen!

import Foundation
import UIKit

public enum PreferenceType: String {

    case about = "General&path=About"
    case accessibility = "General&path=ACCESSIBILITY"
    case airplaneMode = "AIRPLANE_MODE"
    case autolock = "General&path=AUTOLOCK"
    case cellularUsage = "General&path=USAGE/CELLULAR_USAGE"
    case brightness = "Brightness"
    case bluetooth = "Bluetooth"
    case dateAndTime = "General&path=DATE_AND_TIME"
    case facetime = "FACETIME"
    case general = "General"
    case keyboard = "General&path=Keyboard"
    case castle = "CASTLE"
    case storageAndBackup = "CASTLE&path=STORAGE_AND_BACKUP"
    case international = "General&path=INTERNATIONAL"
    case locationServices = "LOCATION_SERVICES"
    case accountSettings = "ACCOUNT_SETTINGS"
    case music = "MUSIC"
    case equalizer = "MUSIC&path=EQ"
    case volumeLimit = "MUSIC&path=VolumeLimit"
    case network = "General&path=Network"
    case nikePlusIPod = "NIKE_PLUS_IPOD"
    case notes = "NOTES"
    case notificationsId = "NOTIFICATIONS_ID"
    case phone = "Phone"
    case photos = "Photos"
    case managedConfigurationList = "General&path=ManagedConfigurationList"
    case reset = "General&path=Reset"
    case ringtone = "Sounds&path=Ringtone"
    case safari = "Safari"
    case assistant = "General&path=Assistant"
    case sounds = "Sounds"
    case softwareUpdateLink = "General&path=SOFTWARE_UPDATE_LINK"
    case store = "STORE"
    case twitter = "TWITTER"
    case facebook = "FACEBOOK"
    case usage = "General&path=USAGE"
    case video = "VIDEO"
    case vpn = "General&path=Network/VPN"
    case wallpaper = "Wallpaper"
    case wifi = "WIFI"
    case tethering = "INTERNET_TETHERING"
    case blocked = "Phone&path=Blocked"
    case doNotDisturb = "DO_NOT_DISTURB"

}

enum PreferenceExplorerError: Error {
    case notFound(String)
}

open class PreferencesExplorer {

    // MARK: - Class properties -

    static private let preferencePath = "App-Prefs:root"

    // MARK: - Class methods -

    static func open(_ preferenceType: PreferenceType) throws {
        let appPath = "\(PreferencesExplorer.preferencePath)=\(preferenceType.rawValue)"
        if let url = URL(string: appPath) {
            if #available(iOS 10.0, *) {
                UIApplication.shared.open(url, options: [:], completionHandler: nil)
            } else {
               UIApplication.shared.openURL(url)
            }
        } else {
            throw PreferenceExplorerError.notFound(appPath)
        }
    }

}

Dies ist sehr hilfreich, da sich die APIs mit Sicherheit ändern und Sie sie einmal und sehr schnell umgestalten können!

Luca Davanzo
quelle
5
Würde dies durch Apple Review gehen?
L_Sonic
Ich werde noch etwas hinzufügen, um es etwas besser zu machen. In der Aufzählung können Sie eine Variable vom Typ String mit dem Namen urlString erstellen. Geben Sie dann "App-Prefs: root =" = self.rawValue zurück. Dadurch entfällt im Wesentlichen die Notwendigkeit für appPath und die statische private Vermietung. Prost.
Mn1
Die Benachrichtigungseinstellungen werden unter iOS 11 nicht geöffnet.
Metin Atalay
2
Dies funktioniert nicht, da wir die folgende Meldung von der App erhalten haben: "Ihre App verwendet das nicht öffentliche URL-Schema" prefs: root = ", bei dem es sich um eine private Entität handelt. Die Verwendung nicht öffentlicher APIs ist im App Store nicht zulässig, da Wenn sich diese APIs ändern, kann dies zu einer schlechten Benutzererfahrung führen. Wenn Sie nicht öffentliche APIs in zukünftigen Übermittlungen dieser App weiterhin verwenden oder verbergen, kann dies zur Kündigung Ihres Apple Developer-Kontos und zum Entfernen aller zugehörigen Apps aus der App führen Geschäft."
CodeOverRide
1
@L_Sonic nein, es wird die Überprüfung nicht bestehen, und wenn dies der Fall ist, könnte es in zukünftigen Updates, die Sie veröffentlichen, zufällig markiert werden
RP Carson
16

Die erste Antwort von App-spezifischen URL-Schemata funktionierte für mich unter iOS 10.3.

if let appSettings = URL(string: UIApplicationOpenSettingsURLString + Bundle.main.bundleIdentifier!) {
    if UIApplication.shared.canOpenURL(appSettings) {
      UIApplication.shared.open(appSettings)
    }
  }
inc_london
quelle
Was soll das öffnen?
Daniel Springer
12

App-Prefs:root=Privacy&path=LOCATIONarbeitete für mich, um zu den allgemeinen Standorteinstellungen zu gelangen. Hinweis: Funktioniert nur auf einem Gerät.

Joe Susnick
quelle
12
Dies wird abgelehnt
Daniel Springer
7

in ios10 / Xcode 8 im Simulator:

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

funktioniert

UIApplication.shared.openURL(URL(string:"prefs:root=General")!)

nicht.

ingconti
quelle
Wurde das NSPräfix in iOS 10 entfernt?
JC Rocamonde
2
Dies funktioniert nur, wenn Ihre App eine .bundle-Datei hat (Ihre App-
Einstellungen
@Sophy Swicz Wie kann ich eine .bundle-Datei hinzufügen?
Entwickler
1
@Developer github.com/phynet/SettingBundleiOSProject Auch Ihre App-Einstellungen sind alle Dienste, die Ihre App verwenden kann und werden in Allgemein -> Einstellungen Ihrer App
Sophy Swicz
7

Ich habe diese Codezeile gesehen

UIApplication.sharedApplication() .openURL(NSURL(string:"prefs:root=General")!)

funktioniert nicht, es hat bei ios10 / Xcode 8 nicht funktioniert, nur ein kleiner Codeunterschied, bitte ersetzen Sie diesen durch

UIApplication.sharedApplication().openURL(NSURL(string:"App-Prefs:root=General")!)

Swift3

UIApplication.shared.openURL(URL(string:"prefs:root=General")!)

Ersetzen mit

UIApplication.shared.openURL(URL(string:"App-Prefs:root=General")!)

Ich hoffe es hilft. Prost.

niravdesai21
quelle
1
Ursachen: App abgelehnt
Ergunkocak
7

Wort der Warnung: Die prefs:rootoder App-Prefs:rootURL-Schemata werden als private API betrachtet. Apple kann Ihre App ablehnen, wenn Sie diese verwenden. Folgendes erhalten Sie möglicherweise, wenn Sie Ihre App einreichen:

Ihre App verwendet das nicht öffentliche URL-Schema "prefs: root =", bei dem es sich um eine private Entität handelt. Die Verwendung nicht öffentlicher APIs ist im App Store nicht zulässig, da dies zu einer schlechten Benutzererfahrung führen kann, wenn sich diese APIs ändern. Die weitere Verwendung oder Verschleierung nicht öffentlicher APIs in zukünftigen Einsendungen dieser App kann zur Kündigung Ihres Apple Developer-Kontos sowie zur Entfernung aller zugehörigen Apps aus dem App Store führen.

Nächste Schritte

Um dieses Problem zu beheben, überarbeiten Sie bitte Ihre App, um die zugehörigen Funktionen mithilfe öffentlicher APIs bereitzustellen, oder entfernen Sie die Funktionen mithilfe des URL-Schemas "prefs: root" oder "App-Prefs: root".

Wenn es keine Alternativen für die Bereitstellung der für Ihre App erforderlichen Funktionen gibt, können Sie eine Erweiterungsanforderung einreichen.

ofer
quelle
Es gibt keine unterstützte Möglichkeit, Einstellungen auf der Seite "WLAN / Sprache / Standort" zu öffnen. Die Tatsache, dass dies in iOS 9 funktioniert hat, ist ein Fehler, der in iOS 10 behoben wurde. Weitere Informationen finden Sie unter forums.developer.apple.com/message/186656#186656
Mohit Kumar
6

Swift 4.2, iOS 12

Die open(url:options:completionHandler:)Methode wurde aktualisiert und enthält ein Nicht-Null-Optionswörterbuch, das ab diesem Beitrag nur eine mögliche Typoption enthält UIApplication.OpenExternalURLOptionsKey(im Beispiel).

@objc func openAppSpecificSettings() {

    guard let url = URL(string: UIApplication.openSettingsURLString),
        UIApplication.shared.canOpenURL(url) else {
            return
    }

    let optionsKeyDictionary = [UIApplication.OpenExternalURLOptionsKey(rawValue: "universalLinksOnly"): NSNumber(value: true)]

    UIApplication.shared.open(url, options: optionsKeyDictionary, completionHandler: nil)

}

Durch das explizite Erstellen einer URL, beispielsweise mit "App-Prefs", hat AFAIK einige Apps aus dem Store abgelehnt.

bsod
quelle
Ich bestätige dies, die App war zuvor mit "App-Prefs" in Ordnung, aber nach Apples Special Event wurde mein Update abgelehnt und fiel auf UIApplicationOpenSettingsURLString zurück.
Vitalii
5

Hinzufügen zu @Luca Davanzo

In iOS 11 wurden einige Berechtigungseinstellungen in den App-Pfad verschoben:

iOS 11-Unterstützung

 static func open(_ preferenceType: PreferenceType) throws {
    var preferencePath: String
    if #available(iOS 11.0, *), preferenceType == .video || preferenceType == .locationServices || preferenceType == .photos {
        preferencePath = UIApplicationOpenSettingsURLString
    } else {
        preferencePath = "\(PreferencesExplorer.preferencePath)=\(preferenceType.rawValue)"
    }

    if let url = URL(string: preferencePath) {
        if #available(iOS 10.0, *) {
            UIApplication.shared.open(url, options: [:], completionHandler: nil)
        } else {
            UIApplication.shared.openURL(url)
        }
    } else {
        throw PreferenceExplorerError.notFound(preferencePath)
    }
}
Tal Zion
quelle
2
Kann dies durch Apple Review gehen? Ich meine, wird dies zur Ablehnung der App führen?
Aakash Dave
4
Wenn ich diesen Code ausführe, gehe ich einfach zur Einstellungsseite. Nicht die Registerkarte mit den spezifischen Einstellungen.
Aakash Dave
2

SWIFT 4

Dies kann die spezifischen Einstellungen Ihrer App erfordern, wenn Sie danach suchen.

UIApplication.shared.openURL(URL(string: UIApplicationOpenSettingsURLString)!)
BennyTheNerd
quelle
danke ... ich habe das funktioniert ... aber ich möchte Einstellungen für Apps ändern, die von anderen Entwicklern stammen. Drücken Sie beispielsweise eine Taste und ändern Sie die Push-Benachrichtigungseinstellungen von Facebook, damit während eines Meetings keine Nachrichten gesendet werden. Ich gehe davon aus, dass es MDM-Lösungen geben könnte ... oder nicht.
IrishGringo
@IrishGringo Die einzige Möglichkeit, die Einstellungen der Facebook-App zu ändern, besteht darin, dass der Benutzer die Einstellungen der Facebook-App selbst öffnet, indem er über die allgemeinen Einstellungen >> Benachrichtigungen >> Facebook
BennyTheNerd
0

Wie oben @niravdesai sagte App-Prefs. Ich fand, dass dies App-Prefs:sowohl für iOS 9, 10 als auch für 11 getestete Geräte funktioniert. wo wie prefs:nur unter iOS 9 funktioniert.

Alix
quelle