Как открыть настройки телефона при нажатии кнопки?

160

Я пытаюсь реализовать функцию в приложении, которое показывает предупреждение, когда подключение к Интернету не доступно. В предупреждении есть два действия («ОК» и «Настройки»): каждый раз, когда пользователь нажимает на настройки, я хочу программно перенести их в настройки телефона.

Я использую Swift и Xcode.

Соломон Айула
источник

Ответы:

302

С помощью UIApplication.openSettingsURLString

Обновление для 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
Соломон Айола
это с помощью iOS8 @Marius Fanu
Solomon Ayoola
@AyoolaSolomon Я обновил свой ответ , чтобы добавить предупреждение о viewDidAppearметоде, с помощью Settingsи Cancelкнопки
Marius Fanu
2
Нет, я так не думаю. Для того, чтобы перейти к вашему приложению, ваше приложение должно реализовать собственную схему URL-адреса и вызвать ее UIApplication.sharedApplication().openURL(yourCustomURL)из текущего приложения, но у вас нет этого доступа из приложения «Настройки»
Marius Fanu
5
@PersianBlue правильно в iOS 10.1.1, это не в состоянии запустить приложение Настройки.
Майкл Гарито
237

⚠️ Будь осторожен!

Этот ответ основан на недокументированных API, и недавно (начиная с iOS12) Apple отклоняет приложения с таким подходом.

Оригинальный ответ ниже

Swift 5

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

Swift 4

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

ПРИМЕЧАНИЕ: следующий метод работает для всех версий ниже iOS 11, для более высоких версий приложение может быть отклонено, так как это частный API

Иногда мы хотим привести пользователя к настройкам, отличным от настроек нашего приложения. Следующий метод поможет вам достичь этого:

Сначала настройте схемы URL в вашем проекте. Вы найдете его в Target -> Info -> URL Scheme. нажмите на кнопку + и введите prefs в URL Schemes

введите описание изображения здесь

Swift 5

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

Свифт 3

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

стриж

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

Objective-C

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

и далее все доступные URL

** на IOS <12 **

  • префы: корень = Общие и путь = О
  • префы: корень = Общие и путь = ДОСТУПНОСТИ
  • префы: корень = AIRPLANE_MODE
  • префы: корень = Общие и путь = AUTOLOCK
  • префы: корень = Общие и путь = USAGE / CELLULAR_USAGE
  • префы: корень = Яркость
  • префы: корень = Bluetooth
  • префы: корень = Общие и путь = DATE_AND_TIME
  • префы: корень = FaceTime
  • префы: корень = Общие
  • префы: корень = General & путь = Keyboard
  • префы: корень = ЗАМОК
  • префы: корень = ЗАМОК & путь = STORAGE_AND_BACKUP
  • префы: корень = General & путь = INTERNATIONAL
  • Prefs: корень = LOCATION_SERVICES
  • Prefs: корень = ACCOUNT_SETTINGS
  • префы: корень = МУЗЫКА
  • префы: корень = МУЗЫКА & путь = EQ
  • префы: корень = МУЗЫКА & путь = VolumeLimit
  • префы: корень = Общий и путь = Сеть
  • префы: корень = NIKE_PLUS_IPOD
  • префы: корневые = ПРИМЕЧАНИЯ
  • префы: корень = NOTIFICATIONS_ID
  • префы: корень = Телефон
  • Prefs: корневые = Фотографии
  • префы: корень = Общие и путь = ManagedConfigurationList
  • префы: корень = Общие и путь = Сброс
  • префы: корень = Звуки и путь = Мелодия
  • префы: корень = Safari
  • префы: корень = General & путь = помощник
  • Prefs: корень = Звуки
  • префы: корень = Общие и путь = SOFTWARE_UPDATE_LINK
  • префы: корень = STORE
  • префы: корень = TWITTER
  • префы: корень = FACEBOOK
  • prefs: root = General & path = USAGE prefs: root = VIDEO
  • префы: корень = Общие и путь = Сеть / VPN
  • префы: корень = обои
  • префы: корень = WIFI
  • префы: корень = INTERNET_TETHERING
  • префы: корень = Телефон и путь = Blocked
  • префы: корень = DO_NOT_DISTURB

