// Rails part
This is my _header.html..erb
<div class="flex justify-between items-center p-5"
data-controller="header bridge--header"
data-header-menu-outlet=".menu-class">
<h1>Lego</h1>
<div class="flex flex-col gap-1 cursor-pointer lg:hidden"
data-header-target="hamburgerMenu"
data-bridge--header-target="hamMenu"
data-bridge-title="Menu"
data-action="click->header#handleHamburgerMenu">
<div class="h-[2px] w-[30px] bg-black"></div>
<div class="h-[2px] w-[30px] bg-black"></div>
<div class="h-[2px] w-[30px] bg-black"></div>
</div>
</div>
This is my _menu.html.erb
<div class="p-5 mx-5 bg-gray-200 hidden menu-class"
data-controller="menu" data-menu-target="menuContainer">
<div class="flex flex-col gap-2 items-center justify-center">
<%= link_to "Blogs", blog_posts_path %>
<%= link_to "About" %>
<%= link_to "Contact" %>
</div>
</div>
this is my header bridge component
import { BridgeComponent, BridgeElement } from "@hotwired/strada";
export default class extends BridgeComponent {
static component = "header";
static targets = ["hamMenu"];
connect() {
console.log("connected header bridge");
}
hamburgerMenuTargetConnected(target) {
const menu = new BridgeElement(target);
const menuTitle = menu.title;
this.send("connect", { menuTitle }, () => {
console.log("target clicked", target);
target.click();
});
}
}
// iOS part
This is my HeaderComponent.swift
import Foundation
import Strada
import UIKit
final class HeaderComponent: BridgeComponent {
override class var name: String { "header" }
override func onReceive(message: Message) {
print("executed")
switch message.event {
case "connect":
handleConnectEvent(message: message)
default:
break
}
}
private func handleConnectEvent(message: Message) {
guard let data: MessageData = message.data() else { return }
configureBarButton(with: data.menuTitle)
}
private func configureBarButton(with title: String) {
guard let viewController = delegate.destination as? UIViewController else { return }
let item = UIBarButtonItem(title: title, style: .plain, target: self, action: #selector(performAction))
viewController.navigationItem.leftBarButtonItem = item
print("item", item)
}
// Reply to the originally received "connect" event message (without any new data).
@objc func performAction() {
reply(to: "connect")
}
}
private extension HeaderComponent {
struct MessageData: Decodable {
let menuTitle: String
}
}
This is my TurboWebViewController.swift
import UIKit
import Turbo
import Strada
import WebKit
final class TurboWebViewController: VisitableViewController, BridgeDestination {
private lazy var bridgeDelegate: BridgeDelegate = {
BridgeDelegate(location: visitableURL.absoluteString,
destination: self,
componentTypes: BridgeComponent.allTypes)
}()
// MARK: View lifecycle
override func viewDidLoad() {
super.viewDidLoad()
bridgeDelegate.onViewDidLoad()
print("viewDidLoad")
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
bridgeDelegate.onViewWillAppear()
print("viewWillAppear")
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
bridgeDelegate.onViewDidAppear()
print("viewDidAppear")
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
bridgeDelegate.onViewWillDisappear()
print("viewWillDisappear")
}
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
bridgeDelegate.onViewDidDisappear()
print("viewDidDisappear")
}
// MARK: Visitable
override func visitableDidActivateWebView(_ webView: WKWebView) {
bridgeDelegate.webViewDidBecomeActive(webView)
print("vistabaleDidActivateWebView")
}
override func visitableDidDeactivateWebView() {
bridgeDelegate.webViewDidBecomeDeactivated()
print("vistabaleDidDeaxctvate")
}
}
This is my SceneDelegate.swift
import UIKit
import Turbo
import WebKit
import Strada
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
private lazy var navigationController = UINavigationController()
private lazy var session: Session = {
let config = WKWebViewConfiguration()
let stradaSubstring = Strada.userAgentSubstring(for: BridgeComponent.allTypes)
let userAgent = "Turbo Native iOS \(stradaSubstring)"
config.applicationNameForUserAgent = userAgent
let webView = WKWebView(frame: .zero, configuration: config)
// Initialize Strada bridge.
Bridge.initialize(webView)
let session = Session(webViewConfiguration: config)
session.delegate = self
return session
}()
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?.makeKeyAndVisible()
visit()
}
private func visit() {
let url = URL(string: "http://localhost:3001")!
let controller = VisitableViewController(url: url)
session.visit(controller, action: .advance)
navigationController.pushViewController(controller, animated: true)
}
}
extension SceneDelegate: SessionDelegate {
func session(_ session: Session, didProposeVisit proposal: VisitProposal) {
let controller = TurboWebViewController(url: proposal.url)
print("controller", controller)
session.visit(controller, options: proposal.options)
navigationController.pushViewController(controller, animated: true)
}
func session(_ session: Session, didFailRequestForVisitable visitable: Visitable, error: Error) {
//TODO: Handle Errors
}
func sessionWebViewProcessDidTerminate(_ session: Session) {
//TODO: Handle dead web view
}
}
So basically my expectation is to see a native menu with the links , i am not sure if i am doing it correct because i have no prior experience with swift before.
It would be great , if anyone helps me out here