DEV Community

Jeffrey Hicks
Jeffrey Hicks

Posted on

Turbo Native in 15 Minutes

Overview

This are my notes while watching Joe Masilotti's youtube video on "Turbo Native in 15 minutes"

Resources

  • Turbo Native in 15 minutes - Joe Masilotti - Learn how to get up and running with Turbo Native on iOS in 15 minutes. All you need to get started is a free copy of Xcode downloaded from the App Store.

Create Barebones Xcode Project

  • Open Xcode

  • File - New Project

    • Select Interface "Story Board"

Image description

  • Should launch to blank app.

Remove Boiler Plate

  • From File Navigator, Delete main.storyboard

Image description

  • From Info PList, Expand keys, Delete Storyboard Name

Image description

  • Remove Storyboard Reference From Build Settings

    • From Navigator Pane, Open Project
    • Click Target
    • Build Settings Tab
    • Delete UIKit Main Storybaord

Image description

Setup Scene

  • Open SceneDelegte from Navigation Pane

  • Delete everything except func scene

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
    guard let windowScene = (scene as? UIWindowScene) else { return }
    self.window = UIWindow(windowScene: windowScene)
    self.window?.rootViewController = UIViewController()
    self.window?.rootViewController?.view.backgroundColor = .orange
    self.window?.makeKeyAndVisible()
}
Enter fullscreen mode Exit fullscreen mode

Build TurboNative App

Get TurboNative Dependency

Alternatively to CocoaPods or Carpet? this is built into Xcode. Similar to Gems.

  • Open File Explorer

  • Click on Project in File Explorer

    • Click Project (Not Target)
    • Package Dependencies
    • Click +

Image description

Use TurboNative Package in Scene

Update SceneDelegate to use NavigationController and Introduce concept of pushViewController

private let navigationController = UINavigationController()

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
    guard let windowScene = (scene as? UIWindowScene) else { return }
    self.window = UIWindow(windowScene: windowScene)
    self.window?.rootViewController = navigationController
    self.window?.rootViewController?.view.backgroundColor = .orange
    self.window?.makeKeyAndVisible()

    visit()
}

private func visit() {
    let controller = UIViewController()
    controller.view.backgroundColor = .green
    navigationController.pushViewController(controller, animated: true)
}
Enter fullscreen mode Exit fullscreen mode

Now instead of UIViewController, let's use Turbo's VisitableViewController

private func visit() {
    let url = URL(string: "http://localhost:3000")!
    let controller = VisitableViewController(url: url)
    navigationController.pushViewController(controller, animated: true)
}
Enter fullscreen mode Exit fullscreen mode

But we also need Turbo's Session. Next to the navigationController at top of file add:

private let session = Session()
Enter fullscreen mode Exit fullscreen mode

And update func visit

private func visit() {
    let url = URL(string: "http://localhost:3000")!
    let controller = VisibleViewController(url: url)
    session.visit(controller, .advance)
  navigationController.pushViewController(controller, animated: true)
}
Enter fullscreen mode Exit fullscreen mode

Activate Links

Update session

private lazy var session: Session = {
    let session = Session()
    session.delegate = self
    return session
}()
Enter fullscreen mode Exit fullscreen mode

But that will warn, because self doesn't quack like a delegate.

Image description

So we an use extensions to extend SceneDelegate. For some reason, you gotta click fix twice.

Image description

    func session(_ session: Turbo.Session, didProposeVisit proposal: Turbo.VisitProposal) {
        let controller = VisitableViewController(url: proposal.url)
        session.visit(controller, action: .advance)
        navigationController.pushViewController(controller, animated: true)
    }
Enter fullscreen mode Exit fullscreen mode

Remove WebView Elements Not Relevant to TurboNative

The strategy here is to let Rails know we are TurboNative app by setting the UserAgent Name.

private lazy var session: Session = {
    let configuration = WKWebViewConfiguration()
    configuration.applicationNameForUserAgent = "Turbo Native iOS"
    let session = Session()
    session.delegate = self
    return session
}()
Enter fullscreen mode Exit fullscreen mode

In Rails app you can conditionally render content based on turbo_native_app?

Top comments (0)