单击按钮时如何打开电话设置?


159

我正在尝试在应用程序中实现一项功能,当互联网连接不可用时会显示警报。该警报有两个操作(“确定”和“设置”),每当用户单击设置时,我都希望以编程方式将其设置为手机设置。

我正在使用Swift和Xcode。

Answers:


300

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

我该如何实施?@Marius Fanu
所罗门·阿约拉

它使用iOS8 @Marius Fanu
Solomon Ayoola,2015年

@AyoolaSolomon我已经更新了我的答案viewDidAppear,以使用SettingsCancel按钮添加方法警报
Marius Fanu 2015年

2
不,我不这么认为。为了转到您的应用程序,您的应用程序应实现自定义URL方案,并UIApplication.sharedApplication().openURL(yourCustomURL)从当前应用程序调用,但您没有从“设置”应用程序获得的访问权限
Marius Fanu 2015年

5
@PersianBlue在iOS 10.1.1中正确,这无法启动“设置”应用程序。
迈克尔·加里托

237

⚠️小心!

此答案基于未公开的API,并且最近(自iOS12起)Apple拒绝使用此方法的应用程序。

下面的原始答案

斯威夫特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方案。您将在Target-> Info-> URL Scheme中找到它。单击+按钮,然后在URL方案中键入首选项

在此处输入图片说明

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

目标C

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

以下是所有可用的网址

**在IOS <12上**

  • prefs:root = General&path =关于
  • prefs:root = General&path =可访问性
  • prefs:root = AIRPLANE_MODE
  • prefs:root = General&path = AUTOLOCK
  • prefs:root = General&path = USAGE / CELLULAR_USAGE
  • prefs:root =亮度
  • prefs:root =蓝牙
  • prefs:root = General&path = DATE_AND_TIME
  • prefs:root = FACETIME
  • prefs:root =常规
  • prefs:root = General&path =键盘
  • prefs:root =城堡
  • prefs:root = CASTLE&path = STORAGE_AND_BACKUP
  • prefs:root = General&path = INTERNATIONAL
  • prefs:root = LOCATION_SERVICES
  • prefs:root = ACCOUNT_SETTINGS
  • prefs:root =音乐
  • prefs:root = MUSIC&path = EQ
  • prefs:root = MUSIC&path = VolumeLimit
  • prefs:root = General&path =网络
  • prefs:root = NIKE_PLUS_IPOD
  • prefs:root =注意
  • prefs:root = NOTIFICATIONS_ID
  • prefs:root =电话
  • prefs:root =照片
  • prefs:root = General&path = ManagedConfigurationList
  • prefs:root = General&path =重置
  • prefs:root =声音和路径=铃声
  • prefs:root = Safari
  • prefs:root = General&path =助手
  • prefs:root =声音
  • prefs:root = General&path = SOFTWARE_UPDATE_LINK
  • prefs:root =存储
  • prefs:root = TWITTER
  • prefs:root = FACEBOOK
  • prefs:root = General&path =使用情况prefs:root = VIDEO
  • prefs:root = General&path =网络/ VPN
  • prefs:root =壁纸
  • prefs:root = WIFI
  • prefs:root = INTERNET_TETHERING
  • prefs:root =电话和路径=已阻止
  • prefs:root = DO_NOT_DISTURB

在IOS 13上

  • 应用偏好:General&path =关于
  • 应用偏好:AIRPLANE_MODE
  • 应用偏好:General&path = AUTOLOCK
  • 应用偏好:蓝牙
  • 应用偏好:General&path = DATE_AND_TIME
  • 应用偏好:FACETIME
  • 应用偏好:常规
  • 应用偏好:General&path = Keyboard
  • 应用偏好:城堡
  • 应用偏好:CASTLE&path = STORAGE_AND_BACKUP
  • 应用偏好:General&path = INTERNATIONAL
  • 应用偏好:音乐
  • 应用偏好:NOTES
  • 应用偏好:NOTIFICATIONS_ID
  • 应用偏好:电话
  • 应用偏好:照片
  • 应用偏好:General&path = ManagedConfigurationList
  • 应用偏好:常规和路径=重置
  • 应用偏好:Sounds&path =铃声
  • 应用偏好:声音
  • 应用偏好:General&path = SOFTWARE_UPDATE_LINK
  • 应用偏好:商店
  • 应用偏好:壁纸
  • 应用偏好:WIFI
  • 应用偏好:INTERNET_TETHERING
  • 应用偏好:DO_NOT_DISTURB

    未测试

  • 应用偏好:TWITTER(??)

  • 应用偏好:FACEBOOK(??)
  • 应用程式偏好设定:NIKE_PLUS_IPOD(??)

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


7
这不适用于iOS10。在iOS 9.3上运行相同的代码。并且可以正常运行,并且可以在iOS 10上运行,但没有(无论使用哪个url)
Gruntcakes

18
对于iOS 10,使用App-Prefs代替prefsURL字符串的方案。例如App-Prefs:root=WIFI
Desmond DAI

