iOS18+Xcode16: openURL弃用导致微信分享无响应的问题

背景

最近遇到个问题,当Xcode升级到16,且设备升级到iOS 18后,使用微信分享无法调起微信,控制台输出:
BUG IN CLIENT OF UIKIT: The caller of UIApplication.openURL(_:) needs to migrate to the non-deprecated UIApplication.open(_:options:completionHandler:). Force returning false (NO).

这个问题原因很简单,是因为在iOS 18以后,openURL:完全被弃用,需要用openURL:options:completionHandler:替代。

实际上在iOS10以后,Apple就已经在Xcode中提示openURL:将会被弃用,需要用openURL:options:completionHandler:替代。但实际上在iOS 17之前openURL:一直是可以用的,所以很多开发者包括很多知名的 SDK都忽略了,直到本次iOS 18完全弃用,导致问题的出现。

解决方案

解决方案也很简单:
1.如果代码是自己的写的,全文搜索并替换相关方法即可。
2.如果是第三方SDK,更新SDK即可。或者手动替换SDK里面相关方法。

特例

我遇到的问题比较奇葩,是某个第三方SDK里面出现了openURL:方法,但是这个SDK已经完全停止维护,几年不更新了,而且这个SDK不是源码模式,而是编译成了.a文件,根本没办法看到他的代码,更没办法手动替换它的代码,这特么就尴尬了。找了很久,终于找到替代方案,那就是利用runtime来替换相关方法。

Objective-C版本参考以下方案:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
    [AppDelegate hookOldOpenUrl:AppDelegate.class];
}

- (BOOL)g_openURL:(NSURL*)url{
    [UIApplication.sharedApplication openURL:url options:nil completionHandler:nil];
    return YES;
}

+ (void)hookOldOpenUrl:(Class)targetCls{
    Class cls = [UIApplication class];
    if (cls) {
        Method originalMethod =class_getInstanceMethod(cls, @selector(openURL:));
        Method swizzledMethod =class_getInstanceMethod(targetCls, @selector(g_openURL:));
        if (!originalMethod || !swizzledMethod) {
            return;
        }
        IMP originalIMP = method_getImplementation(originalMethod);
        IMP swizzledIMP = method_getImplementation(swizzledMethod);
        const char *originalType = method_getTypeEncoding(originalMethod);
        const char *swizzledType = method_getTypeEncoding(swizzledMethod);
        class_replaceMethod(cls,@selector(openURL:),swizzledIMP,swizzledType);
        class_replaceMethod(cls,@selector(g_openURL:),originalIMP,originalType);
    }
}

Swift版本参考以下方案:

func hookOldOpenUrl(tragetCls:AnyClass){
       let cls = UIApplication.self
       let originalSelector = #selector(UIApplication.openURL(_:))       
       let swizzledSelector = #selector(g_openURL)
       let originalMethod = class_getInstanceMethod(cls, originalSelector)
       let swizzledMethod = class_getInstanceMethod(tragetCls, swizzledSelector)
       let didAddMethod: Bool = class_addMethod(cls, originalSelector, method_getImplementation(swizzledMethod!), method_getTypeEncoding(swizzledMethod!))
       if didAddMethod {
               class_replaceMethod(cls, swizzledSelector, method_getImplementation(originalMethod!), method_getTypeEncoding(originalMethod!))
       } else {
               method_exchangeImplementations(originalMethod!, swizzledMethod!)
       }

}

@objc func g_openURL(url:URL)->Bool{
       UIApplication.shared.open(url)
       return true
}

再次运行即可修复该问题。

要安装Docker并安装插件,可以按照以下步骤进行操作: 1. 首先,安装Docker。可以按照官方文档提供的步骤进行安装,或者使用适合您操作系统的包管理器进行安装。 2. 安装Docker Compose插件。可以使用以下方法安装: 2.1 下载指定版本的docker-compose文件: curl -L https://github.com/docker/compose/releases/download/1.21.2/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose 2.2 赋予docker-compose文件执行权限: chmod +x /usr/local/bin/docker-compose 2.3 验证安装是否成功: docker-compose --version 3. 在安装插件之前,可以测试端口是否已被占用,以避免编排过程中出错。可以使用以下命令安装netstat并查看端口号是否被占用: yum -y install net-tools netstat -npl | grep 3306 现在,您已经安装了Docker并安装了Docker Compose插件,可以继续进行其他操作,例如上传docker-compose.yml文件到服务器,并在服务器上安装MySQL容器。可以参考Docker的官方文档或其他资源来了解如何使用Docker和Docker Compose进行容器的安装和配置。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [Docker安装docker-compose插件](https://blog.youkuaiyun.com/qq_50661854/article/details/124453329)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *3* [Docker安装MySQL docker安装mysql 完整详细教程](https://blog.youkuaiyun.com/qq_40739917/article/details/130891879)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值