Actualmente estoy desarrollando una aplicación SwiftUI que quiero que sea multiplataforma en la mayoría de los dispositivos Apple (iPhone, reloj, iPad, macOS). La aplicación compartirá muchas vistas y lógica entre iOS, iPadOS, watchOS y macOS.
Lo que quiero hacer es hacer que la aplicación en macOS sea una aplicación de barra de menú. Para hacer que la experiencia sea la mejor para el usuario, además de registrar un elemento de la barra de menú, quería usar una instancia personalizada de NSWindow que se adjuntará a un elemento de la barra de menú de manera similar a un NSPopover pero que podrá separarse cuando se arrastre fuera y aún así mantener todo la apariencia de una NSWindow normal, como controles de semáforo, etc. Tendrá una funcionalidad similar a las aplicaciones de barra de menú Cardhop, Fantastical y Harvest.
Lo que encuentro difícil de hacer es usar una instancia personalizada de NSWindow en combinación con SwiftUI. Estoy usando las últimas versiones de SwiftUI y Xcode y probablemente no pueda cambiar a una versión anterior, ya que estoy en la nueva MacBook.
Mi versión de Xcode es 13.2.1 y macOS 12.1
Lo que traté de hacer para tener un control completo sobre lo que sucede con la ventana fue renunciar a la etiqueta @main en la estructura de la aplicación SwiftUI y moverla a la instancia de NSApplicationDelegate que codifiqué. Eliminé la estructura de la aplicación SwiftUI del objetivo de macOS e intenté agregar @main y @NSApplicationMain a mi implementación de AppDelegate , pero resultó que AppDelegate no se ejecutó en absoluto. La aplicación se lanzó pero no sucedió nada y no se imprimió nada en la consola.
Leí en internet que en la versión anterior se podía usar el ciclo de vida heredado de UIKit, que en mi caso podría estar ayudándome a resolver mi caso. Como no pude hacerlo, intenté salir de esta situación.
Mi solución actual es seguir teniendo la instancia de estructura de la aplicación SwiftUI como @main y agregar @NSApplicationDelegateAdaptor con mi implementación AppDelegate donde simplemente encuentro la ventana que se inició y ejecuto close() en ella. Esta es una solución muy complicada que no me gusta, pero puedo aceptarla si es la única solución que funcionará en este momento.
Mi pregunta es doble:
¿Es posible renunciar por completo al uso de la estructura de la App y optar por el antiguo AppDelegate en la última versión de SwiftUI? Si no es así, ¿cómo puedo hacer que WindowGroup use una clase NSWindow extendida personalizada que agregará mi funcionalidad de adjuntar, separar, flecha que apunta al elemento de la barra de menú, etc.
¡Gracias por la ayuda de antemano!
En realidad, aún es posible renunciar al ciclo de vida de SwiftUI, pero es más difícil. Como no soy un desarrollador de Apple experimentado, no sabía cómo hacerlo.
https://sarunw.com/posts/how-to-create-macos-app-without-storyboard/
Encontré esto útil, pasando del tutorial Storyboards. En lugar de pasar de Storyboards, uno tiene que eliminar la aplicación SwiftUI del objetivo de macOS, omitir las cosas con la eliminación de storyboards y simplemente hacer el resto. La aplicación funcionó bien para mí. Aparentemente, la clave era el archivo main.swift.