如何像Facebook应用程序一样以编程方式打开设置?

76

我需要在应用程序中以编程方式打开设置。我在SO上进行了搜索,但到处都说这是不可能的。但今天我看到Facebook应用程序中实现了这个功能。当你点击一个UIAlertView上的一个按钮时,就会打开设置。所以确实可以打开设置,我亲眼见证了这一点。但如何做到呢?有人知道Facebook是如何做到的吗?


请注意,Facebook应用程序是开源的,并且完全可以在Github上获得。 - Sulthan
Facebook没有显示这个警报,是操作系统做的。它发生在某些情况下,比如飞行模式被打开或WiFi被关闭,操作系统会提供给您打开设置并进行更改的选项。 - Guy Kogus
9
请注意,Facebook 应用程序并非开放源代码。只有 SDK 是开源的。 - MatterGoal
请查看此链接:https://dev59.com/hm035IYBdhLWcg3wC7if#37439140 - guyromb
请访问以下链接获取关于 Swift 3 的答案:https://dev59.com/Rl4c5IYBdhLWcg3wOoO6#34024467 - Hamed
15个回答

140

iOS 8可以通过编程方式打开设置界面!

以下是代码:

- (void)openSettings
{
    BOOL canOpenSettings = (&UIApplicationOpenSettingsURLString != NULL);
    if (canOpenSettings) {
        NSURL *url = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
        [[UIApplication sharedApplication] openURL:url];
    }
}
如果您的应用程序有其自己的设置捆绑包,那么设置将被打开以显示您的应用程序的设置。如果您的应用程序没有设置捆绑包,则将显示主要设置页面。

如果您的应用程序有其自己的设置捆绑包,那么设置将被打开以显示您的应用程序的设置。如果您的应用程序没有设置捆绑包,则将显示主要设置页面。


3
有人知道如何仅打开“设置”应用程序而不是单个的设置页面吗?Facebook 可以打开“设置”应用程序,而不需要跳转到单个的设置页面。 - Pei
7
注意:如果您没有设置您的设置捆绑,此代码仍会打开应用程序设置(包括“通知”和“使用蜂窝数据”),而不是通用设置。 - MatterGoal
1
你如何删除应用程序的设置,使其打开常规设置?在安装应用程序时,iOS 8已经支持此功能。 - vatti
2
请问如何在Xcode中删除应用程序设置包?我总是进入应用程序设置而不是通用设置。 - Jeff Bootsholz
@decodingpanda 嗨,是的,它实际上适用于PhoneGap,但仅适用于iOS> 8。我不得不创建一个插件来调用此功能。 - MontDeska
显示剩余7条评论

58

你不能,因为没有 API 调用可以做到这一点。

只有系统对话框、Apple 框架的对话框才能打开设置应用程序。在 iOS 5 中有一个应用程序 URL 方案可以打开系统对话框,但后来被 Apple 删除了。


随着 iOS 8 的到来,您可以在应用程序页面上打开设置对话框。

if (&UIApplicationOpenSettingsURLString != NULL) {
   NSURL *url = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
    [[UIApplication sharedApplication] openURL:url];
}
else {
  // Present some dialog telling the user to open the settings app.
}

5
好的,但是Facebook确实做到了。 - Andrey Chernukha
3
这是因为他们与苹果公司密切合作,苹果公司将他们的服务集成到了iOS中。这并不意味着你也可以这样做!他们甚至可能被允许调用一些私有API来打开设置应用程序。 - rckoenes
3
我很肯定那只是应用程序的正常部分,恰巧看起来像设置页面。你知道吗? - Fattie
9
嘿,大家好,iOS 8可以通过编程的方式打开设置,详见我的回答。 - Vito Ziv
2
@VitoZiv 这是真的,但当这个问题被提出时,我的回答是正确的。 - rckoenes
显示剩余7条评论

33

iOS 8可以通过编程的方式打开设置界面!

以下是当前已知的设置应用程序中的URL列表:

