Jak otworzyć ustawienia telefonu po kliknięciu przycisku?


160

Próbuję zaimplementować funkcję w aplikacji, która wyświetla alert, gdy połączenie internetowe jest niedostępne. Alert ma dwie akcje (OK i Ustawienia), za każdym razem, gdy użytkownik kliknie ustawienia, chcę programowo przenieść je do ustawień telefonu.

Używam Swift i Xcode.

Odpowiedzi:


301

Za pomocą UIApplication.openSettingsURLString

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

Jak to zaimplementować? @Marius Fanu
Solomon Ayoola

to przy użyciu iOS8 @Marius Fanu
Solomon Ayoola

@AyoolaSolomon Zaktualizowałem swoją odpowiedź, dodając alert dotyczący viewDidAppearmetody, za pomocą przycisku SettingsiCancel
Marius Fanu

2
Nie, nie sądzę. Aby przejść do Twojej aplikacji, Twoja aplikacja powinna zaimplementować niestandardowy schemat adresu URL i wywołać UIApplication.sharedApplication().openURL(yourCustomURL)z bieżącej aplikacji, ale nie masz tego dostępu z aplikacji Ustawienia
Marius Fanu

5
@PersianBlue jest poprawne w iOS 10.1.1 to nie uruchamia aplikacji Ustawienia.
Michael Garito

237

⚠️ Uważaj!

Ta odpowiedź jest oparta na nieudokumentowanych interfejsach API, a ostatnio (od iOS12) Apple odrzuca aplikacje z takim podejściem.

Oryginalna odpowiedź poniżej

Szybki 5

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

Szybki 4

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

UWAGA: Poniższa metoda działa dla wszystkich wersji poniżej iOS 11, w przypadku wyższych wersji aplikacja może zostać odrzucona, ponieważ jest to prywatny interfejs API

Czasami chcemy przenieść użytkownika do ustawień innych niż ustawienia naszej aplikacji. Poniższa metoda pomoże Ci to osiągnąć:

Najpierw skonfiguruj schematy adresów URL w swoim projekcie. Znajdziesz go w Target -> Info -> URL Scheme. kliknij przycisk + i wpisz preferencje w schematach adresów URL

wprowadź opis obrazu tutaj

Szybki 5

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

Szybki 3

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

Szybki

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

Cel C

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

a poniżej znajdują się wszystkie dostępne adresy URL

** Na IOS <12 **

  • prefs: root = Ogólne & path = Informacje
  • prefs: root = Ogólne & path = DOSTĘPNOŚĆ
  • prefs: root = TRYB_PLANU SAMOLOTU
  • prefs: root = Ogólne & path = AUTOLOCK
  • prefs: root = General & path = USAGE / CELLULAR_USAGE
  • prefs: root = Jasność
  • prefs: root = Bluetooth
  • prefs: root = General & path = DATE_AND_TIME
  • prefs: root = FACETIME
  • prefs: root = General
  • prefs: root = Ogólne & path = Klawiatura
  • prefs: root = ZAMEK
  • prefs: root = ZAMEK & path = STORAGE_AND_BACKUP
  • prefs: root = Ogólne & path = INTERNATIONAL
  • prefs: root = LOCATION_SERVICES
  • prefs: root = ACCOUNT_SETTINGS
  • prefs: root = MUZYKA
  • prefs: root = MUZYKA i ścieżka = EQ
  • prefs: root = MUZYKA & path = VolumeLimit
  • prefs: root = Ogólne & path = Network
  • prefs: root = NIKE_PLUS_IPOD
  • prefs: root = UWAGI
  • prefs: root = NOTIFICATIONS_ID
  • prefs: root = Phone
  • prefs: root = Zdjęcia
  • prefs: root = General & path = ManagedConfigurationList
  • prefs: root = Ogólne & path = Reset
  • prefs: root = Dźwięki & path = Dzwonek
  • prefs: root = Safari
  • prefs: root = Ogólne & path = Asystent
  • prefs: root = Dźwięki
  • 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 = Ogólne & path = Sieć / VPN
  • prefs: root = Wallpaper
  • prefs: root = WIFI
  • prefs: root = INTERNET_TETHERING
  • prefs: root = Phone & path = Zablokowane
  • prefs: root = DO_NOT_DISTURB

