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

打印 上一主题 下一主题

主题 841|帖子 841|积分 2523

背景

最近遇到个问题,当Xcode升级到16,且装备升级到iOS 18后,使用微信分享无法调起微信,控制台输出:
BUG IN CLIENT OF UIKIT: The caller of UIApplication.openURL(_ needs to migrate to the non-deprecated UIApplication.open(_ptions:completionHandler. Force returning false (NO).
这个问题原因很简单,是因为在iOS 18以后,openURL:完全被弃用,需要用openURLptions:completionHandler:替代。
现实上在iOS10以后,Apple就已经在Xcode中提示openURL:将会被弃用,需要用openURLptions:completionHandler:替代。但现实上在iOS 17之前openURL:一直是可以用的,以是很多开发者包括很多知名的 SDK都忽略了,直到本次iOS 18完全弃用,导致问题的出现。
办理方案

办理方案也很简单:
1.如果代码是自己的写的,全文搜索并替换相干方法即可。
2.如果是第三方SDK,更新SDK即可。大概手动替换SDK内里相干方法。
特例

我遇到的问题比较奇葩,是某个第三方SDK内里出现了openURL:方法,但是这个SDK已经完全制止维护,几年不更新了,而且这个SDK不是源码模式,而是编译成了.a文件,根本没办法看到他的代码,更没办法手动替换它的代码,这特么就尴尬了。找了很久,终于找到替代方案,那就是利用runtime来替换相干方法。
Objective-C版本参考以下方案:
  1. - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
  2.     [AppDelegate hookOldOpenUrl:AppDelegate.class];
  3. }
  4. - (BOOL)g_openURL:(NSURL*)url{
  5.     [UIApplication.sharedApplication openURL:url options:nil completionHandler:nil];
  6.     return YES;
  7. }
  8. + (void)hookOldOpenUrl:(Class)targetCls{
  9.     Class cls = [UIApplication class];
  10.     if (cls) {
  11.         Method originalMethod =class_getInstanceMethod(cls, @selector(openURL:));
  12.         Method swizzledMethod =class_getInstanceMethod(targetCls, @selector(g_openURL:));
  13.         if (!originalMethod || !swizzledMethod) {
  14.             return;
  15.         }
  16.         IMP originalIMP = method_getImplementation(originalMethod);
  17.         IMP swizzledIMP = method_getImplementation(swizzledMethod);
  18.         const char *originalType = method_getTypeEncoding(originalMethod);
  19.         const char *swizzledType = method_getTypeEncoding(swizzledMethod);
  20.         class_replaceMethod(cls,@selector(openURL:),swizzledIMP,swizzledType);
  21.         class_replaceMethod(cls,@selector(g_openURL:),originalIMP,originalType);
  22.     }
  23. }
复制代码
Swift版本参考以下方案:
  1. func hookOldOpenUrl(tragetCls:AnyClass){
  2.        let cls = UIApplication.self
  3.        let originalSelector = #selector(UIApplication.openURL(_:))      
  4.        let swizzledSelector = #selector(g_openURL)
  5.        let originalMethod = class_getInstanceMethod(cls, originalSelector)
  6.        let swizzledMethod = class_getInstanceMethod(tragetCls, swizzledSelector)
  7.        let didAddMethod: Bool = class_addMethod(cls, originalSelector, method_getImplementation(swizzledMethod!), method_getTypeEncoding(swizzledMethod!))
  8.        if didAddMethod {
  9.                class_replaceMethod(cls, swizzledSelector, method_getImplementation(originalMethod!), method_getTypeEncoding(originalMethod!))
  10.        } else {
  11.                method_exchangeImplementations(originalMethod!, swizzledMethod!)
  12.        }
  13. }
  14. @objc func g_openURL(url:URL)->Bool{
  15.        UIApplication.shared.open(url)
  16.        return true
  17. }
复制代码
再次运行即可修复该问题。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

冬雨财经

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表