zoukankan      html  css  js  c++  java
  • iOS10 openURL方法跳转到设置界面

    问题

    在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,因为它是不可靠的。也许某天苹果就把它移除了。

    以下是摘抄自GitHub上的一段可以通过Google私有文件


    2down vote
    +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.

    1. Add MobileCoreServices Framework in your bundle
    2. Create LSApplicationWorkspace.h file with the code exactly same as the code provided at here "https://github.com/nst/iOS-Runtime-Headers/blob/master/Frameworks/MobileCoreServices.framework/LSApplicationWorkspace.h".
    3. Now add this LSApplicationWorkspace.h file into your bundle
    4. Create bridging header for your swift app
    5. Add #import "LSApplicationWorkspace.h" in your bridging header
    6. Now add import MobileCoreServices in your current file and add your code let test = LSApplicationWorkspace.defaultWorkSpace(), it will work fine.

    NOTE: For using any private header, you must have to include its .h file into your code. You can find any private headers by searching "runtime headers" in google. You will get all runtime headers. And to include that header in your swift code, you need to go via bridging-header.

  • 相关阅读:
    Jmeter-日期格式转换为时间戳
    Java中异常的处理
    Java中接口的新特性,为接口添加静态方法和默认方法
    Java接口的应用之代理模式
    Java之接口(interface)的理解
    JAVA中使用super调用属性、方法、构造器
    JAVA方法的重写
    Java之方法
    Java之匿名对象
    关于多态性的使用
  • 原文地址:https://www.cnblogs.com/shycie/p/6677004.html
Copyright © 2011-2022 走看看