Closed hassila closed 1 year ago
All the code is simply:
import SwiftTUI
struct MyTerminalView: View {
var body: some View {
Text("Hello, world!")
}
}
@main
struct MyApp {
static func main() {
Application(rootView: MyTerminalView()).start()
}
}
Hi @hassila , thank you for sharing. You cannot run SwiftTUI apps in the Xcode console. Can you try to run the app in your Terminal application? You can do that by opening the package directory in a Terminal application and running
swift run
Oh, same thing from terminal for the larger project which I tried it with - I just brought it up in Xcode for getting the debugger screenshot. You can't reproduce with the attached reproducer?
(And kudos for a super cool project!)
Are you sure it's the same failure when you run from the Terminal? Running the project in the Xcode console like this will always fail with this error. The issue is that the console lacks many terminal features, such as reporting the window size. The renderer than fails drawing in a window of size 0x0.
I’ll give it another spin when in the office tomorrow - but fairly sure - I could get some sample code to give some proper output, but I’d inevitably crash (even with just a Text()). Will revert, thanks.
Thanks, that would be great! You can debug without Xcode. (I personally haven't been able to get Xcode to connect to an app running inside the terminal.) Run this inside your package folder:
lldb .build/debug/repro-swifttui
Then use this to launch the terminal app in a new window:
(lldb) process launch --tty
When the app crashes, you can print a stack trace like this:
(lldb) thread backtrace
That should give us more information on why it's crashing in the Terminal as well.
Ok, this seems to be an issue when I try to integrate it into a slightly larger tool which also uses SwiftArgumentParser etc;
thread #1, queue = 'com.apple.main-thread'
frame #0: 0x00000001a63aedf0 libsystem_kernel.dylib`mach_msg2_trap + 8
frame #1: 0x00000001a63c08d8 libsystem_kernel.dylib`mach_msg2_internal + 80
frame #2: 0x00000001a63b7638 libsystem_kernel.dylib`mach_msg_overwrite + 540
frame #3: 0x00000001a63af16c libsystem_kernel.dylib`mach_msg + 24
frame #4: 0x00000001a64cdbdc CoreFoundation`__CFRunLoopServiceMachPort + 160
frame #5: 0x00000001a64cc4c8 CoreFoundation`__CFRunLoopRun + 1232
frame #6: 0x00000001a64cb8a4 CoreFoundation`CFRunLoopRunSpecific + 612
frame #7: 0x00000001a6552818 CoreFoundation`CFRunLoopRun + 64
frame #8: 0x000000022e485f34 libswift_Concurrency.dylib`swift_task_asyncMainDrainQueueImpl() + 40
frame #9: 0x000000022e485f0c libswift_Concurrency.dylib`swift_task_asyncMainDrainQueue + 100
frame #10: 0x0000000100131d48 ordo-storage-tool`ordo_storage_tool_main at Dump.swift:0 [opt]
frame #11: 0x00000001a60c3e50 dyld`start + 2544
* thread #2, queue = 'com.apple.root.default-qos.cooperative', stop reason = EXC_BREAKPOINT (code=1, subcode=0x1a6276050)
* frame #0: 0x00000001a6276050 libdispatch.dylib`dispatch_main + 68
frame #1: 0x00000001000e5e14 ordo-storage-tool`Application.start(self=0x0000600002104d20) at Application.swift:47:9 [opt]
frame #2: 0x0000000100133ab0 ordo-storage-tool`StorageTool.run() [inlined] static ordo_storage_tool.Interactive.tailLastTransactions() async throws -> () at Interactive.swift:26:49 [opt]
frame #3: 0x0000000100133a70 ordo-storage-tool`StorageTool.run(self=ordo_storage_tool.StorageTool @ 0x00006000017044d0) at Tool.swift:35:35 [opt]
frame #4: 0x0000000100133e60 ordo-storage-tool`protocol witness for AsyncParsableCommand.run() in conformance StorageTool at <compiler-generated>:0 [opt]
frame #5: 0x0000000100022108 ordo-storage-tool`static AsyncParsableCommand.main(self=0x0000000100172230) at AsyncParsableCommand.swift:37 [opt]
frame #6: 0x0000000100131dc4 ordo-storage-tool`specialized thunk for @escaping @convention(thin) @async () -> () at <compiler-generated>:0 [opt]
(lldb)
from the documentation:
This function "parks" the main thread and waits for blocks to be submitted to the main queue.
Applications that call UIApplicationMain(_:_:_:_:) (iOS), NSApplicationMain(_:_:) (macOS),
or CFRunLoopRun() on the main thread must not call dispatchMain().
So it seems I get an implicit CFRunLoop from using Concurrency (async main entry point through SwiftArgumentParser) and thus aren't allowed to call dispatchMain()
.
Right, I don't expect that to work, SwiftTUI apps need to be started from the main thread and start their own runloop.
Ok, will see if I can refactor this and get it to work - I'm looking to adding an 'interactive' mode to a CLI utility and it'd be cool to leverage SwiftTUI for that. Thanks for the reply.
Ok, for future readers - it is possible to integrate with Swift Argument Parser, just use 'Parsable Command' (can't have async entry point to the program unfortunately).
Trying to build small sample project (attached) which fails due to the rect being zero (so upperBound becomes negative -1).
2022-12-01 17:01:32.059857+0100 repro-swifttui[38382:1822751] Swift/arm64e-apple-macos.swiftinterface:5817:
Also tried with the official 0.1.0 - but got the same issue
repro-swifttui.zip