【问题标题】:Deep Link is not handled when app is closed React Native iOS app关闭应用程序时不处理深度链接 React Native iOS 应用程序
【发布时间】:2019-08-18 11:22:06
【问题描述】:

我正在为 iOS 开发一个 React Native 应用程序。

此应用必须能够打开深层链接,并且在后台打开应用时可以正常工作。 当应用关闭时,原生 iOS 代码 (Objective-C) 无法获取应用打开时使用的 URL。

据我了解它是如何工作的,我必须检查 launchOptions 的 NSDictionary 以查看应用程序是否已通过 URL 启动。如果URL初始化对应的key存在则返回true执行以下代码

- (BOOL)application:(UIApplication *)application
        openURL:(NSURL *)url
        options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
  return [RCTLinkingManager application:application openURL:url options:options];

  return YES;
}

这是必须执行的函数才能获取打开应用程序的初始 URL。这是我的应用程序 didFinishWithLaunchOptions 的代码:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary  *)launchOptions
{
    if ([launchOptions objectForKey:UIApplicationLaunchOptionsURLKey]) {
    return true;
  }
}

【问题讨论】:

  • 您能否解决这个问题,因为我们也只在 IOS 中处于同一位置如果您找到解决方案,请告诉我?谢谢

标签: ios objective-c react-native deep-linking


【解决方案1】:

虽然绝对不是一个答案,但我已经(非常)通过更改(或者如果您还没有,添加)解决了这个问题(至少在规范解决方案可用之前) - (BOOL)application:(UIApplication *)application continueUserActivity:(nonnull NSUserActivity *)userActivity restorationHandler:(nonnull void (^)(NSArray&lt;id&lt;UIUserActivityRestoring&gt;&gt; * _Nullable))restorationHandler { 中的 AppDelegate.m 到:

- (BOOL)application:(UIApplication *)application continueUserActivity:(nonnull NSUserActivity *)userActivity
 restorationHandler:(nonnull void (^)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler
{
  NSURL *url = [userActivity webpageURL];
  BOOL result = [RCTLinkingManager application:application
                          continueUserActivity:userActivity
                            restorationHandler:restorationHandler];
  if([userActivity webpageURL]){
    #if DEBUG
    float seconds = 3.5;
    #else
    float seconds = 1.5;
    #endif
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(seconds * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
      NSURL *newUrl = [NSURL URLWithString:[NSString stringWithFormat:@"MYAPPSCHEME:/%@", url.path]];
      [[UIApplication sharedApplication] openURL:newUrl options:@{} completionHandler:nil];
    });
  }
  
  return result;
}

它基本上检查是否有一个可用的 URL 导致启动,并在“事情已经解决”后调用对应用程序的开放 URL 调用(因为在调试模式下加载需要更长的时间,我已更改为 3.5 秒它处理得很好)。相应地更改seconds,当然还有MYAPPSCHEME。是的,MYAPPSCHEME: 之后有一个 单斜杠 (/) 而不是双斜杠,因为 url.path 似乎已经有一个前导斜杠。用我的应用程序方案替换 http[s] 的原因是,如果我离开 http[s]://,它会启动 Safari 而不是处理深层链接(当应用程序已经在运行并且URL 被处理)。我的应用以与常规 http 链接相同的方式处理自定义方案,因此它运行良好,但请确保您进行了相应的设置以使其正常工作。

在进行上述更改并重新编译后(不要忘记您是在 Objective-C 部分,而不是 JS/React Native),它起作用了。我希望看到一个实际的解决方案,而不是一个 hacky 的解决方法,但在那之前,这已经为我解决了。

【讨论】:

  • 不错的解决方法,它对我有用!对于未来的读者,MYAPPSCHEME 必须替换为 XCode -> Targets [your app] -> Info -> URL Types -> URL Schemes 中的那个
【解决方案2】:

对我来说,Intercom 不处理深层链接的核心问题是,如果应用程序从后台打开,react-native-intercom 不会通过didFinishLaunchingWithOptions 将初始 URL 传递给应用程序。

而是react-native-intercom 在应用程序启动后立即调用openURL 方法,而应用程序的react-native 部分错过了此事件。

解决方案是在openURL 方法中创建一个新线程。锁定它以停止执行,然后在 React 应用程序向本机代码发出信号,表明它已准备好处理深度链接时解锁踏板。修复有点复杂,所以我创建了一个单独的存储库,描述问题和解决方案。

核心思想可以用代码描述为:

dispatch_queue_t queue = dispatch_queue_create("<yourAppName>.openUrlQueue", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queue, ^{
  while (!DeepLink.canHandleDeepLinks) {
    [DeepLink.canHandleDeepLinksLock wait];
  }
  [DeepLink.canHandleDeepLinksLock unlock];


  dispatch_async(dispatch_get_main_queue(), ^{
    // This method call will trigger the Linking event with URL to be dispatched to your 'javascript' code
    [RCTLinkingManager application:application openURL:url options:options];
  });
});

我创建了一个repository 来解决这个问题。去看看吧。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-10-22
    • 1970-01-01
    • 1970-01-01
    • 2020-03-14
    • 1970-01-01
    • 2022-12-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多