Comment ouvrir les paramètres du téléphone lorsqu'un bouton est cliqué?

160

J'essaie de mettre en œuvre une fonctionnalité dans une application qui affiche une alerte lorsque la connexion Internet n'est pas disponible. L'alerte comporte deux actions (OK et Paramètres), chaque fois qu'un utilisateur clique sur les paramètres, je souhaite les amener aux paramètres du téléphone par programmation.

J'utilise Swift et Xcode.

Solomon Ayoola
la source

Réponses:

302

En utilisant UIApplication.openSettingsURLString

Mise à jour pour 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
la source
Comment mettre en œuvre cela? @Marius Fanu
Solomon Ayoola
il en utilisant iOS8 @Marius Fanu
Solomon Ayoola
@AyoolaSolomon J'ai mis à jour ma réponse pour ajouter une alerte sur la viewDidAppearméthode, avec le bouton SettingsetCancel
Marius Fanu
2
Non, je ne pense pas. Pour accéder à votre application, votre application doit implémenter un schéma d'URL personnalisé et appeler à UIApplication.sharedApplication().openURL(yourCustomURL)partir de l'application actuelle, mais vous n'avez pas cet accès depuis l'application Paramètres
Marius Fanu
5
@PersianBlue est correct dans iOS 10.1.1 cela ne parvient pas à lancer l'application Paramètres.
Michael Garito
237

⚠️ Soyez prudent!

Cette réponse est basée sur des API non documentées et récemment (depuis iOS12) Apple rejette les applications avec cette approche.

Réponse originale ci-dessous

Swift 5

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

Swift 4

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

REMARQUE: la méthode suivante fonctionne pour toutes les versions inférieures à iOS 11, pour les versions supérieures, l'application peut être rejetée car il s'agit d'une API privée

Parfois, nous voulons amener un utilisateur à des paramètres autres que les paramètres de notre application. La méthode suivante vous aidera à y parvenir:

Tout d'abord, configurez les schémas d'URL dans votre projet. Vous le trouverez dans Target -> Info -> URL Scheme. cliquez sur le bouton + et tapez prefs dans les schémas d'URL

entrez la description de l'image ici

Swift 5

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

Swift 3

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

Rapide

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

Objectif c

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

et voici toutes les URL disponibles

** Sur IOS <12 **

  • prefs: root = General & path = About
  • prefs: root = Général & chemin = ACCESSIBILITÉ
  • prefs: root = AIRPLANE_MODE
  • prefs: root = General & path = AUTOLOCK
  • prefs: root = General & path = USAGE / CELLULAR_USAGE
  • prefs: root = Luminosité
  • prefs: root = Bluetooth
  • prefs: root = General & path = DATE_AND_TIME
  • prefs: root = FACETIME
  • prefs: root = Général
  • prefs: root = Général & chemin = Clavier
  • prefs: root = CASTLE
  • prefs: root = CASTLE & path = STORAGE_AND_BACKUP
  • prefs: root = Général & chemin = INTERNATIONAL
  • prefs: root = LOCATION_SERVICES
  • prefs: root = ACCOUNT_SETTINGS
  • prefs: root = MUSIQUE
  • prefs: root = MUSIC & path = EQ
  • prefs: root = MUSIC & path = VolumeLimit
  • prefs: root = Général & chemin = Réseau
  • prefs: root = NIKE_PLUS_IPOD
  • prefs: root = REMARQUES
  • prefs: root = NOTIFICATIONS_ID
  • prefs: root = Téléphone
  • prefs: root = Photos
  • prefs: root = General & path = ManagedConfigurationList
  • prefs: root = General & path = Reset
  • prefs: root = Sons & chemin = Sonnerie
  • prefs: root = Safari
  • prefs: root = Général & chemin = Assistant
  • prefs: root = Sons
  • prefs: root = General & path = SOFTWARE_UPDATE_LINK
  • prefs: root = STORE
  • prefs: root = TWITTER
  • prefs: root = FACEBOOK
  • prefs: root = General & path = USAGE prefs: root = VIDEO
  • prefs: root = Général & chemin = Réseau / VPN
  • prefs: root = Fond d'écran
  • prefs: root = WIFI
  • prefs: root = INTERNET_TETHERING
  • prefs: root = Téléphone & chemin = Bloqué
  • prefs: root = DO_NOT_DISTURB

