问题
在iOS10之前,跳转到系统设置界面的某个指定界面的方式如下:
//打开定位服务界面NSURL*url=[NSURL URLWithString:@"prefs:root=Privacy&path=LOCATION"]; if ([[UIApplication sharedApplication] canOpenURL:url]) { [[UIApplication sharedApplication] openURL:url]; };
但是在iOS10上,调用canOpenURL:打开系统设置界面时控制台会报如下错误,并且无法跳转:
-canOpenURL: failed for URL: "Prefs:root=Privacy&path=LOCATION" - error: "The operation couldn’t be completed. (OSStatus error -10814.)"
原因是iOS10只允许如下方式跳转到设置里自己app的界面,对跳转到其他界面做了限制:
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:UIApplicationOpenSettingsURLString]];
解决方法
可以使用 MobileCoreServices.framework
里的私有API:
- (BOOL)openSensitiveURL:(id)arg1 withOptions:(id)arg2;
头文件参考:
使用方法:
//注意首字母改成了大写,prefs->PrefsNSURL*url=[NSURL URLWithString:@"Prefs:root=Privacy&path=LOCATION"]; Class LSApplicationWorkspace = NSClassFromString(@"LSApplicationWorkspace"); [[LSApplicationWorkspace performSelector:@selector(defaultWorkspace)] performSelector:@selector(openSensitiveURL:withOptions:) withObject:url withObject:nil];
MobileCoreServices.framework
不是私有库,所以直接使用 performSelector:
即可调用私有API。
注意
- iOS10的系统URLScheme改成了首字母大写,使用小写的方式会无法打开。
- 使用私有API的app无法通过App Store审核。你也可以尝试把私有类名和selector字符串混淆一下,绕过审核。例如 用ASCII混淆的方法:
- (UIView *)statusBarView { UIView *statusBar = nil; NSData *data = [NSData dataWithBytes:(unsigned char []){ 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x42, 0x61, 0x72} length:9]; NSString *key = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding]; id object = [UIApplication sharedApplication]; if ([object respondsToSelector:NSSelectorFromString(key)]) { statusBar = [object valueForKey:key]; } return statusBar; }
不过,还是不建议使用私有API,因为它是不可靠的。也许某天苹果就把它移除了。
以下是摘抄自GitHub上的一段可以通过Google私有文件
2 +100 | Point 1: LSApplicationWorkspace is private api, so if you use this and will upload your app to app store, it will get rejected. Point 2: If you are having any in-house app and still want to use this in your app, then below is the way to use it.
NOTE: For using any private header, you must have to include its |