Как открыть настройки телефона при нажатии кнопки?
Я пытаюсь реализовать функцию в приложении, которая показывает предупреждение, когда подключение к Интернету недоступно. В предупреждении есть два действия ("ОК" и "Настройки"): каждый раз, когда пользователь нажимает на настройки, я хочу программно перенести их в настройки телефона.
Я использую Swift и Xcode.
15 ответов
С помощью UIApplicationOpenSettingsURLString
Обновление для Swift 3
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)
}
Swift 2.x
override func viewDidAppear(animated: Bool) {
var alertController = UIAlertController (title: "Title", message: "Go to Settings?", preferredStyle: .Alert)
var settingsAction = UIAlertAction(title: "Settings", style: .Default) { (_) -> Void in
let settingsUrl = NSURL(string: UIApplicationOpenSettingsURLString)
if let url = settingsUrl {
UIApplication.sharedApplication().openURL(url)
}
}
var cancelAction = UIAlertAction(title: "Cancel", style: .Default, handler: nil)
alertController.addAction(settingsAction)
alertController.addAction(cancelAction)
presentViewController(alertController, animated: true, completion: nil)
}
Swift 4
UIApplication.shared.open(URL.init(string: UIApplicationOpenSettingsURLString)!, options: [:], completionHandler: nil)
ПРИМЕЧАНИЕ: следующий метод работает для всех версий ниже iOS 11, для более высоких версий приложение может быть отклонено, так как это частный API
Иногда мы хотим привести пользователя к настройкам, отличным от настроек нашего приложения. Следующий метод поможет вам достичь этого:
Сначала настройте схемы URL в вашем проекте. Вы найдете его в Target -> Info -> URL Scheme. нажмите на кнопку + и введите префы в URL Схемы
Свифт 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
- префы: корень = Общие и путь = О
- префы: корень = Общие и путь = ДОСТУПНОСТИ
- префы: корень =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
- Prefs: корневые = ПРИМЕЧАНИЯ
- префы: корень = 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 8+ вы можете сделать следующее:
func buttonClicked(sender:UIButton)
{
UIApplication.sharedApplication().openURL(NSURL(string: UIApplicationOpenSettingsURLString))
}
Swift 4
let settingsUrl = URL(string: UIApplicationOpenSettingsURLString)!
UIApplication.shared.open(settingsUrl)
Используя подсказку @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-интерфейс изменится наверняка, и вы сможете провести рефакторинг один раз и очень быстро!
Первый ответ от 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)
}
}
App-Prefs:root=Privacy&path=LOCATION
работал для меня, чтобы добраться до общих настроек местоположения. Примечание: работает только на устройстве.
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 получил некоторые приложения, отклоненные из магазина.
Слово предупреждения: prefs:root
или же App-Prefs:root
Схемы URL считаются частным API. Apple может отклонить ваше приложение, если вы используете его, вот что вы можете получить при отправке приложения:
Ваше приложение использует непубличную схему URL "prefs: root =", которая является частной сущностью. Использование закрытых API-интерфейсов в App Store запрещено, так как это может привести к ухудшению работы пользователей в случае изменения этих API. Продолжение использования или сокрытие непубличных API в будущих представлениях этого приложения может привести к удалению вашей учетной записи Apple Developer, а также удалению всех связанных приложений из App Store.
Следующие шаги
Чтобы решить эту проблему, пожалуйста, измените ваше приложение, чтобы предоставить связанные функциональные возможности с помощью общедоступных API-интерфейсов, или удалите функциональные возможности, используя схему URL-адресов "prefs: root" или "App-Prefs: root".
Если нет альтернативы для предоставления функциональности, требуемой вашему приложению, вы можете подать запрос на расширение.
Я видел эту строку кода
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")!)
Надеюсь, поможет. Приветствия.
В ios10/ Xcode 8 в симуляторе:
UIApplication.shared.openURL(URL(string:UIApplicationOpenSettingsURLString)!)
работает
UIApplication.shared.openURL(URL(string:"prefs:root=General")!)
не.
Добавление в @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)
}
}
UIApplication.open(_:options:completionHandler:)
должен использоваться только из основного потока
Решение:
if let appSettings = URL(string: UIApplication.openSettingsURLString + Bundle.main.bundleIdentifier!) {
if UIApplication.shared.canOpenURL(appSettings) {
DispatchQueue.main.async {
UIApplication.shared.open(appSettings)
}
}
}
SWIFT 4
Это может принять конкретные настройки вашего приложения, если это то, что вы ищете.
UIApplication.shared.openURL(URL(string: UIApplicationOpenSettingsURLString)!)
В iOS 10 и Swift 3 используйте код ниже:
UIApplication.shared.open(URL.init(string: "App-Prefs:root=General")!, options: [:]) { (success) in
}
As above @niravdesai said App-prefs. я нашел это App-Prefs:
works for both iOS 9, 10 and 11. devices tested. в то время как prefs:
only works on iOS 9.