W systemie IOS 13

  • App-prefs: General & path = About
  • Preferencje aplikacji: AIRPLANE_MODE
  • App-prefs: General & path = AUTOLOCK
  • Ustawienia aplikacji: Bluetooth
  • Preferencje aplikacji: Ogólne i ścieżka = DATE_AND_TIME
  • Preferencje aplikacji: FACETIME
  • Preferencje aplikacji: Ogólne
  • App-prefs: General & path = klawiatura
  • App-prefs: ZAMEK
  • Preferencje aplikacji: ZAMEK i ścieżka = STORAGE_AND_BACKUP
  • App-prefs: General & path = INTERNATIONAL
  • Ustawienia aplikacji: MUZYKA
  • Ustawienia aplikacji: UWAGI
  • Preferencje aplikacji: NOTIFICATIONS_ID
  • Ustawienia aplikacji: Telefon
  • Ustawienia aplikacji: Zdjęcia
  • App-prefs: General & path = ManagedConfigurationList
  • App-prefs: General & path = Reset
  • App-prefs: Sounds & path = Ringtone
  • App-prefs: Sounds
  • App-prefs: General & path = SOFTWARE_UPDATE_LINK
  • Ustawienia aplikacji: SKLEP
  • Ustawienia aplikacji: tapeta
  • Ustawienia aplikacji: WIFI
  • Preferencje aplikacji: INTERNET_TETHERING
  • Preferencje aplikacji: DO_NOT_DISTURB

    Nie testowany

  • Preferencje aplikacji: TWITTER (??)

  • Preferencje aplikacji: FACEBOOK (??)
  • Preferencje aplikacji: NIKE_PLUS_IPOD (??)

Uwaga: ustawienie sieci nie zostanie otwarte w symulatorze, ale łącze będzie działać na prawdziwym urządzeniu.


7
To nie działa z iOS 10. Uruchomiłem ten sam kod w iOS 9.3. i zadziałało, działało na iOS 10 i nie zadziałało (niezależnie od używanego
adresu

18
W systemie iOS 10 użyj App-Prefszamiast prefsjako schematu ciągu adresu URL. np.App-Prefs:root=WIFI
Desmond DAI

8
niedawno przekazał aplikację do przeglądu w celu udostępnienia jej w App Store, a firma Apple odrzuciła ją z powodu użycia „prefs: root” lub „App-Prefs: root”. Użyłem go do otwarcia ustawień Wi-Fi, gdy użytkownik nie ma połączenia z Internetem.
Marcel T

21
Ponieważ iOS 12 pojawi się wkrótce, Apple odrzuca aplikację, która zawiera takie pref. Pamiętaj o tym. Nawet moja aplikacja też została odrzucona
Thiha Aung

8
NIE używaj App-Prefslub, prefs:rootponieważ są to prywatne interfejsy API i jeśli nie masz szczęścia, Twoja aplikacja zostanie odrzucona.
Tejas K,

45

W iOS 8+ możesz wykonać następujące czynności:

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

Szybki 4

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

16
Spowoduje to przejście do ustawień specyficznych dla aplikacji. Jak mogę je przenieść na stronę ustawień ogólnych lub jeszcze lepiej do sekcji zdrowia?
Ace Green

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

@AceGreen czy dotarłeś do sekcji zdrowia?
Saad

Jak otworzyć samą aplikację Ustawienia? „Strona domowa” tego
Daniel Springer

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

21

Korzystając ze wskazówki @ vivek, opracowuję klasę narzędzi w oparciu o Swift 3 , mam nadzieję, że docenisz!

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

}

Jest to bardzo pomocne, ponieważ to API na pewno się zmieni i możesz raz i bardzo szybko refaktoryzować!


5
Czy to przejdzie przez recenzję Apple?
L_Sonic

Dodam jeszcze jedną rzecz, żeby było trochę lepiej. W wyliczeniu można utworzyć zmienną typu String o nazwie urlString. Następnie zwróć „App-Prefs: root =” = self.rawValue. W zasadzie usunie to potrzebę appPath i statycznego prywatnego let. Twoje zdrowie.
mn1

Ustawienia powiadomień nie otwierają się na iOS 11.
Metin Atalay,

2
to nie zadziała, ponieważ otrzymaliśmy wiadomość od aplikacji: „Twoja aplikacja używa schematu niepublicznego adresu URL„ prefs: root = ”, który jest jednostką prywatną. Korzystanie z niepublicznych interfejsów API jest niedozwolone w App Store, ponieważ może to prowadzić do złego wrażenia użytkownika, jeśli te interfejsy API się zmienią. Dalsze używanie lub ukrywanie niepublicznych interfejsów API w przyszłych przesyłaniach tej aplikacji może spowodować zamknięcie Twojego konta Apple Developer, a także usunięcie wszystkich powiązanych aplikacji z Aplikacji Sklep."
CodeOverRide

1
@L_Sonic nie, nie przejdzie przeglądu, a jeśli tak, może zostać losowo oznaczony w przyszłych aktualizacjach, które wrzucisz
RP Carson


12

App-Prefs:root=Privacy&path=LOCATIONpomogło mi w uzyskaniu ogólnych ustawień lokalizacji. Uwaga: działa tylko na urządzeniu.


