【问题标题】:React Native deep linking does not work when app is killed当应用程序被杀死时,React Native 深度链接不起作用
【发布时间】:2020-03-14 20:12:46
【问题描述】:

可能的解决方案

与此同时,我自己找到了一个解决方案,可能不是那么“干净”。

在 App.js 中,我像这样指定我的 initialRouteName:

import {createAppContainer} from 'react-navigation';
import {createStackNavigator} from 'react-navigation-stack';

import Home from './screens/Home';
import Form from './screens/Form';
import {Linking, Platform} from 'react-native';
import React from 'react';

function getRoute() {
  let route = "";
  Linking.getInitialURL().then(url => {
    route = url;
  })

  if (route === 'playgroundapp://form') {
    return 'Form';
  } else {
    return "Home"
  }
}

const AppNavigator = createStackNavigator(
    {
  Home: { screen: Home },
  Form: { screen: Form },
}, {
      initialRouteName: getRoute()
    });

export default createAppContainer(AppNavigator);

问题

我希望能够从我的 iOS 小部件深层链接到我的 React Native 应用程序。
当应用程序在后台运行时,链接工作正常,它导航到正确的页面。但是当应用程序被杀死时,它只打开应用程序,而不再导航到正确的页面。

我遵循了这个教程:https://medium.com/react-native-training/deep-linking-your-react-native-app-d87c39a1ad5e

根据官方文档做了一些调整:https://facebook.github.io/react-native/docs/linking

AppDelegate.m

#import "AppDelegate.h"

#import <React/RCTBridge.h>
#import <React/RCTBundleURLProvider.h>
#import <React/RCTRootView.h>

#import <React/RCTLinkingManager.h>

@implementation AppDelegate

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

- (BOOL)application:(UIApplication *)application continueUserActivity:(nonnull NSUserActivity *)userActivity
 restorationHandler:(nonnull void (^)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler
{
 return [RCTLinkingManager application:application
                  continueUserActivity:userActivity
                    restorationHandler:restorationHandler];
}

- (NSURL *)sourceURLForBridge:(RCTBridge *)bridge
{
#if DEBUG
  return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil];
#else
  return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"];
#endif
}

@end

App.js

import {createAppContainer} from 'react-navigation';
import {createStackNavigator} from 'react-navigation-stack';

import Home from './screens/Home';
import Form from './screens/Form';

const AppNavigator = createStackNavigator({
  Home: { screen: Home },
  Form: { screen: Form },
});

export default createAppContainer(AppNavigator);

Home.js

import React, {Component} from 'react';

import {
  Linking,
  Platform,
  Text,
  View,
} from 'react-native';

import Form from './Form';

export default class Home extends Component {
  componentDidMount() {
    if (Platform.OS === 'android') {
      Linking.getInitialURL().then(url => {
        this.navigate(url);
      });
    } else {
      Linking.addEventListener('url', this.handleOpenURL);
    }
  }

  componentWillUnmount() {
    Linking.removeEventListener('url', this.handleOpenURL);
  }

  handleOpenURL = event => {
    console.log(event.url)
    this.navigate(event.url);
  };

  navigate = url => {
    const {navigate} = this.props.navigation;
    const route = url.replace(/.*?:\/\//g, '');

    const routeName = route.split('/')[0];
    if (routeName === 'form') {
      navigate('Form');
    }
  };

  }

  render() {
    return (
      <View style={styles.container}>
        <Text style={styles.h1}>Playground</Text>
      </View>
    );
  }
}

所以我从我的小部件链接到这样的应用程序: extensionContext?.open(URL(string: "playgroundapp://form")! , completionHandler: nil)

为什么当应用程序不在后台运行时它不起作用?我发现了一些类似的问题,但没有对我有用或过时的答案。

【问题讨论】:

  • 有人找到解决方案了吗?

标签: ios react-native deep-linking


【解决方案1】:

像这样编写配置。

