美文网首页锻炼吃饭的家伙iOS bug修复iOS 开发小技巧
私有API-iOS10 openURL方法跳转到设置界面失效的解

私有API-iOS10 openURL方法跳转到设置界面失效的解

作者: 黑超熊猫zuik | 来源:发表于2016-10-10 20:48 被阅读14132次

    问题

    在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;
    

    头文件参考:LSApplicationWorkspace.h
    使用方法:

    //注意首字母改成了大写,prefs->Prefs
    NSURL*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,因为它是不可靠的。也许某天苹果就把它移除了。

    update:

    • 还有一步遗漏了,app需要添加一个Prefs的URL Schemes,即添加到info.plistLSApplicationQueriesSchemes项中。

    参考:

    http://stackoverflow.com/a/39102075/6380485
    https://www.zhihu.com/question/50635906/answer/125195317
    iOS10系统URLScheme

    相关文章

      网友评论

      • 希达like:在systemVersion 大于10.0 小于11.0 时 调用下面方法 可以正常跳转。这和楼主说的iOS10只允许UIApplicationOpenSettingsURLString方式跳转到设置里自己app的界面,对跳转到其他界面做了限制 相矛盾啊
        [[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"App-Prefs:root=Privacy&path=CAMERA"] options:@{} completionHandler:nil];
        希达like:@黑超熊猫zuik 好的 谢谢楼主解疑
        黑超熊猫zuik:用Prefs会跳转失败,用App-Prefs可以。现在不建议用这种方式跳转,苹果审核时会把Prefs视为私有 API
      • 捏捏你的脸:兄弟 多谢。
      • 李某lkb:这个混淆失败,被拒
        黑超熊猫zuik:@李某lkb 苹果如果搜出了私有api会在回复邮件里列出来的,你检查看看是不是有遗漏没混淆的
        李某lkb:@黑超熊猫zuik ascii混淆的
        黑超熊猫zuik:@李某lkb 你是怎么混淆的?
      • 丶雨凡:感谢作者.本人测试了Swift工程,引入OC文件,在OC文件里写的跳转到系统密码设置,没有导入MobileCoreServices,
        没有添加LSApplicationQueriesSchemes也成功了.说明:我使用企业账号,不上APPStore的.:clap:
      • 54685FD78BDA:私有api跳转你测试过吗?尤其是真机上
        黑超熊猫zuik:@54685FD78BDA 我在6s/10.1.1,iPad mini3/10.0.1真机上都是可以的,你是不是没把prefs开头大写?
        54685FD78BDA:@zuik黑超熊猫 我昨天测试,模拟器ok,真机(ip7)已经不能跳转
        黑超熊猫zuik:@54685FD78BDA 测试正常

      本文标题:私有API-iOS10 openURL方法跳转到设置界面失效的解

      本文链接:https://www.haomeiwen.com/subject/qwsvyttx.html