Come faccio ad aprire le impostazioni del telefono quando si fa clic su un pulsante?


160

Sto cercando di implementare una funzione in un'app che mostra un avviso quando la connessione Internet non è disponibile. L'avviso ha due azioni (OK e Impostazioni), ogni volta che un utente fa clic sulle impostazioni, voglio portarle alle impostazioni del telefono a livello di codice.

Sto usando Swift e Xcode.

Risposte:


301

utilizzando UIApplication.openSettingsURLString

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

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

Come lo implemento? @Marius Fanu
Solomon Ayoola il

usando iOS8 @Marius Fanu
Solomon Ayoola il

@AyoolaSolomon Ho aggiornato la mia risposta per aggiungere un avviso sul viewDidAppearmetodo, con il pulsante SettingseCancel
Marius Fanu,

2
No, non credo. Per UIApplication.sharedApplication().openURL(yourCustomURL)accedere all'app, l'applicazione deve implementare uno schema URL personalizzato e chiamare l' app dall'app corrente, ma non hai tale accesso dall'app Impostazioni
Marius Fanu,

5
@PersianBlue è corretto in iOS 10.1.1 questo non riesce ad avviare l'app Impostazioni.
Michael Garito,

237

⚠️ Stai attento!

Questa risposta si basa su API non documentate e di recente (dal momento che iOS12) Apple sta rifiutando le app con questo approccio.

Risposta originale di seguito

Swift 5

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

Swift 4

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

NOTA: il seguente metodo funziona per tutte le versioni sotto iOS 11, per le versioni successive l'app potrebbe essere rifiutata poiché è un'API privata

A volte vogliamo portare un utente a impostazioni diverse da quelle della nostra app. Il seguente metodo ti aiuterà a raggiungere questo obiettivo:

Innanzitutto, configura gli schemi URL nel tuo progetto. Lo troverai in Target -> Informazioni -> Schema URL. fai clic sul pulsante + e digita le preferenze in Schemi URL

inserisci qui la descrizione dell'immagine

Swift 5

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

Swift 3

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

veloce

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

Objective-C

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

e seguenti sono tutti gli URL disponibili

** Su IOS <12 **

  • prefs: root = Generale & path = Chi
  • prefs: root = Generale & path = ACCESSIBILITA '
  • prefs: root = AIRPLANE_MODE
  • prefs: root = Generale & path = AUTOLOCK
  • prefs: root = Generale & path = UTILIZZO / CELLULAR_USAGE
  • prefs: root = Luminosità
  • prefs: root = Bluetooth
  • prefs: root = Generale & path = DATE_AND_TIME
  • prefs: root = FaceTime
  • prefs: root = Generale
  • prefs: root = Generale & path = Keyboard
  • prefs: root = CASTELLO
  • prefs: root = Castle & path = STORAGE_AND_BACKUP
  • prefs: root = Generale & path = INTERNATIONAL
  • prefs: radice = LOCATION_SERVICES
  • prefs: radice = ACCOUNT_SETTINGS
  • prefs: root = MUSIC
  • prefs: root = MUSIC & path = EQ
  • prefs: root = MUSIC & path = VolumeLimit
  • prefs: root = Generale & path = Network
  • prefs: root = NIKE_PLUS_IPOD
  • prefs: radice = NOTE
  • prefs: root = NOTIFICATIONS_ID
  • prefs: root = Telefono
  • prefs: radice = Foto
  • prefs: root = Generale & path = ManagedConfigurationList
  • prefs: root = Generale & path = Ripristina
  • prefs: radice = Suoni e percorso = Ringtone
  • prefs: root = Safari
  • prefs: root = Generale & path = Assistant
  • prefs: radice = Suoni
  • prefs: root = Generale & path = SOFTWARE_UPDATE_LINK
  • prefs: root = STORE
  • prefs: root = TWITTER
  • prefs: root = FACEBOOK
  • prefs: root = Generale & percorso = UTILIZZO prefs: root = VIDEO
  • prefs: root = Generale & path = Network / VPN
  • prefs: root = Wallpaper
  • prefs: root = WIFI
  • prefs: root = INTERNET_TETHERING
  • prefs: root = Phone & path = bloccati
  • prefs: root = DO_NOT_DISTURB