Sur IOS 13

  • App-prefs: General & path = À propos
  • Préférences d'application: AIRPLANE_MODE
  • App-prefs: Général & path = AUTOLOCK
  • Préférences d'application: Bluetooth
  • Préférences d'application: Général & path = DATE_AND_TIME
  • Préférences d'application: FACETIME
  • Préférences d'application: Général
  • App-prefs: Général & path = Clavier
  • Préférences d'application: CASTLE
  • Préférences d'application: CASTLE & path = STORAGE_AND_BACKUP
  • App-prefs: Général & chemin = INTERNATIONAL
  • Préférences d'application: MUSIQUE
  • Préférences d'application: REMARQUES
  • Préférences d'application: NOTIFICATIONS_ID
  • Préférences d'application: Téléphone
  • Préférences d'application: Photos
  • App-prefs: Général & path = ManagedConfigurationList
  • App-prefs: Général & chemin = Réinitialiser
  • App-prefs: Sounds & path = Sonnerie
  • Préférences d'application: Sons
  • Préférences d'application: Général & path = SOFTWARE_UPDATE_LINK
  • Préférences d'application: STORE
  • App-prefs: Fond d'écran
  • Préférences d'application: WIFI
  • Préférences d'application: INTERNET_TETHERING
  • Préférences d'application: DO_NOT_DISTURB

    Pas testé

  • Préférences d'application: TWITTER (??)

  • Préférences d'application: FACEBOOK (??)
  • Préférences d'application: NIKE_PLUS_IPOD (??)

Remarque: les paramètres réseau ne seront pas ouverts dans un simulateur, mais le lien fonctionnera sur un appareil réel.

vivek takrani
la source
7
Cela ne fonctionne pas avec iOS 10. Ran le même code sur iOS 9.3. et cela a fonctionné, a fonctionné sur iOS 10 et ce n'est pas le cas (quelle que soit l'url utilisée)
Gruntcakes
18
Pour iOS 10, utilisez App-Prefsau lieu de prefscomme schéma de la chaîne d'URL. par exempleApp-Prefs:root=WIFI
Desmond DAI
8
a récemment révisé une application pour la publier dans l'App Store, et Apple l'a déclinée en raison de l'utilisation de "prefs: root" ou "App-Prefs: root". Je l'ai utilisé pour ouvrir les paramètres wifi, lorsque l'utilisateur n'a pas de connexion Internet.
Marcel T
21
Depuis la sortie prochaine d'iOS 12, Apple rejette les applications qui incluent une telle préférence. Veuillez en être conscient. Même mon application a été rejetée aussi
Thiha Aung
8
NE PAS utiliser App-Prefsou prefs:rootcomme ce sont des API privées, et à moins que vous ne soyez très chanceux, votre application sera rejetée.
Tejas K
45

Dans iOS 8+, vous pouvez effectuer les opérations suivantes:

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

Swift 4

    let settingsUrl = URL(string: UIApplicationOpenSettingsURLString)!
    UIApplication.shared.open(settingsUrl)
Christian
la source
16
Cela vous amène aux paramètres spécifiques de l'application, comment puis-je les amener à la page des paramètres généraux ou encore mieux à la section santé?
Ace Green
2
Swift 3 -UIApplication.shared.openURL(URL(string: UIApplicationOpenSettingsURLString)!)
Aviv Ben Shabat
@AceGreen êtes-vous arrivé à la section santé?
Saad
Comment ouvrir uniquement l'application Paramètres? La "page d'accueil" de celui
Daniel Springer
sans pour autant "!" signURL(string: UIApplication.openSettingsURLString).map { UIApplication.shared.open($0, options: [:], completionHandler: nil) }
ober
21

En utilisant l'indication de @ vivek, je développe une classe d'utils basée sur Swift 3 , j'espère que vous apprécierez!

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)
        }
    }

}

Ceci est très utile car cette API changera à coup sûr et vous pouvez refactoriser une fois et très rapidement!

Luca Davanzo
la source
5
Est-ce que cela passerait par l'examen Apple?
L_Sonic
Je vais ajouter une autre chose pour l'améliorer légèrement. Dans l'énumération, vous pouvez créer une variable de type String avec le nom urlString. Puis renvoyez "App-Prefs: root =" = self.rawValue. Cela supprimera fondamentalement le besoin d'appPath et du let statique privé. À votre santé.
mn1
Les paramètres de notification ne s'ouvrent pas sur iOS 11.
Metin Atalay
2
cela ne fonctionnera pas car nous avons reçu ce message de l'application: "Votre application utilise le schéma d'URL non publique" prefs: root = ", qui est une entité privée. L'utilisation d'API non publiques n'est pas autorisée sur l'App Store car cela peut entraîner une mauvaise expérience utilisateur si ces API changent. Si vous continuez à utiliser ou à masquer des API non publiques dans les futures soumissions de cette application, vous risquez de résilier votre compte de développeur Apple, ainsi que de supprimer toutes les applications associées de l'application. Boutique."
CodeOverRide
1
@L_Sonic non, il ne passera pas l'examen, et si c'est le cas, il pourrait être signalé au hasard dans toutes les futures mises à jour que vous poussez
RP Carson
16

La première réponse des schémas d'URL spécifiques à l' application a fonctionné pour moi sur iOS 10.3.

if let appSettings = URL(string: UIApplicationOpenSettingsURLString + Bundle.main.bundleIdentifier!) {
    if UIApplication.shared.canOpenURL(appSettings) {
      UIApplication.shared.open(appSettings)
    }
  }
inc_london
la source
Qu'est-ce que c'est censé ouvrir?
Daniel Springer
12

