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

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

Я использую 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.

Другие вопросы по тегам