8
最近对某个应用进行了审核,以便将其发布到App Store中,而Apple则拒绝使用该应用,因为使用了“ prefs:root”或“ App-Prefs:root”。当用户没有互联网连接时,我用它来打开wifi设置。
Marcel T

21
由于iOS 12即将面世,Apple拒绝了包含此类首选项的应用程序。请注意。即使我的应用得到了拒绝过
Thiha昂

8
请勿使用App-Prefsprefs:root因为它们是私有API,除非您非常幸运,否则您的应用将被拒绝。
Tejas K,

45

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

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

斯威夫特4

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

16
这会将您带到应用程序特定的设置,如何将它们带到常规设置页面,甚至更好地进入“健康”部分?
Ace Green

2
斯威夫特UIApplication.shared.openURL(URL(string: UIApplicationOpenSettingsURLString)!)
3-–阿维夫·本·沙巴特

@AceGreen您是否已进入“健康”部分?
萨德

您如何仅打开“设置”应用程序?它的“主页”
Daniel Springer

没有“!” 签名URL(string: UIApplication.openSettingsURLString).map { UIApplication.shared.open($0, options: [:], completionHandler: nil) }
奥伯

21

根据@vivek的提示,我基于Swift 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肯定会发生变化,并且您可以一次且非常快速地进行重构!


5
这会通过苹果审查吗?
L_Sonic

我将添加一件事以使其稍微好一些。在枚举中,可以使名称为urlString的String类型的变量。然后返回“ App-Prefs:root =“ = self.rawValue。这基本上将消除对appPath和静态私有let的需要。干杯。
1

通知设置是不开放iOS上的11
倚天阿塔莱

2
这将无法正常工作,因为我们收到了来自应用程序的消息:“您的应用程序使用了“ prefs:root =“非公共URL方案,这是一个私有实体。在App Store上不允许使用非公共API,因为如果这些API发生更改,可能会导致不良的用户体验。在以后提交此应用程序时继续使用或隐藏非公共API可能会导致您的Apple Developer帐户终止,并从该应用程序中删除所有关联的应用程序商店。”
CodeOverRide

1
@L_Sonic不,它不会通过审核,并且如果通过,则在您推送的任何将来更新中都可能会随机标记它
RP Carson



7

在模拟器中的ios10 / Xcode 8中:

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

作品

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

才不是。


NSiOS 10中是否已删除前缀?
罗卡蒙德

2
仅当您的应用程序具有.bundle文件(您的应用程序首选项)时,此方法才有效
Sophy Swicz

@Sophy Swicz如何添加.bundle文件?
开发人员

1
@Developer github.com/phynet/SettingBundleiOSProject 也是如此,您的应用程序设置是应用程序允许使用的所有服务,并显示在应用程序的“常规”->“设置”中
Sophy Swicz

7

我看过这行代码

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

不起作用,在ios10 / Xcode 8中对我不起作用,只是很小的代码差异,请替换为

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

迅捷3

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

用。。。来代替

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

希望能帮助到你。干杯。


1
原因:应用遭拒
-ergunkocak

7

警告词:prefs:rootApp-Prefs:rootURL方案被视为私有API。如果您使用这些应用程序,Apple可能会拒绝您的应用程序,这是您提交应用程序时可能会得到的:

您的应用程序使用“ prefs:root =“非公共URL方案,这是一个私有实体。在App Store上不允许使用非公共API,因为如果这些API发生更改,可能会导致不良的用户体验。在以后提交此应用程序时继续使用或隐藏非公共API可能会导致您的Apple Developer帐户终止,并从App Store中删除所有关联的应用程序。

下一步

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

如果没有其他方法可提供您的应用程序所需的功能,则可以提出增强请求。


没有支持的方法来打开“ Wi-Fi /语言/位置”页面的“设置”。在iOS 9中可以正常工作的事实是iOS 10中已修复的错误。有关更多信息,请参阅forums.developer.apple.com/message/186656#186656
Mohit Kumar

6

Swift 4.2,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-Prefs”)已导致AFAIK拒绝了商店中的某些应用。


我确认这一点,之前应用程序可以使用“ App-Prefs”很好,但是在苹果公司的特别活动之后,我的更新被拒绝了,回落到UIApplicationOpenSettingsURLString上。
Vitalii

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吗?我的意思是,这会导致应用被拒绝吗?
Aakash Dave

4
当我运行此代码时,我只是将我带到设置页面。不是其中的特定设置选项卡。
Aakash Dave

2

SWIFT 4

如果这正是您要查找的内容,则可以采用您应用程序的特定设置。

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

谢谢...我已经在工作...但是我想更改其他开发人员的应用程序上的设置。例如,按一个按钮并更改facebook的Push通知设置,这样它们就不会在会议期间发送消息。我预测可能会有MDM解决方案...
IrishGringo

@IrishGringo更改Facebook应用程序设置的唯一方法是让用户自己通过常规设置>>通知>> Facebook
BennyTheNerd

0

如上所述,@ niravdesai表示App-prefs。我发现该功能App-Prefs:适用于经过测试的iOS 9、10和11设备。其中,作为prefs:仅适用于iOS 9。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.