Su IOS 13

  • App-prefs: generali e percorso = Informazioni
  • App-prefs: AIRPLANE_MODE
  • App-prefs: General & path = AUTOLOCK
  • App-prefs: Bluetooth
  • App-prefs: General & path = DATE_AND_TIME
  • App-prefs: FaceTime
  • App-preferenze: Generali
  • App-prefs: General & path = Keyboard
  • App-prefs: CASTELLO
  • App-prefs: Castle & path = STORAGE_AND_BACKUP
  • App-prefs: General & path = INTERNATIONAL
  • App-prefs: Musica
  • App-prefs: NOTE
  • App-prefs: NOTIFICATIONS_ID
  • App-prefs: Telefono
  • App-prefs: Foto
  • App-prefs: General & path = ManagedConfigurationList
  • App-prefs: General & path = Ripristina
  • App-prefs: Suoni & path = Ringtone
  • App-prefs: Suoni
  • App-prefs: General & path = SOFTWARE_UPDATE_LINK
  • App-prefs: NEGOZIO
  • App-prefs: Carta da parati
  • App-prefs: WIFI
  • App-prefs: INTERNET_TETHERING
  • App-prefs: DO_NOT_DISTURB

    Non testato

  • Pre-app: TWITTER (??)

  • Pre-app: FACEBOOK (??)
  • Pre-app: NIKE_PLUS_IPOD (??)

Nota: le impostazioni di rete non verranno aperte in un simulatore, ma il collegamento funzionerà su un dispositivo reale.


7
Questo non funziona con iOS 10. È stato eseguito lo stesso codice su iOS 9.3. e ha funzionato, funzionava su iOS 10 e non ha funzionato (indipendentemente
dall'URL

18
Per iOS 10, utilizzare App-Prefsinvece prefscome schema della stringa URL. ad es.App-Prefs:root=WIFI
Desmond DAI,

8
recentemente ha rivisto un'app per rilasciarla sull'App Store e Apple l'ha rifiutata a causa dell'uso di "prefs: root" o "App-Prefs: root". L'ho usato per aprire le impostazioni wifi, quando l'utente non ha una connessione a Internet.
Marcel T,

21
Da quando iOS 12 uscirà presto, l'app di rifiuto di Apple che include tale pref. Si prega di essere consapevoli di esso. Anche la mia app è stata respinta
Thiha Aung,

8
NON utilizzare App-Prefso prefs:rootpoiché si tratta di API private e, a meno che tu non sia molto fortunato, l'app verrà rifiutata.
Tejas K,

45

In iOS 8+ puoi fare quanto segue:

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

Swift 4

    let settingsUrl = URL(string: UIApplicationOpenSettingsURLString)!
    UIApplication.shared.open(settingsUrl)

16
Questo ti porta alle impostazioni specifiche dell'app, come posso portarle alla pagina delle impostazioni generali o ancora meglio alla sezione salute?
Ace Green,

2
Swift 3 -UIApplication.shared.openURL(URL(string: UIApplicationOpenSettingsURLString)!)
Aviv Ben Shabat,

@AceGreen sei arrivato alla sezione salute?
Saad,

Come si apre solo l'app Impostazioni? La "Home page" di esso
Daniel Springer

senza "!" segnoURL(string: UIApplication.openSettingsURLString).map { UIApplication.shared.open($0, options: [:], completionHandler: nil) }
ober

21

Usando il suggerimento di @ vivek, sviluppo una classe utils basata su Swift 3 , spero che apprezzerai!

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

}

Questo è molto utile dal momento che le API cambieranno di sicuro e puoi eseguire il refactoring una volta e molto velocemente!


5
Questo passerebbe attraverso la revisione delle mele?
L_Sonic,

Ho intenzione di aggiungere un'altra cosa per renderla leggermente migliore. Nell'enum, puoi creare una variabile di tipo String con il nome urlString. Quindi restituire "App-Prefs: root =" = self.rawValue. Ciò eliminerà sostanzialmente la necessità di appPath e di let privato privato. Saluti.
mn 1

Le impostazioni di notifica non si aprono su iOS 11.
Metin Atalay

2
questo non funzionerà poiché abbiamo ricevuto questo messaggio dall'app: "La tua app utilizza lo schema URL non pubblico" prefs: root = ", che è un'entità privata. L'uso di API non pubbliche non è consentito sull'App Store perché può portare a un'esperienza utente scadente nel caso in cui queste API cambino. Continuare a utilizzare o nascondere API non pubbliche in futuri invii di questa app può comportare la chiusura del proprio account Apple Developer, nonché la rimozione di tutte le app associate dall'app Negozio."
CodeOverRide,

1
@L_Sonic no, non passerà la recensione e, in tal caso, potrebbe essere contrassegnato in modo casuale in eventuali aggiornamenti futuri che spingi
RP Carson,

16

La prima risposta da Schemi URL specifici per app ha funzionato per me su iOS 10.3.

if let appSettings = URL(string: UIApplicationOpenSettingsURLString + Bundle.main.bundleIdentifier!) {
    if UIApplication.shared.canOpenURL(appSettings) {
      UIApplication.shared.open(appSettings)
    }
  }