const config = {
  ...config,
  const onReceiveURL = ({ url }: { url: string }) => {
       listener(url);
    };

    // Listen to incoming links from deep linking
    Linking.addEventListener('url', onReceiveURL);

    return () => {
      // Clean up the event listeners
      Linking.removeEventListener('url', onReceiveURL);
    };

}

【讨论】:

    【解决方案2】:

    如果您使用 react-navigation 深层链接,请确保您的调试器已关闭。并且您可以看到带有警报组件替换的参数

    【讨论】:

      【解决方案3】:

      检查这个包。

      从“@react-native-firebase/dynamic-links”导入动态链接;

      dynamicLinks().getInitialLink()
            .then(link => {
          // this method will call when app is closer or killed
              console.log('dynamicLinksnew :', link);
           
            });
      
      dynamicLinks().onLink(async (link) => {
            // this method call when app is in background or foreground 
           console.log('dynamicLinks :', link);
           
          });
      

      【讨论】:

        【解决方案4】:

        如果对于 iOS,您已按如下方式处理 RCTLinkingManager

        - (BOOL)application:(UIApplication *)application
                    openURL:(NSURL *)url
                    options:(NSDictionary<NSString *, id> *)options
        {
          BOOL handled = [[RNFirebaseLinks instance] application:application openURL:url options:options];
        
          if(!handled)
          {
            handled = [RCTLinkingManager application:application openURL:url options:options];
          }
        
          return handled;
        }
        
        - (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler
        {
          BOOL handled = [[RNFirebaseLinks instance] application:application continueUserActivity:userActivity restorationHandler:restorationHandler];
          if(!handled)
          {
            handled = [RCTLinkingManager application:application continueUserActivity:userActivity restorationHandler:restorationHandler];
          }
        
          return handled;
        }
        

        您已按照React Native linking 中提到的程序进行操作。

        _dynamicLinkListener; // variable defined to hold listeener instance
        
         componentDidMount() {
                this.setUpDynamicLink();
                this.setUpDeepLink();
            }
        
         componentWillUnmount() {
                this.cleanUpDynamicLink();
                this.cleanUpDeepLink();
            }
        
        setUpDynamicLink = () => {
                // will work when link is opening the app
                Firebase.links()
                    .getInitialLink()
                    .then((url) => {
                        this.handleURL(url);
                    });
        
                // listener will work when app is already opened or in background
                this._dynamicLinkListener = Firebase.links().onLink((url) => {
                    this.handleURL(url);
                });
            }
        
        setUpDeepLink = () => {
                // will work when link is opening the app
                Linking.getInitialURL().then(url => {
                    this.handleURL(url);
                });
        
                // listener will work when app is already opened or in background
                Linking.addEventListener('url', this.handleURL);
            }
        
        cleanUpDynamicLink = () => {
                this._dynamicLinkListener();
            }
        
        cleanUpDeepLink = () => {
                Linking.removeEventListener('url', this.handleURL);
            }
        
        handleURL = (event) => {
                let url = "";
        
                if (!event) {
                    return "";
                }
        
                if (typeof event == 'string') {
                    url = event;
                } else {
                    url = (event.url) ? event.url : "";
                }
        
                if (!url) {
                    return;
                }
        
        
                console.debug(url);
            }
        

        那你就可以走了。当应用程序处于foregroundbackground 而不是killed 状态时,我收到了深度链接回调。

        为您的应用程序禁用调试并使用一些Alert 来显示url,而不是使用控制台输出。 Linking 在启用调试时有一些问题。在此之后我能够在警报中看到 url。

        上面提到的代码也有动态链接的Firebase实现,你可以删除你不想要的。

        【讨论】:

        • 谢谢,停止调试已帮我解决了
        猜你喜欢
        • 2020-10-22
        • 1970-01-01
        • 2021-05-29
        • 1970-01-01
        • 1970-01-01
        • 2020-08-12
        • 1970-01-01
        • 2020-07-17
        • 1970-01-01
        相关资源
        最近更新 更多