点击按钮时如何打开手机设置?

我试图在一个应用程序中实现一个功能,当互联网连接不可用时显示警报。 警报有两个动作(确定和设置),每当用户单击设置,我想以编程方式将他们带到手机设置

我使用Swift和Xcode。

174915 次浏览

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

斯威夫特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)
}

斯威夫特5

if let settingsUrl = URL(string: UIApplication.openSettingsURLString) {


UIApplication.shared.open(settingsUrl)


}

在iOS 8+中,您可以执行以下操作:

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

斯威夫特4

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

⚠️小心!

这个答案是基于未记录的api,最近(从iOS12开始)苹果拒绝使用这种方法的应用程序。

以下是原始答案

斯威夫特5

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

斯威夫特4

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

注意:以下方法适用于iOS 11以下的所有版本,对于更高版本的应用程序可能会被拒绝,因为它是一个私有API

有时候我们想让用户进入应用程序设置以外的设置。 下面的方法将帮助您实现这一点:

首先,在项目中配置URL方案。你会发现它在目标->信息-> URL方案。点击+按钮,在URL方案中输入prefs

enter image description here

斯威夫特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 * *

  • 控制台:根= General&路径=
  • 控制台:根= General&路径=可访问性
  • 控制台:根= AIRPLANE_MODE
  • 控制台:根= General&路径=自动锁
  • 控制台:=使用/ CELLULAR_USAGE根= General&路径
  • 控制台:根=亮度
  • 控制台:根=蓝牙
  • 控制台:= DATE_AND_TIME根= General&路径
  • 控制台:根= FACETIME
  • 控制台:根=
  • 控制台:根= General&路径=键盘
  • 控制台:根=城堡
  • 控制台:= STORAGE_AND_BACKUP根= CASTLE&路径
  • 控制台:根= General&路径=国际
  • 控制台:根= LOCATION_SERVICES
  • 控制台:根= ACCOUNT_SETTINGS
  • 控制台:根=音乐
  • 控制台:根= MUSIC&路径=情商
  • 控制台:= VolumeLimit根= MUSIC&路径
  • 控制台:根= General&路径=网络
  • 控制台:根= NIKE_PLUS_IPOD
  • 控制台:根=笔记
  • 控制台:根= NOTIFICATIONS_ID
  • 控制台:根=电话
  • 控制台:根=照片
  • 控制台:= ManagedConfigurationList根= General&路径
  • 控制台:根= General&路径=重置
  • 控制台:根= Sounds&路径=铃声
  • 控制台:根= Safari
  • 控制台:根= General&路径=助理
  • 控制台:根=声音
  • 控制台:= SOFTWARE_UPDATE_LINK根= General&路径
  • 控制台:根=商店
  • 控制台:根= TWITTER
  • 控制台:根= FACEBOOK
  • 控制台:根= General&路径=使用控制台:根=视频
  • 控制台:根= General&路径=网络/ VPN
  • 控制台:根=墙纸
  • 控制台:根= WIFI
  • 控制台:根= INTERNET_TETHERING
  • 控制台:根= Phone&路径=屏蔽
  • 控制台:根= DO_NOT_DISTURB

在IOS 13上

  • App-prefs: General&路径=
  • App-prefs: AIRPLANE_MODE
  • App-prefs: General&路径=自动锁
  • App-prefs:蓝牙
  • = DATE_AND_TIME App-prefs: General&路径
  • App-prefs: FACETIME
  • App-prefs:一般
  • App-prefs: General&路径=键盘
  • App-prefs:城堡
  • = STORAGE_AND_BACKUP App-prefs: CASTLE&路径
  • =国际App-prefs: General&路径
  • App-prefs:音乐
  • App-prefs:笔记
  • App-prefs: NOTIFICATIONS_ID
  • App-prefs:电话
  • App-prefs:照片
  • = ManagedConfigurationList App-prefs: General&路径
  • =重置App-prefs: General&路径
  • =铃声App-prefs: Sounds&路径
  • App-prefs:听起来
  • = SOFTWARE_UPDATE_LINK App-prefs: General&路径
  • App-prefs:存储
  • App-prefs:壁纸
  • App-prefs:无线网络
  • App-prefs: INTERNET_TETHERING
  • < p > App-prefs: DO_NOT_DISTURB

    没有测试 < / p >

  • App-prefs: TWITTER (? ?)

  • App-prefs: FACEBOOK (? ?)
  • App-prefs: NIKE_PLUS_IPOD (? ?)

注意:网络设置将不会在模拟器中打开,但该链接将在真实设备上工作。

在ios10/ Xcode 8模拟器:

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

作品

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

没有。

我看过这行代码

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")!)
希望这对你有帮助。 欢呼。< / p >

如上所述@niravdesai说App-prefs。 我发现App-Prefs:适用于iOS 9、10和11。设备测试。 其中prefs:只适用于iOS 9。

应用程序特定的URL方案的第一个响应在iOS 10.3上为我工作。

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

斯威夫特4

如果这是你想要的,这可能会占用你应用程序的特定设置。

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

使用@vivek的提示,我开发了一个基于斯威夫特3的utils类,希望你能欣赏!

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-Prefs:root=Privacy&path=LOCATION为我工作得到一般的位置设置。注:仅在设备上有效。

加上@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)
}
}

警告:prefs:rootApp-Prefs:root URL方案被认为是私有API。如果你使用这些,苹果可能会拒绝你的应用,以下是你提交应用时可能会遇到的情况:

你的应用程序使用&;prefs:root="非公共URL方案,即私有实体。App Store不允许使用非公开api,因为如果这些api发生变化,可能会导致糟糕的用户体验。在未来的应用程序提交中继续使用或隐藏非公开api可能会导致您的苹果开发者帐户被终止,以及从应用商店中移除所有相关的应用程序。

下一个步骤

要解决此问题,请修改应用程序以使用公共api提供相关功能或使用“prefs:root”删除功能。或“App-Prefs: root"URL方案。

如果没有提供应用程序所需功能的替代方案,您可以提交增强请求。

iOS 12 +

open(url:options:completionHandler:)方法已被更新为包含一个非nil选项字典,到本文为止,它只包含一个类型为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 - prepres"”,会导致一些应用程序被商店拒绝。

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