App-Prefs:root=Privacy&path=LOCATIONtravaillé pour moi pour accéder aux paramètres de localisation généraux. Remarque: ne fonctionne que sur un appareil.

Joe Susnick
la source
12
Cela est rejeté
Daniel Springer
7

dans ios10 / Xcode 8 dans le simulateur:

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

travaux

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

ne fait pas.

ingconti
la source
Le NSpréfixe a-t-il été supprimé dans iOS 10?
JC Rocamonde
2
Cela ne fonctionnera que si votre application a un fichier .bundle (vos préférences d'application)
Sophy Swicz
@Sophy Swicz Comment puis-je ajouter un fichier .bundle?
Développeur
1
@Developer github.com/phynet/SettingBundleiOSProject également, les paramètres de votre application sont tous les services que votre application permet d'utiliser et sont affichés dans Général -> paramètres de votre application
Sophy Swicz
7

J'ai vu cette ligne de code

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

ne fonctionne pas, cela n'a pas fonctionné pour moi dans ios10 / Xcode 8, juste une petite différence de code, veuillez le remplacer par

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

Swift3

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

Remplacer par

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

J'espère que ça aide. À votre santé.

niravdesai21
la source
1
Causes: Application rejetée
ergunkocak
7

mot d'avertissement: les schémas d'URL prefs:rootou App-Prefs:rootsont considérés comme des API privées. Apple peut rejeter votre application si vous les utilisez, voici ce que vous pouvez obtenir lors de la soumission de votre application:

Votre application utilise le schéma d'URL non public "prefs: root =", qui est une entité privée. L'utilisation d'API non publiques n'est pas autorisée sur l'App Store car elle peut conduire à une mauvaise expérience utilisateur si ces API changent. Continuer à utiliser ou dissimuler des API non publiques dans les futures soumissions de cette application peut entraîner la résiliation de votre compte de développeur Apple, ainsi que la suppression de toutes les applications associées de l'App Store.

Prochaines étapes

Pour résoudre ce problème, veuillez réviser votre application pour fournir la fonctionnalité associée à l'aide des API publiques ou supprimer la fonctionnalité à l'aide du schéma d'URL "prefs: root" ou "App-Prefs: root".

S'il n'y a aucune alternative pour fournir les fonctionnalités requises par votre application, vous pouvez déposer une demande d'amélioration.

ofer
la source
Il n'y a pas de moyen pris en charge d'ouvrir les paramètres sur la page Wi-Fi / Langue / Emplacement. Le fait que cela a fonctionné sous iOS 9 est un bogue qui a été corrigé dans iOS 10. Pour plus d'informations, veuillez consulter forums.developer.apple.com/message/186656#186656
Mohit Kumar
6

Swift 4.2, iOS 12

La open(url:options:completionHandler:)méthode a été mise à jour pour inclure un dictionnaire d'options non nul, qui à partir de cet article ne contient qu'une seule option possible de type UIApplication.OpenExternalURLOptionsKey(dans l'exemple).

@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)

}

La construction explicite d'une URL, comme avec "App-Prefs", a, AFAIK, obtenu le rejet de certaines applications du magasin.

bsod
la source
Je confirme cela, l'application fonctionnait bien avec "App-Prefs" avant, mais après l'événement spécial d'Apple, ma mise à jour a été rejetée, revenant à UIApplicationOpenSettingsURLString.
Vitalii
5

Ajout à @Luca Davanzo

iOS 11, certains paramètres d'autorisation ont été déplacés vers le chemin de l'application:

Prise en charge d'iOS 11

 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
la source
2
cela peut-il passer par Apple Review? Je veux dire, cela mènera-t-il au rejet de l'application?
Aakash Dave
4
lorsque j'exécute ce code, je m'amène simplement à la page des paramètres. Pas l'onglet des paramètres spécifiques.
Aakash Dave
2

SWIFT 4

Cela peut prendre les paramètres spécifiques de votre application, si c'est ce que vous recherchez.

UIApplication.shared.openURL(URL(string: UIApplicationOpenSettingsURLString)!)
BennyTheNerd
la source
merci ... je fais fonctionner cela ... mais je veux modifier les paramètres sur les applications qui sont par d'autres développeurs. Par exemple, appuyez sur un bouton et modifiez les paramètres de notification Push de Facebook afin qu'ils ne transmettent pas de message pendant une réunion. Je prédis qu'il pourrait y avoir des solutions MDM ... ou pas.
IrishGringo
@IrishGringo, le seul moyen de modifier les paramètres de l'application Facebook est que l'utilisateur ouvre les paramètres de l'application Facebook lui-même en naviguant via les paramètres généraux >> Notifications >> Facebook
BennyTheNerd
0

Comme ci-dessus, @niravdesai a déclaré App-prefs. J'ai trouvé que cela App-Prefs:fonctionne pour les appareils iOS 9, 10 et 11. testés. où comme prefs:fonctionne uniquement sur iOS 9.

Alix
la source