На IOS 13

  • App-префы: Общие и путь = О
  • App-префы: AIRPLANE_MODE
  • App-префы: Общие и путь = AUTOLOCK
  • App-префы: Bluetooth
  • App-префы: Общие и путь = DATE_AND_TIME
  • App-префы: FaceTime
  • App-префы: Общие
  • App-префы: General & путь = Keyboard
  • App-префы: ЗАМОК
  • App-префы: ЗАМОК & путь = STORAGE_AND_BACKUP
  • App-префы: Общие и путь = INTERNATIONAL
  • App-префы: МУЗЫКА
  • App-префы: ПРИМЕЧАНИЯ
  • App-префы: NOTIFICATIONS_ID
  • App-префы: Телефон
  • App-префы: Фотографии
  • App-префы: Общие и путь = ManagedConfigurationList
  • App-префы: Общий путь = & Сброс
  • App-префы: Звуки & Path = Ringtone
  • App-префы: Звуки
  • App-префы: Общие и путь = SOFTWARE_UPDATE_LINK
  • App-префы: STORE
  • App-префы: Обои
  • App-префы: WIFI
  • App-префы: INTERNET_TETHERING
  • App-префы: DO_NOT_DISTURB

    Не проверено

  • Настройки приложения: TWITTER (??)

  • Настройки приложения: FACEBOOK (??)
  • Настройки приложения: NIKE_PLUS_IPOD (??)

Примечание: настройки сети не будут открыты в симуляторе, но ссылка будет работать на реальном устройстве.

Вивек Такрани
источник
7
Это не работает с iOS 10. Запустил тот же код на iOS 9.3. и это работало, работало на iOS 10 и не работало (независимо от того, какой URL используется)
Gruntcakes
18
Для iOS 10 используйте App-Prefsвместо prefsсхемы строку URL. НапримерApp-Prefs:root=WIFI
Десмонд DAI
8
недавно предоставил приложение на рассмотрение, чтобы выпустить его в App Store, и Apple отклонила его из-за использования «prefs: root» или «App-Prefs: root». Я использовал его, чтобы открыть настройки Wi-Fi, когда у пользователя нет подключения к интернету.
Марсель Т
21
Поскольку iOS 12 скоро выйдет, Apple отвергает приложение, которое включает в себя такие префы. Пожалуйста, знайте об этом. Даже мое приложение было отклонено тоже
Тиха Аунг
8
НЕ используйте App-Prefsили, prefs:rootпоскольку они являются частными API, и если вам не повезет, ваше приложение будет отклонено.
Теджас К
45

В iOS 8+ вы можете сделать следующее:

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

Swift 4

    let settingsUrl = URL(string: UIApplicationOpenSettingsURLString)!
    UIApplication.shared.open(settingsUrl)
Кристиан
источник
16
Это приведет вас к конкретным настройкам приложения, как мне перенести их на страницу общих настроек или, что еще лучше, в раздел здоровья?
Эйс Грин
2
Swift 3 -UIApplication.shared.openURL(URL(string: UIApplicationOpenSettingsURLString)!)
Авив Бен Шабат
@AceGreen ты попал в раздел здоровья?
Саад
Как открыть только приложение «Настройки»? «Домашняя страница» этого
Дэниел Спрингер
без "!" знакURL(string: UIApplication.openSettingsURLString).map { UIApplication.shared.open($0, options: [:], completionHandler: nil) }
обер
21

Используя подсказку @ vivek, я разрабатываю класс утилит на основе Swift 3 , надеюсь, вы это оцените!

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

}

Это очень полезно, так как этот API наверняка изменится, и вы сможете провести рефакторинг один раз и очень быстро!

Лука Даванцо
источник
5
Будет ли это пройти обзор Apple?
L_Sonic
Я собираюсь добавить еще одну вещь, чтобы сделать его немного лучше. В перечислении вы можете создать переменную типа String с именем urlString. Затем верните «App-Prefs: root =» = self.rawValue. Это в основном устранит необходимость в appPath и статическом приватном let. Приветствия.
mn1
Настройки уведомлений не открываются на iOS 11.
Metin Atalay
2
это не будет работать, так как мы получили это сообщение от приложения: "Ваше приложение использует непубличную схему URL" prefs: root = ", которая является частной сущностью. Использование непубличных API не разрешено в App Store, потому что это может привести к ухудшению работы пользователей в случае изменения этих API. Продолжение использования или сокрытие непубличных API в будущих представлениях этого приложения может привести к удалению вашей учетной записи Apple Developer, а также удалению всех связанных приложений из приложения. Хранить."
CodeOverRide
1
@L_Sonic Нет, он не пройдет проверку, и если это произойдет, он может быть случайно помечен в любых будущих обновлениях, которые вы отправляете
RP Carson
16

Первый ответ от App-Specific URL Schemes работал для меня на iOS 10.3.

