import Tauri
import UIKit
import WebKit
class KeyboardPlugin: Plugin {
private var keyboardObserver: KeyboardObserver?
override public func load(webview: WKWebView) {
super.load(webview: webview)
print("🎹 [KeyboardPlugin] Loading iOS keyboard plugin...")
// Initialize keyboard observer
keyboardObserver = KeyboardObserver { [weak self] event in
print("🎹 [KeyboardPlugin] Keyboard event detected: \(event.eventType) height: \(event.keyboardHeight)")
self?.sendKeyboardEvent(event)
}
keyboardObserver?.startObserving()
print("🎹 [KeyboardPlugin] Keyboard observer started")
}
deinit {
keyboardObserver?.stopObserving()
}
private func sendKeyboardEvent(_ event: KeyboardEvent) {
// Use Tauri's trigger method to emit events
let data: JSObject = [
"eventType": event.eventType,
"keyboardHeight": event.keyboardHeight,
"animationDuration": event.animationDuration
]
print("🎹 [KeyboardPlugin] Triggering event: plugin:keyboard::ios-keyboard-event with data: \(data)")
self.trigger("plugin:keyboard::ios-keyboard-event", data: data)
print("🎹 [KeyboardPlugin] Event triggered successfully")
}
}
// Keyboard event structure
struct KeyboardEvent {
let eventType: String
let keyboardHeight: Double
let animationDuration: Double
}
// Keyboard observer class
class KeyboardObserver {
private var onKeyboardEvent: ((KeyboardEvent) -> Void)?
init(onEvent: @escaping (KeyboardEvent) -> Void) {
self.onKeyboardEvent = onEvent
}
func startObserving() {
// Keyboard will show
NotificationCenter.default.addObserver(
self,
selector: #selector(keyboardWillShow),
name: UIResponder.keyboardWillShowNotification,
object: nil
)
// Keyboard did show
NotificationCenter.default.addObserver(
self,
selector: #selector(keyboardDidShow),
name: UIResponder.keyboardDidShowNotification,
object: nil
)
// Keyboard will hide
NotificationCenter.default.addObserver(
self,
selector: #selector(keyboardWillHide),
name: UIResponder.keyboardWillHideNotification,
object: nil
)
// Keyboard did hide
NotificationCenter.default.addObserver(
self,
selector: #selector(keyboardDidHide),
name: UIResponder.keyboardDidHideNotification,
object: nil
)
}
func stopObserving() {
NotificationCenter.default.removeObserver(self)
}
@objc private func keyboardWillShow(notification: NSNotification) {
guard let userInfo = notification.userInfo,
let keyboardFrame = userInfo[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect,
let animationDuration = userInfo[UIResponder.keyboardAnimationDurationUserInfoKey] as? Double else {
return
}
let event = KeyboardEvent(
eventType: "will-show",
keyboardHeight: keyboardFrame.height,
animationDuration: animationDuration
)
onKeyboardEvent?(event)
}
@objc private func keyboardDidShow(notification: NSNotification) {
guard let userInfo = notification.userInfo,
let keyboardFrame = userInfo[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect,
let animationDuration = userInfo[UIResponder.keyboardAnimationDurationUserInfoKey] as? Double else {
return
}
let event = KeyboardEvent(
eventType: "did-show",
keyboardHeight: keyboardFrame.height,
animationDuration: animationDuration
)
onKeyboardEvent?(event)
}
@objc private func keyboardWillHide(notification: NSNotification) {
guard let userInfo = notification.userInfo,
let animationDuration = userInfo[UIResponder.keyboardAnimationDurationUserInfoKey] as? Double else {
return
}
let event = KeyboardEvent(
eventType: "will-hide",
keyboardHeight: 0,
animationDuration: animationDuration
)
onKeyboardEvent?(event)
}
@objc private func keyboardDidHide(notification: NSNotification) {
guard let userInfo = notification.userInfo,
let animationDuration = userInfo[UIResponder.keyboardAnimationDurationUserInfoKey] as? Double else {
return
}
let event = KeyboardEvent(
eventType: "did-hide",
keyboardHeight: 0,
animationDuration: animationDuration
)
onKeyboardEvent?(event)
}
}
// Export the plugin initialization function
@_cdecl("init_plugin_keyboard")
func initPlugin() -> Plugin {
return KeyboardPlugin()
}