utilizar @main en Xcode 12

Resuelto Alireza12t asked hace 4 años • 6 respuestas

Quiero ejecutar este código en iOS 13 y superior, ¿cómo debo solucionar este error? Quiero que este código también pueda ejecutarse en iOS 13.

@available(iOS 14.0, *)
@main

struct WeatherProApp: App {
  @Environment(\.scenePhase) private var scenePhase
  @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate

  
  var body: some Scene {
    WindowGroup{
      let fetcher = WeatherFetcher()
      let viewModel = WeeklyWeatherViewModel(weatherFethcer: fetcher)
      WeeklyWeatherView(viewModel: viewModel)
    }
    .onChange(of: scenePhase) { (newScenePhase) in
      switch newScenePhase {
      case .active:
        print("scene is now active!")
      case .inactive:
        print("scene is now inactive!")
      case .background:
        print("scene is now in the background!")
      @unknown default:
        print("Apple must have added something new!")
      }
    }
  }
}

pero me muestra este error

Imagen de error

Alireza12t avatar Jul 16 '20 19:07 Alireza12t
Aceptado

Siguiendo la respuesta de @the.blaggy , así es como logré ejecutar mi proyecto en iOS 13:

  1. Crea un SceneDelegate si no tienes uno

EscenaDelegate.swift

class SceneDelegate: UIResponder, UIWindowSceneDelegate {

    var window: UIWindow?

    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
        let contentView = ContentView()

        // Use a UIHostingController as window root view controller.
        if let windowScene = scene as? UIWindowScene {
            let window = UIWindow(windowScene: windowScene)
            window.rootViewController = UIHostingController(rootView: contentView)
            self.window = window
            window.makeKeyAndVisible()
        }
    }
}
  1. Abra su info.plist como código fuente y agregue esas líneas:

Lista de información

   <key>UIApplicationSceneManifest</key>
       <dict>
           <key>UIApplicationSupportsMultipleScenes</key>
           <false/>
           <key>UISceneConfigurations</key>
           <dict>
           <key>UIWindowSceneSessionRoleApplication</key>
           <array>
               <dict>
                   <key>UISceneConfigurationName</key>
                   <string>Default Configuration</string>
                   <key>UISceneDelegateClassName</key>
                   <string>$(PRODUCT_MODULE_NAME).SceneDelegate</string>
               </dict>
           </array>
       </dict>
   </dict>
  1. Agregue esto en su WeatherProApp.swift

WeatherProApp.swift

    @main
    struct WeatherProAppWrapper {
        static func main() {
            if #available(iOS 14.0, *) {
                WeatherProApp.main()
            }
            else {
                UIApplicationMain(CommandLine.argc, CommandLine.unsafeArgv, nil, NSStringFromClass(SceneDelegate.self))
            }
        }
    }
Ugo Marinelli avatar Dec 21 '2020 10:12 Ugo Marinelli

Esto podría depender de otro código de proyecto, pero lo siguiente probado funciona (Xcode 12b), por lo que podría resultar útil.

La idea es ocultar un contenedor dentro de otra estructura con un verificador de disponibilidad:

@available(iOS 14.0, macOS 10.16, *)
struct Testing_SwiftUI2AppHolder {
    @main
    struct Testing_SwiftUI2App: App {

        var body: some Scene {
            WindowGroup {
                ContentView()
            }
        }
    }
}
Asperi avatar Jul 16 '2020 13:07 Asperi

Si realmente lo necesita, simplemente cambie @main a @UIApplicationMain, debería funcionar.

Vladimir Sukanica avatar Jan 31 '2021 09:01 Vladimir Sukanica