12
To zostaje odrzucone
Daniel Springer

7

w ios10 / Xcode 8 w symulatorze:

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

Pracuje

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

nie.


Czy NSprefiks został usunięty w iOS 10?
JC Rocamonde,

2
To zadziała tylko wtedy, gdy Twoja aplikacja ma plik .bundle (preferencje aplikacji)
Sophy Swicz

@Sophy Swicz JAK mogę dodać plik .bundle?
Deweloper

1
@Developer github.com/phynet/SettingBundleiOSProject również, ustawienia Twojej aplikacji to wszystkie usługi, z których aplikacja pozwala korzystać i które są wyświetlane w
sekcji

7

Widziałem tę linię kodu

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

nie działa, nie działa u mnie w ios10 / Xcode 8, tylko mała różnica w kodzie, proszę zastąpić to

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

Swift3

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

Zamienić

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

Mam nadzieję, że to pomoże. Twoje zdrowie.


1
Przyczyny: aplikacja odrzucona
ergunkocak

7

słowo ostrzeżenia: schematy prefs:rootlub App-Prefs:rootURL są uważane za prywatne API. Apple może odrzucić Twoją aplikację, jeśli z nich korzystasz. Oto, co możesz otrzymać, przesyłając swoją aplikację:

Twoja aplikacja używa schematu niepublicznego adresu URL „prefs: root =”, który jest jednostką prywatną. Korzystanie z niepublicznych interfejsów API jest niedozwolone w App Store, ponieważ może to prowadzić do złego wrażenia użytkownika, jeśli te interfejsy API się zmienią. Dalsze używanie lub ukrywanie niepublicznych interfejsów API w przyszłych przesyłkach tej aplikacji może skutkować zamknięciem konta Apple Developer, a także usunięciem wszystkich powiązanych aplikacji z App Store.

Następne kroki

Aby rozwiązać ten problem, popraw aplikację, aby zapewniała powiązaną funkcjonalność przy użyciu publicznych interfejsów API, lub usuń tę funkcję, korzystając ze schematu adresu URL „prefs: root” lub „App-Prefs: root”.

Jeśli nie ma alternatywy dla zapewnienia funkcjonalności wymaganej przez Twoją aplikację, możesz złożyć wniosek o ulepszenie.


Nie ma obsługiwanego sposobu, aby otworzyć Ustawienia na stronie Wi-Fi / Język / Lokalizacja. Fakt, że to zadziałało w iOS 9, jest błędem, który został naprawiony w iOS 10. Aby uzyskać więcej informacji, odwiedź forums.developer.apple.com/message/186656#186656
Mohit Kumar

6

Swift 4.2, iOS 12

open(url:options:completionHandler:)Metoda została zaktualizowana o słownika a non-nil opcje, które jak tego postu zawiera tylko jedną z możliwych opcji typu UIApplication.OpenExternalURLOptionsKey(na przykład).

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

}

Jawne utworzenie adresu URL, na przykład „App-Prefs”, spowodowało, AFAIK, spowodowanie odrzucenia niektórych aplikacji ze sklepu.


Potwierdzam to, aplikacja działała wcześniej z „App-Prefs”, ale po wydarzeniu specjalnym Apple moja aktualizacja została odrzucona, wracając do UIApplicationOpenSettingsURLString.
Vitalii,

5

Dodawanie do @Luca Davanzo

iOS 11, niektóre ustawienia uprawnień zostały przeniesione do ścieżki aplikacji:

Obsługa 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
czy to może przejść przez przegląd Apple? Mam na myśli, czy to doprowadzi do odrzucenia aplikacji?
Aakash Dave

4
kiedy uruchamiam ten kod, po prostu przenoszę mnie na stronę ustawień. Nie dotyczy to konkretnej karty ustawień.
Aakash Dave

2

SWIFT 4

Może to wymagać określonych ustawień aplikacji, jeśli tego właśnie szukasz.

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

dzięki ... mam to działa ... ale chcę zmienić ustawienia w aplikacjach innych programistów. Na przykład naciśnij przycisk i zmień ustawienia powiadomień push na Facebooku, aby nie wysyłali wiadomości podczas spotkania. Przewiduję, że mogą istnieć rozwiązania MDM ... lub nie.
IrishGringo

@IrishGringo Jedynym sposobem zmiany ustawień aplikacji Facebook jest samodzielne otwarcie przez użytkownika ustawień aplikacji Facebook poprzez przejście w Ustawieniach ogólnych >> Powiadomienia >> Facebook
BennyTheNerd

0

Jak powyżej @niravdesai powiedział App-prefs. Okazało się, że App-Prefs:działa to zarówno na testowanych urządzeniach z iOS 9, 10, jak i 11.. gdzie prefs:działa tylko na iOS 9.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.