从服务器引导涡轮机器应用程序
#android #ios #rails #turbo

该帖子是提取并根据The Rails and Hotwire Codex提取的。它还假定对涡轮天然的熟悉。

在为Web开发时,我们可以在Web请求期间使用HTTP重定向(3xx状态代码)将用户发送到任何位置。 Turbo Native有效地将网站包装在本机导航中。这意味着重定向可能并不总是能解决问题。

让我们举个例子。 A 登录屏幕在本机应用中呈现。成功登录后,我们希望将用户重定向到主页。在该应用程序中,我们要忽略模式以揭示其下面的屏幕,以使用户可以继续进行任何操作。传统的重定向无法正常工作,我们需要告诉应用程序只是驳回模式。

服务器驱动的本地导航

turbo-rails Gem绘制了三个路由,这些路由指示本机应用程序做某事。这些路线不会返回任何有意义的内容;该应用程序旨在拦截访问提案对这些路线并实施逻辑以执行指令。路线及其指示的是:

路线 指令
/recede_historical_location 该应用应该返回
/resume_historical_location 该应用程序不应在导航方面无能为力
/refresh_historical_location 该应用程序应刷新当前页面

查看源代码以查看routesactions 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,以提高您的铁轨和热线技巧!它将教您如何构建涡轮原生导航系统并填补此博客文章中的空白。