React Native 0.73 iOS端应用运行时Linking.addEventListener('url')未触发的问题
最近开发React Native 0.73项目时,用Linking API处理深度链接碰到了个iOS专属的坑——Android上一切正常,iOS这边却卡壳了,跟大家唠唠这个情况和我折腾出来的解决办法。
预期表现&Android实际效果
我本来以为不管应用在前台还是后台,只要打开深度链接,Linking.addEventListener('url', callback)这个监听器就会触发,回调里就能拿到链接做后续处理。这个逻辑在Android上跑起来顺得不行,完全没毛病。
iOS上的诡异表现
结果到了iOS设备或者模拟器上,情况就不对了:打开深度链接确实能把后台的应用拉到前台,但是那个url监听器就像睡着了一样,完全不触发回调,试了N次都是这样,差点把我整懵。
踩坑后总结的解决办法
后来查了一堆资料又反复调试,终于把问题解决了,给大家列几个关键的排查点:
检查AppDelegate的配置
iOS这边的深度链接需要AppDelegate里的方法把事件传递给RN的Linking模块,要是这块没配置对,RN根本收不到事件。打开你的AppDelegate.mm文件,确保有这两段代码:#import <React/RCTLinkingManager.h> // 处理普通URL Scheme - (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options { return [RCTLinkingManager application:app openURL:url options:options]; } // 处理Universal Links - (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler { return [RCTLinkingManager application:application continueUserActivity:userActivity restorationHandler:restorationHandler]; }要是用的是Swift版AppDelegate,也要确保正确调用RCTLinkingManager的对应方法。
正确注册和清理监听器
别随便在子组件里注册监听器,最好在根组件的useEffect里注册,而且一定要记得在组件卸载时清理,不然可能会有内存泄漏或者监听失效的问题:import { useEffect } from 'react'; import { Linking } from 'react-native'; function App() { useEffect(() => { // 定义深度链接处理逻辑 const handleDeepLink = (event) => { console.log('收到深度链接:', event.url); // 这里写你的业务逻辑,比如跳转页面、解析参数 }; // 注册监听器 const linkSubscription = Linking.addEventListener('url', handleDeepLink); // 组件卸载时移除监听 return () => { linkSubscription.remove(); }; }, []); // 你的其他组件代码... }另外,要是应用刚启动时的深度链接,可以用
Linking.getInitialURL()来获取,配合监听器就能覆盖所有场景。确认Info.plist的URL Scheme配置
最后再检查下Info.plist里的URL Scheme有没有配对,要是Scheme错了,iOS根本不会把链接传给你的应用:<key>CFBundleURLTypes</key> <array> <dict> <key>CFBundleURLSchemes</key> <array> <string>你的自定义scheme,比如myapp</string> </array> </dict> </array>比如你用
myapp://test来测试,这里的Scheme就是myapp,一定要对应上。
我当时就是按这个顺序排查,先是补了AppDelegate里的代码,然后调整了监听器的注册位置,最后确认了Scheme配置,问题就解决了,iOS上的监听器终于正常触发了。如果你也碰到这个坑,可以试试这些办法。
备注:内容来源于stack exchange,提问作者Zukuan JING

