Bridge Components
Vamos avançar na transformação da aplicação para torná-la mais nativa. Uma abordagem eficaz é utilizar Bridge Components (antigamente conhecidos como Strada Components), que criam uma integração entre a aplicação web e iOS, adicionando elementos nativos.
Primeiro Bridge Component
No capítulo anterior, identificamos o botão New URL na tela de URLs. Vamos substituí-lo por um botão nativo, removendo-o da interface web para uma aparência mais integrada e nativa.
Passo a passo para criar o botão New URL na sua versão nativa usando um Bridge Component:
- Crie um Bridge Component no projeto iOS que receba as instruções do Rails.
- Crie um Stimulus Controller que, ao disparar o evento connect, envie as informações necessárias para renderizar o elemento nativo.
- Configure o markup na página onde o componente será exibido.
iOS Bridge Button Component
No projeto iOS, clique com o botão direito na árvore de arquivos e selecione New Empty File
ou use o atalho Command + N
. Crie um arquivo Swift chamado ButtonComponent
. O código a seguir contém comentários para facilitar o entendimento de quem não tem experiência prévia com Swift.
Implementação do componente Swift
import HotwireNative
import UIKit
final class ButtonComponent: BridgeComponent {
// Nomeia o componente para permitir a conexão
// com o Stimulus Controller por meio desta string.
override class var name: String { "button" }
// No evento `connect` do Stimulus, o componente recebe
// informações necessárias, como o título do botão.
override func onReceive(message: Message) {
// Use print(message) para verificar os dados recebidos do Rails.
// O conteúdo será exibido nos logs do Xcode.
guard let viewController else { return }
addButton(via: message, to: viewController)
}
private var viewController: UIViewController? {
delegate.destination as? UIViewController
}
// Função responsável por montar e renderizar o botão nativo
// na tela do app iOS e adicioná-lo à Navbar no lado direito
// em resposta ao evento `connect` do Stimulus Controller.
private func addButton(via message: Message, to viewController: UIViewController) {
guard let data: MessageData = message.data() else { return }
let action = UIAction { [unowned self] _ in
self.reply(to: "connect")
}
let item = UIBarButtonItem(title: data.title, primaryAction: action)
viewController.navigationItem.rightBarButtonItem = item
}
}
// Decodifica a mensagem do Stimulus Controller
// para a struct `MessageData`. Classes, structs e extensions
// foram discutidos na seção sobre Swift.
private extension ButtonComponent {
struct MessageData: Decodable {
let title: String
}
}
Registre o componente no Hotwire Native
para torná-lo disponível no projeto e acessível conforme necessário. No arquivo AppDelegate
, insira o seguinte código abaixo da configuração do PathConfiguration
:
Hotwire.registerBridgeComponents([
ButtonComponent.self
])
Conectando o Rails ao componente nativo
Certifique-se de que os pacotes necessários estejam instalados no projeto Rails:
./bin/importmap pin @hotwired/stimulus @hotwired/hotwire-native-bridge
Para concluir a integração e habilitar o Rails a chamar o componente nativo, crie um novo Stimulus Controller no caminho e nome indicados:
app/javascript/controllers/button_controller.js
Implementação do controller Stimulus no Rails
import { BridgeComponent } from "@hotwired/hotwire-native-bridge"
export default class extends BridgeComponent {
// Lembra da string no Component Swift?
static component = "button"
// O método `connect` é executado quando o elemento está pronto,
// informando à bridge o componente chamado e definindo a ação
// do botão nativo via callback.
connect() {
super.connect()
const element = this.bridgeElement
const title = element.bridgeAttribute("title")
this.send("connect", {title}, () => {
this.element.click()
})
}
}
Conectando o botão New URL ao controller Stimulus
Para concluir, é necessário disparar o método connect
do Stimulus Controller. Isso é feito através de um elemento HTML. Atualize o botão New URL no arquivo:
app/views/urls/index.html.erb
No helper link_to
, adicione os atributos data necessários para que o Stimulus Controller seja acionado, incluindo o nome do controller e o título do botão:
<%= link_to "Back to urls", urls_path, class: "ml-2 rounded-lg py-3 px-5 bg-gray-100 inline-block font-medium",
data: { controller: "button", bridge_title: "New Url" } %>
Após a atualização, execute novamente o aplicativo iOS (Command + R
). Navegue até URLs e observe que o botão nativo aparece conforme implementado. Quando clicado, ele executa a mesma ação que o botão web. Isso ocorre porque o Stimulus Controller, por meio do callback no método connect
e na chamada this.send
, instrui que o evento acionado ao clicar no botão nativo seja equivalente ao clique no botão web (this.element.click()
).
Recapitulando
Para compreender os Bridge Components, é essencial considerar três elementos principais:
- Swift Component: Código nativo responsável por implementar a funcionalidade no iOS (ou Android).
- Stimulus Controller: Código JavaScript que conecta-se a um elemento HTML, envia mensagens à bridge nativa para executar ou exibir funcionalidades, transmite os dados necessários para montar o elemento nativo e define o callback.
- Markup HTML (ERB): Estrutura HTML que chama o Stimulus Controller, passando os atributos
data-bridge
necessários para o funcionamento do componente nativo.
Esses passos representam, de forma simplificada, o fluxo de integração utilizando a bridge nativa.