Zum*_*uma 9 deep-linking react-native react-navigation
我正在构建一个具有react-native和react-navigation库的移动应用程序,用于管理我的应用程序中的导航。现在,我的应用看起来像这样:
App [SwitchNavigator]
Splash [Screen]
Auth [Screen]
MainApp [StackNavigator]
Home [Screen] (/home)
Profile [Screen] (/profile)
Notifications [Screen] (/notifications)
Run Code Online (Sandbox Code Playgroud)
我已经将“深层链接”与上述屏幕Home,Profile和的模式集成在一起Notifications,并且按预期工作。我面临的问题是使用深层链接时如何管理用户的身份验证。现在,无论何时打开深层链接(myapp://profile例如),无论我是否通过身份验证,该应用程序都会将我带到屏幕上。我想要它做的是先检查AsyncStorage是否有一个userToken,如果没有,或者它不再有效,然后在Auth屏幕上重定向。
我以与此处所述几乎完全相同的方式设置了身份验证流程。因此,当我的应用程序启动时,Splash屏幕会检查用户电话中是否存在有效令牌,然后将其发送到Auth屏幕或Home屏幕上。
我目前想出的唯一解决方案是将每个深层链接指向,对Splash用户进行身份验证,然后解析该链接以导航至正确的屏幕。例如,当用户打开时myapp://profile,我打开应用程序Splash,验证令牌,然后解析url(/profile),最后重定向到Auth或Profile。
这是这样做的好方法,还是反应导航提供了更好的方法?他们网站上的“ 深层链接”页面有点亮。
谢谢您的帮助 !
我的设置与您的设置相似。我遵循了身份验证流程·反应导航 和SplashScreen-博览会文档来设置我的Auth流,因此令我有些失望的是,使深层链接也流经它也是一个挑战。我可以通过自定义主开关导航器来使此工作正常进行,该方法类似于您所说的当前解决方案。我只是想分享我的解决方案,所以有一个具体的例子说明如何开始工作。我已经像这样设置了主开关导航器(也正在使用TypeScript,所以如果它们不熟悉,请忽略类型定义):
const MainNavigation = createSwitchNavigator(
{
SplashLoading,
Onboarding: OnboardingStackNavigator,
App: AppNavigator,
},
{
initialRouteName: 'SplashLoading',
}
);
const previousGetActionForPathAndParams =
MainNavigation.router.getActionForPathAndParams;
Object.assign(MainNavigation.router, {
getActionForPathAndParams(path: string, params: any) {
const isAuthLink = path.startsWith('auth-link');
if (isAuthLink) {
return NavigationActions.navigate({
routeName: 'SplashLoading',
params: { ...params, path },
});
}
return previousGetActionForPathAndParams(path, params);
},
});
export const AppNavigation = createAppContainer(MainNavigation);
Run Code Online (Sandbox Code Playgroud)
您想通过身份验证流进行路由的任何深层链接都必须以开头auth-link,或者您选择以其开头的任何内容。这里是什么SplashLoading样子:
export const SplashLoading = (props: NavigationScreenProps) => {
const [isSplashReady, setIsSplashReady] = useState(false);
const _cacheFonts: CacheFontsFn = fonts =>
fonts.map(font => Font.loadAsync(font as any));
const _cacheSplashAssets = () => {
const splashIcon = require(splashIconPath);
return Asset.fromModule(splashIcon).downloadAsync();
};
const _cacheAppAssets = async () => {
SplashScreen.hide();
const fontAssetPromises = _cacheFonts(fontMap);
return Promise.all([...fontAssetPromises]);
};
const _initializeApp = async () => {
// Cache assets
await _cacheAppAssets();
// Check if user is logged in
const sessionId = await SecureStore.getItemAsync(CCSID_KEY);
// Get deep linking params
const params = props.navigation.state.params;
let action: any;
if (params && params.routeName) {
const { routeName, ...routeParams } = params;
action = NavigationActions.navigate({ routeName, params: routeParams });
}
// If not logged in, navigate to Auth flow
if (!sessionId) {
return props.navigation.dispatch(
NavigationActions.navigate({
routeName: 'Onboarding',
action,
})
);
}
// Otherwise, navigate to App flow
return props.navigation.navigate(
NavigationActions.navigate({
routeName: 'App',
action,
})
);
};
if (!isSplashReady) {
return (
<AppLoading
startAsync={_cacheSplashAssets}
onFinish={() => setIsSplashReady(true)}
onError={console.warn}
autoHideSplash={false}
/>
);
}
return (
<View style={{ flex: 1 }}>
<Image source={require(splashIconPath)} onLoad={_initializeApp} />
</View>
);
};
Run Code Online (Sandbox Code Playgroud)
我使用routeName查询参数创建了深层链接,查询参数是执行身份验证检查后导航到的屏幕的名称(显然,您可以添加所需的任何其他查询参数)。由于我的SplashLoading屏幕可以处理所有字体/资产的加载以及身份验证的检查,因此我需要每个深层链接来进行路由。我遇到的问题是,我将手动从多任务处理中退出应用程序,点击深层链接网址,并且由于绕过深层链接SplashLoading而无法加载字体而导致应用程序崩溃。
上面的方法声明了一个action变量,如果未设置该变量将无效。如果routeName查询参数不是undefined,则设置action变量。这样一来,一旦Switch路由器基于auth(Onboarding或App)决定采用哪个路径,该路由就会获得子操作,并routeName在退出auth / splash加载流程后导航至。
这是我创建的示例链接,可以在此系统上正常运行:
exp://192.168.1.7:19000/--/auth-link?routeName=ForgotPasswordChange&cacheKey=a9b3ra50-5fc2-4er7-b4e7-0d6c0925c536
希望图书馆作者将来将此功能作为本机支持的功能,这样就不必进行黑客攻击了。我也很想知道您的想法!
| 归档时间: |
|
| 查看次数: |
2692 次 |
| 最近记录: |