从 main() 方法手动启动 SwiftUI 应用程序

问题描述 投票:0回答:1

我已经配置了我的应用程序,以便可以通过在运行时检查环境变量来在 GUI 模式或 CLI 模式下运行它。

我已经让它工作了,至少在表面上是这样,但是 GUI 版本 (SwiftUI) 似乎并没有与父进程绑定,因此父进程立即终止,并使 SwiftUI 窗口成为孤立的。实际上,这意味着应用程序的某些部分(尤其是异步内容)无法正常工作。

关于我做错了什么有什么想法吗?网络上从

main()
显式调用 SwiftUI 应用程序的示例并不多,所以我主要是跟着我的鼻子写的。

这是代码:

@main
struct CourierApp {
    
    static func main() async throws {
        guard let launchMode = ProcessInfo.processInfo.environment["LAUNCH_MODE"], launchMode == "GUI" else {
            try await launchCLI()
            return
        }
        try await launchGUI()
    }
    
    private static func launchCLI() async throws {
        guard var courierCLI = try? CourierCLI.parse(ProcessInfo.processInfo.arguments) else {
            throw ValidationError("Invalid arguments. You should invoke Courier providing first your archive and then the output directory for the program. Optionally, some flags can be provided - see the manual for details.")
        }
        try await courierCLI.run()
    }
    
    private static func launchGUI() async throws {
        await CourierGUI.main()
    }
}

struct CourierCLI: AsyncParsableCommand {
    
    @Argument var archivePath: String
    @Argument var outputPath: String
    @Flag var uploadToAppStoreConnect = false
    @Option(name: [.customShort("e"), .customLong("entitlements")]) var overrideEntitlements: String? = nil
    
    mutating func run() async throws {
        
    }
    
    func validate() throws {
        if let overrideEntitlements {
            let arrayEntitlements = overrideEntitlements.split(separator: ",")
            guard arrayEntitlements.count <= 2 else {
                throw ValidationError("When passing entitlements to override, you must provide a comma-delimited list of entitlements, taking care to only include entitlements to grant - any omitted will not be granted to the app. Example: 'tracking,bluetooth'.")
            }
        }
    }
}

struct CourierGUI: App {
    
    var body: some Scene {
        WindowGroup {
            MasterView()
                .navigationTitle("Courier")
        }
        .defaultPosition(.center)
    }
}

swift macos swiftui command-line-interface
1个回答
0
投票

可以使用 main.swift 手动调用 CourierApp.main()。 从

@main
中删除
struct CourierApp
注释并创建 main.swift:

if shouldLaunchGUI {
    CourierApp.main()
    return
} else {
    guard var courierCLI = try? CourierCLI.parse(ProcessInfo.processInfo.arguments) else {
        return
    }
    courierCLI.run()
}
© www.soinside.com 2019 - 2024. All rights reserved.