android、ios配置scheme之后,react-native如何获取url,并且自动跳转到首页

react-navigation 配置

react-navigation (使用的是5.x版本)需要配置linking,官网链接https://reactnavigation.org/docs/5.x/deep-linking/

import React, { Component } from "react";
import { Image, Platform, Linking } from "react-native";
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';

import Home from "../screens/Home/index";

const prefix = Platform.OS == 'android' ? 'schemeapp://www.app.com/' : 'schemapp://www.app.com/';
const Stack = createStackNavigator();
const Tab = createBottomTabNavigator();
export default class Route extends Component {
    render() {
        
        const linking = {
            prefixes: [prefix]
        };
        return (
            <NavigationContainer
                linking={linking}
                ref={navigatorRef => {
                    NavigationService.setTopLevelNavigator(navigatorRef);
                }}
            >
                <Stack.Navigator
                    mode="modal"
                    headerMode="float"
                >
                    <Stack.Screen
                        name="Hhome"
                        component={Home}
                        options={{
                            title: '首页'
                        }}
                    />
                 </Stack.Navigator>
            </NavigationContainer>
            );
       }
 }

Android

先判断 是安卓还是ios,
如果是安卓环境,
监听APP是在后台,还是活跃的
先通过change监听,如果是活跃的,就调用跳转函数
跳转函数
通过Linking.getInitialURL() 获取外部跳转过来的url, 处理url 带过来的参数。
判断有没有登录
如果没有登录就跳转到登录页面,如果登录就跳转到首页。

import { StyleSheet, View, Linking, AppState, Platform, DeviceEventEmitter } from "react-native";

    async componentDidMount() {
        let self = this;
        if(Platform.OS == "ios"){
            // 要在 App 启动后也监听传入的 App 链接
            // schemeapp://Home?routeName=Home
            // schmeapp://www.app.com/Home?routeName=Home
            this.linkingIOS()
        } else {
            AppState.addEventListener('change', this.onAppStateChange);
            if (AppState.currentState === 'active') {
                console.log('走了吗')
                self.linking()
            }
        }
    }
    componentWillUnmount(){
        Linking.removeEventListener('url', this._handleOpenURL);
        AppState.removeEventListener('change', this.onAppStateChange)
    }
    // android scheme 监听
    onAppStateChange = (nextAppState) => {
        let self = this;
        if (nextAppState === 'active') {
            if(!self.state.activeFlag){
                self.linking()
            }
        }
    }
    // android 跳转
    linking(){
        let self = this;
        Linking.getInitialURL()
        .then((url) => {
            console.log('url',url)
            self.setState({
                activeFlag:true
            },()=>{
            if (url) {
                let obj = self.handleUrl(url);
                console.log('跳转',obj)
                // self.getLogin(obj,url)

                self.getISLogin(obj,url)
            } else {
                console.log('这个')
                self.interval = setTimeout(() => {
                    self.props.navigation.replace("Login");
                }, 2000);
            }
        })
            })
    }
    // 取URL地址参数转为对象
    handleUrl(url) {
        const urlObj = {};
        const middleStr = url.split('?');
        const paramPairStr = middleStr[1]?middleStr[1].split('&'):[];
        paramPairStr.forEach((element) => {
        const singleParamStr = element.split('=');
        urlObj[singleParamStr[0]] = singleParamStr[1];
        });
        console.log('参数',urlObj)
        return urlObj;
    }
    // android 判断是否登录
    getISLogin(param,url){
        let self = this;
        Storage.getString("token").then((token)=>{
        console.log('token',token)
        if(token){
            console.log('param',param)
            let routeName = param.routeName?param.routeName:'Home'
            if(routeName=='Home'){
                routeName = 'Home'
            }
            self.props.navigation.replace(routeName,param)
        } else{
            Toast.show('登录已过期,请重新登录!');
            self.props.navigation.replace("Login");
        }
    })
    }

IOS

如果是IOS 环境,调用linkingIOS 方法,
linkingIOS
先通过 Linking.getInitialURL() 获取 url, (测试大多数情况下是空的)
如果url不为空,就继续往后,判断登录;
如果url为空,就继续用另一种方法获取,用监听url获取,Linking.addEventListener('url', self._handleOpenURL)
如果监听到url,会调用_handleOpenURL方法,
_handleOpenURL方法
方法里面,获取到url,之后处理url带过啦的参数,再判断是否登录,如果登录了跳转到Home,如果没有登录就跳转到Login

    // ios 跳转
    linkingIOS(){
        let self = this;
        // Linking.getInitialURL():APP在运行当中,这个方法是不能处理APP被外部URL调起的情况的。
        Linking.getInitialURL().then((url) => {
            if (url) {
                let obj = self.handleUrl(url);
                console.log('跳转',obj)
                self.getISLogin(obj,url)
            } else{
                Linking.addEventListener('url', self._handleOpenURL);
                self.interval = setTimeout(() => {
                    self.props.navigation.replace("Login");
                }, 2000);
            }
        }).catch(err => {
            console.error('错误信息为:', err);
            alert('错误信息为:' + err);
        });
    }
    // ios 
    _handleOpenURL = (event) => {
        //调用事件通知
        console.log('监听了的url',event.url)
        let obj =  this.handleUrl(event.url);
        this.getISLoginios(obj,event.url)
    };
    // ios 判断是否登录
    getISLoginios(param,url){
        let self = this;
        Storage.getString("token").then((token) => {
            console.log('tokenios',token)
            if(token){
                console.log('param',param)
                let routeName = param.routeName?param.routeName:'Home'
                if(routeName=='Home'){
                    routeName = 'Home'
                }
                self.props.navigation.push(routeName,param) // 需要使用push,防止 多次监听,重复跳转
            } else {
                Toast.show('登录已过期,请重新登录!');
                self.props.navigation.push("Login");
            }
        })
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值