示例:项目里面有扫码功能,当用户第一次扫码—选择不允许访问相机,再次使用扫码APP就需要引导用户到系统的相机页面开启相机权限。类似的功能还有定位、录音、蓝牙、相册等,这些功能都需要给用户提示/引导。
根据上述情况,市场上的App有两种做法:
①不做跳转,给用户提示;
②给用户提示,并做跳转,引导用户到设置界面;
具体看需求吧,亲测过微信(包括定位和相机权限)、QQ、淘宝的(iOS 10 - iOS 11)都没有做跳转,和淘票票一样都是给的提示,不过支付宝的相机权限也做了跳转。
正文:
1.第一次网上查找总结的结果 ❎
可以看到网上大多数的解释是:
①iOS 10之前可以进入系统设置的子页面
②iOS 10之后不允许跳转到设置的子页面,只允许跳转到设置界面(首页)
说明:上述这种方法我没应用到已上架项目,不过看到有的人通过使用苹果私有API去实现iOS10以后版本能够跳转到系统设置子页面,但同时会加大遇到审核被拒的可能性,所以也不建议大家使用;感兴趣的朋友可以上网查一下相关的代码。
指南2.5.1-性能-软件需求,您的应用程序使用或引用以下非公共的api:LSApplicationWorkspace
准则2.5.1-性能-软件需求
您的应用程序使用或引用以下非公开的api: LSApplicationWorkspace
在App Store中不允许使用非公开的api,因为如果这些api发生变化,就会导致糟糕的用户体验。
下一个步骤
为了解决这个问题,请修改您的应用程序,删除任何非公开的api。如果您在源代码中定义了与上述api相同的方法,我们建议更改您的方法名称,以便它们不再与苹果的私有api发生冲突,以避免您的应用程序在未来的提交中被标记。
另外,如果您正在使用第三方库,请更新这些库的最新版本。如果您没有访问库的源代码,您可以使用“字符串”或“otool”命令行工具搜索已编译的二进制文件。“strings”工具可以输出库调用的方法列表和“otool-ov”将输出objective-a类结构及其定义的方法。这些工具可以帮助您缩小问题代码所在的位置。您还可以使用“nm”工具来验证是否有任何第三方库调用这些api。
思考:参考的其中一篇博客甚至展示了了苹果的文件来证明上述第二点,但现在我再次访问那个博客已经是404了;得到上面的结果让我很不甘心,心想苹果不会这么绝情,于是我就测试了一下其他APP,发现iOS 10以后可以跳转到设置界面,看来我没找对答案;于是又搜了一波,终于找到了解决方案。
2. 跳转至系统设置页面的正确姿势(适配 iOS 8.1 ~ iOS 14) ✅
⚠️ 不要在URL Types 中设置prefs 了;
⚠️ 下面的方法在iOS 11+不能实现,本文后面会介绍怎么在iOS 11+下实现该方案,请耐心看完。
例:跳转到系统设置-相机权限
// 亲测:iOS 8.1 ~ iOS 14
- (IBAction)pushToSystemConfig:(UIButton *)sender {
NSURL *url = [NSURL URLWithString:@"App-Prefs:root=Privacy&path=CAMERA"];
if ([[UIApplication sharedApplication] canOpenURL:url]){
if (@available(iOS 10.0, *)) {
[[UIApplication sharedApplication] openURL:url options:@{} completionHandler:nil];
}else {
[[UIApplication sharedApplication] openURL:url];
}
}
}
补充:
① iOS 9.0之后版本,应用间进行跳转,在状态栏的左边增加了快速返回上一App的点击事件,方便了不少;
② 需要注意的是,当你改变了系统相机权限后回到App中,该App会重启;这里还测试了定位功能,而开启定位功能回到应用不会引起应用重启,不过这你也不用担心,这是系统层决定的。
4. 跳转至系统设置页面的正确姿势(适配 iOS 8.1 ~ iOS 14) ✅
关于iOS 11+,上面的做法当然行不通了,但还是有办法满足需求的,可以看本文上面的摩拜单车跳转到自己的设置界面的图 (现在主流App都是这个做法)
原因:iOS 11+ 现在只允许跳转到系统设置首页/该应用的设置界面⚠️ 因为有一些小伙伴是新建一个测试工程进行测试的,并没有登入开发者账号,工程也就没有配置开发证书,在模拟器上测试时,发现只能跳转到设置首页,仔细观察可以发现在设置界面底部应用列表根本找不到你测试的应用,所以就不能跳转到该应用的设置界面
// 跳转到设置 - 相机 / 该应用的设置界面
NSURL *url1 = [NSURL URLWithString:@"App-Prefs:root=Privacy&path=CAMERA"];
// iOS10也可以使用url2访问,不过使用url1更好一些,可具体根据业务需求自行选择
NSURL *url2 = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
if (@available(iOS 11.0, *)) {
if ([[UIApplication sharedApplication] canOpenURL:url2]){
[[UIApplication sharedApplication] openURL:url2 options:@{} completionHandler:nil];
}
} else {
if ([[UIApplication sharedApplication] canOpenURL:url1]){
if (@available(iOS 10.0, *)) {
[[UIApplication sharedApplication] openURL:url1 options:@{} completionHandler:nil];
} else {
[[UIApplication sharedApplication] openURL:url1];
}
}
}
3. 如果你不是跳转到系统相机界面,怎么办呢?
其他跳转如下:
注:App-Prefs等同于App-prefs
名称 | 对应字符串 |
---|---|
无线局域网 | App-Prefs:root=WIFI |
蓝牙 | App-Prefs:root=Bluetooth |
蜂窝移动网络 | App-Prefs:root=MOBILE_DATA_SETTINGS_ID |
个人热点 | App-Prefs:root=INTERNET_TETHERING |
运营商 | App-Prefs:root=Carrier |
通知 | App-Prefs:root=NOTIFICATIONS_ID |
通用 | App-Prefs:root=General |
通用-关于本机 | App-Prefs:root=General&path=About |
通用-键盘 | App-Prefs:root=General&path=Keyboard |
通用-辅助功能 | App-Prefs:root=General&path=ACCESSIBILITY |
通用-语言与地区 | App-Prefs:root=General&path=INTERNATIONAL |
通用-还原 | App-Prefs:root=Reset |
墙纸 | App-Prefs:root=Wallpaper |
Siri | App-Prefs:root=SIRI |
隐私 | App-Prefs:root=Privacy |
Safari | App-Prefs:root=SAFARI |
音乐 | App-Prefs:root=MUSIC |
音乐-均衡器 | App-Prefs:root=MUSIC&path=com.apple.Music:EQ |
照片与相机 | App-Prefs:root=Photos |
FaceTime | App-Prefs:root=FACETIME |
如果你发现上面还是没有你需要的字符串怎么办?
找规律:比如我这篇写的进入相机权限页面就没有;将真机/模拟器的语言改为英文,再仔细对比上面的字符串,就会发现规律,多尝试几遍就试出来相应的字符串了。
补充:
名称 | 对应字符串 |
---|---|
个人热点 | App-Prefs:root=INTERNET_TETHERING |
运营商 | App-Prefs:root=Carrier |
隐私->麦克风 | App-Prefs:root=Privacy&path=MICROPHONE |
隐私->定位 | App-Prefs:root=Privacy&path=LOCATION |
隐私->相机 | App-Prefs:root=Privacy&path=CAMERA |