该帖子是提取并根据The Rails and Hotwire Codex提取的。它还假定对涡轮天然的熟悉。
在为Web开发时,我们可以在Web请求期间使用HTTP重定向(3xx
状态代码)将用户发送到任何位置。 Turbo Native有效地将网站包装在本机导航中。这意味着重定向可能并不总是能解决问题。
让我们举个例子。 A 登录屏幕在本机应用中呈现。成功登录后,我们希望将用户重定向到主页。在该应用程序中,我们要忽略模式以揭示其下面的屏幕,以使用户可以继续进行任何操作。传统的重定向无法正常工作,我们需要告诉应用程序只是驳回模式。
服务器驱动的本地导航
turbo-rails
Gem绘制了三个路由,这些路由指示本机应用程序做某事。这些路线不会返回任何有意义的内容;该应用程序旨在拦截访问提案对这些路线并实施逻辑以执行指令。路线及其指示的是:
路线 | 指令 |
---|---|
/recede_historical_location |
该应用应该返回 |
/resume_historical_location |
该应用程序不应在导航方面无能为力 |
/refresh_historical_location |
该应用程序应刷新当前页面 |
查看源代码以查看routes和actions they point to。
这些路由专门用于本机应用程序,并且在Web上没有任何意义。为了帮助您,turbo-rails
具有在使用该应用程序的情况下有条件地重定向的方法。例如,而不是以下重定向:
redirect_to root_path, status: :see_other
我们将使用:
recede_or_redirect_to root_path, status: :see_other
这将重定向到网络上的/
,并在本机应用程序中重定向到/recede_historical_location
。查看所有可用的重定向方法in the source code。
使用这些方法,可以指示该应用程序在登录后登录后仍可以解散登录模式,同时仍将其重定向到Web上的根路径。
接下来,重定向到上述路径需要在应用程序中拦截和处理。我们将调用以下路径:路径指令,因为它们将应用程序执行操作。
拦截和处理路径指令
让我们看一下iOS。从应用程序中为每个Web请求触发以下委托方法。
extension RoutingController: SessionDelegate {
func session(_ session: Session, didProposeVisit proposal: VisitProposal) {
// ...
}
}
在这里,我们可以检查访问是否为 path Directive 并采取相应的行动。
extension RoutingController: SessionDelegate {
func session(_ session: Session, didProposeVisit proposal: VisitProposal) {
if proposal.isPathDirective {
executePathDirective(proposal)
} else {
visit(proposal)
}
}
func executePathDirective(_ proposal: VisitProposal) {
guard proposal.isPathDirective else { return }
switch proposal.url.path {
case "/recede_historical_location":
dismissOrPopViewController()
case "/refresh_historical_location":
refreshWebView()
default:
()
}
}
private func dismissOrPopViewController() {
// ...
}
private func refreshWebView() {
// ...
}
}
extension VisitProposal {
var isPathDirective: Bool {
return url.path.contains("_historical_location")
}
}
这将在iOS上解决问题。
构建涡轮天然导航系统是非平凡的,因此我不得不省略大量周围的代码以使此帖子保持重点。如果您有兴趣深入研究,My book会填补所有空白。
接下来,让我们看一下Android。自定义导航是通过创建从TurboNavDestination
继承的interface
来处理的。在此界面中,每个Web请求都调用shouldNavigateTo(newLocation: String)
方法。我们可以在此处处理路径指令。
interface NavDestination: TurboNavDestination {
override fun shouldNavigateTo(newLocation: String): Boolean {
return when {
isPathDirective(newLocation) -> {
executePathDirective(newLocation)
false
}
else -> true
}
}
private fun executePathDirective(url: String) {
val url = URL(url)
when (url.path) {
"/recede_historical_location" -> navigateUp()
"/refresh_historical_location" -> refresh()
}
}
private fun isPathDirective(url: String): Boolean {
return url.contains("_historical_location")
}
// ...
}
结论
这就是Turbo Native驱动的应用程序可以从服务器中成为控制器的方式!这为我们提供了巨大的灵活性和可扩展性,而无需部署应用程序更新。
如果您喜欢这篇文章,请查看我的书The Rails and Hotwire Codex,以提高您的铁轨和热线技巧!它将教您如何构建涡轮原生导航系统并填补此博客文章中的空白。