- (void) openSettings
{
if (&UIApplicationOpenSettingsURLString != nil)
    [[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]];
else
    NSLog(@"UIApplicationOpenSettingsURLString is not available in current iOS version");
}    
prefs:root=General&path=About
prefs:root=General&path=ACCESSIBILITY
prefs:root=AIRPLANE_MODE
prefs:root=General&path=AUTOLOCK
prefs:root=General&path=USAGE/CELLULAR_USAGE
prefs:root=Brightness
prefs:root=General&path=Bluetooth
prefs:root=General&path=DATE_AND_TIME
prefs:root=FACETIME
prefs:root=General
prefs:root=General&path=Keyboard
prefs:root=CASTLE
prefs:root=CASTLE&path=STORAGE_AND_BACKUP
prefs:root=General&path=INTERNATIONAL
prefs:root=LOCATION_SERVICES
prefs:root=ACCOUNT_SETTINGS
prefs:root=MUSIC
prefs:root=MUSIC&path=EQ
prefs:root=MUSIC&path=VolumeLimit
prefs:root=General&path=Network
prefs:root=NIKE_PLUS_IPOD
prefs:root=NOTES
prefs:root=NOTIFICATIONS_ID
prefs:root=Phone
prefs:root=Photos
prefs:root=General&path=ManagedConfigurationList
prefs:root=General&path=Reset
prefs:root=Sounds&path=Ringtone
prefs:root=Safari
prefs:root=General&path=Assistant
prefs:root=Sounds
prefs:root=General&path=SOFTWARE_UPDATE_LINK
prefs:root=STORE
prefs:root=TWITTER
prefs:root=General&path=USAGE
prefs:root=VIDEO
prefs:root=General&path=Network/VPN
prefs:root=Wallpaper
prefs:root=WIFI
prefs:root=INTERNET_TETHERING

2
你能否提供任何官方的苹果来源,证明这个问题是如何被发现的? - Joey Carson
6
只需将偏好设置更改为 iOS 10 的“App-Prefs”即可。 上述代码适用于 iOS 8、9、10。 - Stalin Pusparaj
1
"App-Prefs:root=Privacy&path=Location" 是特定于 位置服务 的。 - dichen
2
你的应用程序因使用prefs:root而被苹果拒绝。 - Helam
1
我的应用程序因为“app-prefs:root=privacy”而被拒绝了。 - Can Poyrazoğlu
显示剩余6条评论

20

Vito Ziv在Swift中的回答。

func openSettings() {
    UIApplication.shared.open(URL(string: UIApplicationOpenSettingsURLString)!, completionHandler: nil)

}

我们如何在应用程序中找到无线网络设置,以便用户重新连接wifi? - JMStudios.jrichardson
1
@JMStudios.jrichardson 目前还没有这种方法。只有应用程序设置。 - alexey.metelkin
1
openURL在Swift3中已被弃用,是否有更新的示例? - Geoff

14
这个问题所涉及的Facebook应用程序中的警报是iOS在您的Info.plist文件中将UIRequiresPersistentWiFi设置为YES并且用户在没有网络连接的情况下启动您的应用程序时显示的标准警报
总结这里的讨论:
  • 没有URL可以用来进入“设置”应用程序的根级别
  • 您可以使用iOS 8中的UIApplicationOpenSettingsURLString将用户发送到您的应用程序部分的设置应用程序。
  • 您的应用程序可以显示与Facebook相同的警报,通过将UIRequiresPersistentWiFi设置为YES,它确实打开了“设置”应用程序的根级别。