if let appSettings = URL(string: UIApplicationOpenSettingsURLString + Bundle.main.bundleIdentifier!) {
    if UIApplication.shared.canOpenURL(appSettings) {
      UIApplication.shared.open(appSettings)
    }
  }
inc_london
источник
Что это должно открыть?
Даниэль Спрингер,
12

App-Prefs:root=Privacy&path=LOCATIONработал для меня, чтобы добраться до общих настроек местоположения. Примечание: работает только на устройстве.

Джо Сусник
источник
12
Это было отклонено
Даниэль Спрингер
7

в ios10 / Xcode 8 в симуляторе:

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

работает

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

не.

ingconti
источник
Был ли NSпрефикс был удален в прошивке 10?
JC Rocamonde
2
Это будет работать, только если у вашего приложения есть файл .bundle (настройки вашего приложения)
Sophy Swicz
@ Софи Swicz Как я могу добавить файл .bundle?
Разработчик
1
@Developer github.com/phynet/SettingBundleiOSProject Кроме того, настройки вашего приложения - это все сервисы, которые ваше приложение позволяет использовать, и они отображаются в общих
чертах
7

Я видел эту строку кода

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

не работает, у меня не работает в ios10 / Xcode 8, только небольшая разница в коде, пожалуйста, замените это на

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

Swift3

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

Заменить

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

Надеюсь, поможет. Приветствия.

niravdesai21
источник
1
Причины: приложение отклонено
ergunkocak
7

Предупреждение: схемы URL prefs:rootили App-Prefs:rootURL считаются частным API. Apple может отклонить ваше приложение, если вы используете его, вот что вы можете получить при отправке приложения:

Ваше приложение использует непубличную схему URL "prefs: root =", которая является частной сущностью. Использование закрытых API-интерфейсов в App Store запрещено, так как это может привести к ухудшению работы пользователей в случае изменения этих API. Продолжение использования или сокрытие непубличных API в будущих представлениях этого приложения может привести к удалению вашей учетной записи Apple Developer, а также удалению всех связанных приложений из App Store.

Следующие шаги

Чтобы решить эту проблему, пожалуйста, измените свое приложение, чтобы обеспечить связанные функциональные возможности с помощью общедоступных API, или удалите функциональные возможности, используя схему URL «prefs: root» или «App-Prefs: root».

Если нет альтернативы для предоставления функциональности, необходимой вашему приложению, вы можете отправить запрос на расширение.

Офер
источник
Не существует поддерживаемого способа открыть «Настройки» на странице «Wi-Fi / Язык / Расположение». Тот факт, что это работало в iOS 9, является ошибкой, которая была исправлена ​​в iOS 10. Для получения дополнительной информации, пожалуйста, обращайтесь по адресу forum.developer.apple.com/message/186656#186656
Мохит Кумар,
6

Swift 4.2, iOS 12

open(url:options:completionHandler:)Метод был обновлен , чтобы включить не-нильполугруппу варианты словаря, который , как этот пост содержит только один возможный вариант типа UIApplication.OpenExternalURLOptionsKey(в данном примере).

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

}

Явное создание URL, например, с помощью «App-Prefs», AFAIK привело к отклонению некоторых приложений из магазина.

BSOD
источник
Я подтверждаю это, приложение было хорошо с "App-Prefs" раньше, но после специального события Apple мое обновление было отклонено, возвращаясь к UIApplicationOpenSettingsURLString.
Виталий
5

Добавление к @Luca Davanzo

iOS 11, некоторые настройки разрешений перенесены в путь к приложению:

Поддержка 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
это может пройти через Apple Review? Я имею в виду, приведет ли это к отклонению приложения?
Аакаш Дейв
4
когда я запускаю этот код, я просто беру меня на страницу настроек. Не конкретная вкладка настроек в нем.
Аакаш Дейв
2

SWIFT 4

Это может принять конкретные настройки вашего приложения, если это то, что вы ищете.

UIApplication.shared.openURL(URL(string: UIApplicationOpenSettingsURLString)!)
BennyTheNerd
источник
спасибо ... у меня это работает ... но я хочу изменить настройки приложений других разработчиков. Например, нажмите кнопку и измените настройки push-уведомлений на facebook, чтобы они не отображались во время собрания. Я предсказываю, что могут быть решения MDM ... или нет.
IrishGringo
@IrishGringo - единственный способ изменить настройки приложения Facebook, чтобы пользователь сам открыл настройки приложения Facebook,
перейдя
0

Как и выше @niravdesai сказал App-Prefs. Я обнаружил, что App-Prefs:работает как на iOS 9, 10, так и на 11 устройствах. где как prefs:работает только на iOS 9.

Alix
источник