Cosa dovrebbe aprire questo?
Daniel Springer,

12

App-Prefs:root=Privacy&path=LOCATIONha funzionato per me per arrivare alle impostazioni generali della posizione. Nota: funziona solo su un dispositivo.


12
Questo viene respinto
Daniel Springer,

7

in ios10 / Xcode 8 nel simulatore:

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

lavori

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

non.


Il NSprefisso è stato rimosso in iOS 10?
JC Rocamonde,

2
Funzionerà solo se la tua app ha un file .bundle (le tue preferenze dell'app)
Sophy Swicz,

@Sophy Swicz HOw posso aggiungere il file .bundle?
Sviluppatore

1
@Developer github.com/phynet/SettingBundleiOSProject anche, le impostazioni della tua app sono tutti i servizi che la tua app consente di utilizzare e sono mostrate in Generale -> impostazioni della tua app
Sophy Swicz

7

Ho visto questa riga di codice

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

non funziona, non ha funzionato per me in ios10 / Xcode 8, solo una piccola differenza di codice, si prega di sostituirlo con

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

Swift3

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

Sostituirlo con

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

Spero che sia d'aiuto. Saluti.


1
Cause: App respinta
ergunkocak

7

avvertenza: gli schemi URL prefs:rooto App-Prefs:rootsono considerati API private. Apple potrebbe rifiutare la tua app se le usi, ecco cosa potresti ottenere quando invii la tua app:

L'app utilizza lo schema URL non pubblico "prefs: root =", che è un'entità privata. L'uso di API non pubbliche non è consentito sull'App Store perché può causare un'esperienza utente scadente qualora tali API cambino. Continuare a utilizzare o nascondere API non pubbliche in futuri invii di questa app può comportare la chiusura del proprio account Apple Developer, nonché la rimozione di tutte le app associate dall'App Store.

Prossimi passi

Per risolvere questo problema, rivedi la tua app per fornire la funzionalità associata utilizzando le API pubbliche o rimuovila utilizzando lo schema URL "prefs: root" o "Prefs app: root".

Se non ci sono alternative per fornire le funzionalità richieste dalla tua app, puoi presentare una richiesta di miglioramento.


Non esiste un modo supportato per aprire le impostazioni nella 'pagina' Wi-Fi / Lingua / Posizione. Il fatto che ciò abbia funzionato in iOS 9 è un bug che è stato corretto in iOS 10. Per maggiori informazioni, consultare il forum.developer.apple.com/message/186656#186656
Mohit Kumar,

6

Swift 4.2, iOS 12

Il open(url:options:completionHandler:)metodo è stato aggiornato per includere un dizionario di opzioni diverso da zero, che a partire da questo post contiene solo una possibile opzione di tipo UIApplication.OpenExternalURLOptionsKey(nell'esempio).

@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 costruzione esplicita di un URL, come "App-Prefs", ha fatto sì che AFAIK abbia rifiutato alcune app dallo store.


Lo confermo, l'app andava bene con "App-Prefs" in precedenza, ma dopo l'evento speciale di Apple il mio aggiornamento è stato rifiutato, tornando a UIApplicationOpenSettingsURLString.
Vitalii,

5

Aggiunta a @Luca Davanzo

iOS 11, alcune impostazioni delle autorizzazioni sono state spostate nel percorso dell'app:

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

2
questo può passare attraverso Apple Review? Voglio dire, questo porterà al rifiuto dell'app?
Aakash Dave,

4
quando eseguo questo codice, mi porta semplicemente alla pagina delle impostazioni. Non la scheda delle impostazioni specifiche al suo interno.
Aakash Dave,

2

SWIFT 4

Questo potrebbe richiedere le impostazioni specifiche della tua app, se è quello che stai cercando.

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

grazie ... Ho funzionato ... ma voglio cambiare le impostazioni delle app che sono di altri sviluppatori. Ad esempio, premere un pulsante e modificare le impostazioni di notifica Push di Facebook in modo che non inviino messaggi durante una riunione. Prevedo che potrebbero esserci soluzioni MDM ... oppure no.
Irish Gringo,

@IrishGringo l'unico modo per modificare le impostazioni dell'app di Facebook è che l'utente possa aprire le impostazioni dell'app di Facebook navigando tramite le Impostazioni generali >> Notifiche >> Facebook
BennyTheNerd,

0

Come sopra @niravdesai ha detto App-prefs. Ho scoperto che App-Prefs:funziona con dispositivi iOS 9, 10 e 11. testati. dove come prefs:funziona solo su iOS 9.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.