你的应用程序在设置应用程序中的部分是什么?如果您没有为您的应用程序提供 settings.bundle,会发生什么行为? 我发现当通过 Xcode 启动时,此 URL 会将我带到顶级设置页面。但是当通过 TestFlight 时,它会进入我的(空)应用程序设置子页面。但我没有创建 settings.bundle,也没有在我的 .app 产品中找到一个... - pkamb
就做与Facebook相同的事情而言,这应该是正确的答案。UIRequiresPersistentWiFi是我要寻找的以显示警报。但是,有没有人知道是否可以在运行时通过编程方式触发它,而不是使用info.plist?@Richard Venable,您是否知道是否有一种方法可以调用,以便在单击特定按钮时实际使用它? - user3832583

11
一份关于 prefs:root=Prefs:root 的备忘录。

是的,我们的应用因为使用了私有 API: prefs:root=App-Prefs:root URL 方案被苹果公司于 (2018-06-29) 拒绝了。

苹果公司拒绝


针对 Swift 4,

只有UIApplication.openSettingsURLString 是公开的 API 来打开设置。


2018年8月14日 - 我们的应用程序也因使用此功能而被拒绝。在他们最终拒绝我们之前,它已经在我们的代码库中使用了3个版本。 - Cameron E
你们在这里找到任何解决方案了吗? - Sukeshj
不,我现在使用 UIApplication.openSettingsURLString,并请求我的老板修改UI规范以解决这个问题。 - AechoLiu

7
 if (&UIApplicationOpenSettingsURLString != NULL)

iOS 8及以上版本中始终为TRUE。因此,您可以像这样进行编辑:

NSURL *url = [NSURL URLWithString:UIApplicationOpenSettingsURLString];

if ([[UIApplication sharedApplication] canOpenURL:url]) {
    [[UIApplication sharedApplication] openURL:url options:@{} completionHandler:nil];
}

(使用新的iOS 10 openURL)

5

如果您想打开应用程序设置,您需要编写带有UIApplicationOpenSettingsURLString方法的代码。

fileprivate func openSettings() {
  UIApplication.shared.open(URL(string: UIApplicationOpenSettingsURLString)!)      
}

如果您需要打开多个设置中的一个,则需要使用此功能。
fileprivate func openSettings() {
  UIApplication.shared.open(URL(string:"App-Prefs:root=General")!)
}

请勿在您的应用程序中使用“App-Prefs:root=General”。苹果公司会因为您的应用程序使用非公共URL而拒绝您的应用程序。我的应用程序也被拒绝了。 - Ravi Kumar

3
若要在iOS 8及之后版本中打开我们自己应用的设置,请使用以下代码。
- (void) openSettings
{
    if(&UIApplicationOpenSettingsURLString != nil)
        [[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]];
    else
        NSLog(@"UIApplicationOpenSettingsURLString is not available in current iOS version");
}

请参考并详细描述,请访问在iOS 8中以编程方式打开设置应用程序


2
 if (&UIApplicationOpenSettingsURLString != NULL) {
            UIAlertView_Blocks *alertView = [[UIAlertView_Blocks alloc] initWithTitle:NSLocalizedString(@"Camera Access Denied", nil)
                                                                              message:NSLocalizedString(@"You must allow camera access in Settings", nil)
                                                                             delegate:nil
                                                                    cancelButtonTitle:NSLocalizedString(@"Cancel", nil)
                                                                    otherButtonTitles:NSLocalizedString(@"Open Settings", nil), nil];
            [alertView showWithDissmissBlock:^(NSInteger buttonIndex) {
                if (alertView.cancelButtonIndex != buttonIndex) {
                    NSURL *url = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
                    [[UIApplication sharedApplication] openURL:url];
                }
            }];
        }
        else {
            UIAlertView_Blocks *alertView = [[UIAlertView_Blocks alloc] initWithTitle:NSLocalizedString(@"Camera Access Denied", nil)
                                                                              message:NSLocalizedString(@"You must allow camera access in Settings > Privacy > Camera", nil)
                                                                             delegate:nil
                                                                    cancelButtonTitle:NSLocalizedString(@"OK", nil)
                                                                    otherButtonTitles:nil, nil];
            [alertView showWithDissmissBlock:^(NSInteger buttonIndex) {
            }];
        }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接