用于深层链接后未清除Linking.getInitialURL()

时间:2018-10-19 15:45:47

标签: android ios react-native deeplink

这个问题我已经有两个星期了。我使用Wix's Navigation浏览应用程序。我遵循this tutorial来实现深度链接/通用链接。

我有一个名为BaseScreen的基类,其中像教程中一样保留所有的Deeplink处理程序。 BaseScreen看起来像这样:

componentDidMount(){
    // this handles the case where the app is closed and is launched via Universal Linking.
    Linking.getInitialURL()
        .then((url) => {
          if (url) {
            // Alert.alert('GET INIT URL','initial url  ' + url)
            this.resetStackToProperRoute(url)
          }
        })
        .catch((e) => {})

   // This listener handles the case where the app is woken up from the Universal or Deep Linking
   Linking.addEventListener('url', this.appWokeUp);
  }

  componentWillUnmount(){
    // Remove the listener
    Linking.removeEventListener('url', this.appWokeUp);
  }

  appWokeUp = (event) => {
    // this handles the use case where the app is running in the background and is activated by the listener...
    // Alert.alert('Linking Listener','url  ' + event.url)
    this.resetStackToProperRoute(event.url)
  }

  resetStackToProperRoute = (url) => {
    // grab the trailing portion of the url so we can use that data to fetch proper information from the server
    let trailing = url.slice(url.lastIndexOf('=') + 1, url.length)
    // go to the desired screen with the trailing token grabbed from the url
    this.props.navigator.resetTo({
      screen: 'NewPassword',
      overrideBackPress: true,
      passProps: {
        token: trailing
      },
      animated: true,
      animationType: 'fade',
      navigatorStyle: {
      navBarHidden: true,
  }
})
  }

应用启动后,将显示屏幕LoginScreen,该屏幕扩展了上方的BaseScreen。终止应用程序后,单击邮件中的URL,应用程序首先启动LoginScreen,然后将其重定向到屏幕NewPassword,完成所有操作后,我将重定向回{{ 1}}的作者:

LoginScreen

但是this.props.navigator.resetTo({ screen: 'LoginScreen', animated: true, overrideBackPress: true, animationType: 'fade', navigatorStyle: { navBarHidden: true, } }) 中的Linking.getInitialURL()仍然收到旧网址,因此它将再次重定向到LoginScreen,这是一个循环。

我还尝试通过NewPassword passProps: {}却没有运气时使用resetTo选项。

我想解决此问题的唯一方法是在LoginScreen屏幕上完成所有操作后手动清除initialUrl。 NewPassword的侦听器应该在那里,因为如果我不杀死应用程序(只是将其最小化),则侦听器应该正在运行以导航到BaseScreen

Wix的导航中有一个有关Deeplink的文档,我尝试将方法NewPassword放到onNavigatorEvent(event)中,但是没有被调用。我不知道我是否想念什么。

谢谢您的时间。任何想法将不胜感激

2 个答案:

答案 0 :(得分:2)

Linking.getInitialURL()当我们再次返回同一页面时为我们提供了相同的Url,要解决此问题,我们可以做一个简单的条件,即不调用DeepLink函数。像...

步骤1:首先,初始化一个dummyDeepLinkedUrl字符串。

var dummyDeepLinkedUrl;

步骤2:检查是否存在类似条件,例如deeplinkUrl是否来自Linking.getInitialURL()且deeplinkUrl不等于dummyDeepLinkedUrl。

if (url && url != dummyDeepLinkedUrl) {}

步骤3:(如果不同),请调用Deeplink函数,并将deeplinkUrl分配给dummyDeepLinkedUrl。

    this.navigateToRespectivePage(url);
    dummyDeepLinkedUrl = url;

最后,它看起来像:

Linking.getInitialURL().then(url => {
      if (url && url != dummyDeepLinkedUrl) {
        this.navigateToRespectivePage(url);
        dummyDeepLinkedUrl = url;
      }
    });

答案 1 :(得分:0)

有两种方法可以处理打开应用程序的URL。

  1. 如果该应用程序已经打开,则该应用程序会处于前台状态,并且会触发Linking事件。 Linking.addEventListener(url,callback)。

  2. 如果尚未打开应用程序,则将其打开,并将URL作为initialURL传递。您可以使用以下方法处理这些事件: Linking.getInitialURL(url)-返回一个Promise,解析为 网址(如果有的话)。

您可以阅读more detail 这是例子

export default class App extends Component {
  constructor(props) {
    super(props)
    this.state = {
      initialised: false
    }
  }

  componentDidMount() {
    AppState.addEventListener('change', this._handleAppStateChange);
    Linking.addEventListener('url', event => {
       console.log('deep link from background', event.url)
    })
  }

  _handleAppStateChange = async (nextAppState) => {
    const url = await Linking.getInitialURL();
    if (url !== null && !this.state.initialised) {
      this.setState({ initialised: true })
      console.log('deep link from init app', url)
    }
  }

  componentWillUnmount() {
    AppState.removeEventListener('change', this._handleAppStateChange);
    Linking.removeEventListener('url')
  }
}