stackotter / swift-cross-ui

A cross-platform declarative UI framework, inspired by SwiftUI.
https://stackotter.github.io/swift-cross-ui/documentation/swiftcrossui/
MIT License
621 stars 36 forks source link

CombineX support #26

Open darvin opened 1 year ago

darvin commented 1 year ago

published etc

stackotter commented 1 year ago

Could you please provide more details on how you would expect CombineX to be integrated with SwiftCrossUI and where you would expect to be able to use it? Specifically, what would this integration enable you to do that you can't already do with SwiftCrossUI?

Currently users are expected to use SwiftCrossUI's custom ViewState and AppState mechanisms which are very similar to Combine's ObservableObject but simpler.

As an aside, if/when I add Combine integration I will probably use OpenCombine instead of CombineX because OpenCombine is the solution I've been using in my cross-platform projects.

lhoward commented 1 year ago

Just a +1 for OpenCombine support (I see it was there originally, but was removed in deb735a32f0b52449e39c9bb379a7029599c2144). I'd like to use SwiftCrossUI for a project I'm working on that is reasonable dependent on the Combine APIs.

stackotter commented 1 year ago

Ok awesome, I’m happy to look into adding OpenCombine support 👍 How exactly would you like to see it being integrated? Would you just want the AppState/ViewState protocol to be replaced by ObservableObject, or would you like SwiftCrossUI to have a more complex state system that more closely resembles SwiftUI (where you can add however many different state properties to a view as you want including ones using @State, @ObservedObject etc)?

I’ll probably go with the first approach first, but I can certainly look into the pros and cons of copying SwiftUI more closely in terms of state management.

lhoward commented 1 year ago

Actually, hold that thought – let me see if I can eliminate my use of Combine by moving completely to async/await. More soon :)

stackotter commented 1 year ago

Ok :) I’m interested to know what sorts of projects people will use SwiftCrossUI for. If you don’t mind me asking, what kind of app are you making? And are you trying to make a SwiftUI app into a cross platform app? or starting a project with cross platform in mind?

lhoward commented 1 year ago

I'm working on an embedded project (audio mixer with touchscreen) and I want to take advantage of my familiarity with Swift and SwiftUI. The price of course is the latter is not available on embedded platforms. So my plan – which is very much in the early stages – is to use SwiftCrossUI and, potentially if Gtk is too heavyweight, write another backend using a different UI framework (although I have no idea what).

Time will tell whether this is a good idea or I should have just used Flutter!

stackotter commented 1 year ago

Sounds cool! Feel free to open issues for any other missing features you need. I'm happy to help prepare SwiftCrossUI for supporting multiple backends experimentally if that ends up being necessary eventually.

lhoward commented 1 year ago

OK, I've managed to eliminate Combine dependencies in my library thanks to the wonderful AsyncCurrentValueSubject from AsyncExtensions. So OpenCombine support is less important to me now. :)

stackotter commented 1 year ago

Nice :) Don’t hesitate to let me know if you need any other features to help you create the UI you have in mind!

lhoward commented 1 year ago

I've been having a look at LVGL (tweaking a fork of LVGLSwift). I'm thinking it might be a better fit for me because that way I don't need a compositor, potentially can even run without an operating system.

My use case is fairly simple so, I probably also don't really need SwiftUI, but it would be ideal (and I've started prototyping the client using it).

How easy do you think it would be to abstract your project so it could support both GTK and LVGL?

stackotter commented 1 year ago

I have thought about abstracting the project in the past, and back then at least I thought it was probably pretty doable. I'm happy to give it a go in a week or two (travelling for a week and a bit busy so won't be able to work on SwiftCrossUI for a bit). This would also mean that the previously requested QT backend could be added pretty easily after supporting LVGL (or before, depending on which will be easier).

lhoward commented 1 year ago

Sounds good, I'm also going to be away from 9th July but happy to put some work in. In the meantime I'll look at wrapping up LVGL in something Swifty.

stackotter commented 1 year ago

Sounds good, a swifty wrapper would be great 👍

stackotter commented 1 year ago

If you create a new issue for this we can track the progress a bit better probably

lhoward commented 1 year ago

Yeah, I’m interested to see if marrying async/await to an old school event driven API works!

lhoward commented 1 year ago

There was a Swifty wrapper but I NIH-started a new one here :) https://github.com/PADL/LVGLSwift

stackotter commented 1 year ago

Nice :) looks like it’s private or something tho, I get a 404

lhoward commented 1 year ago

Fixed, not much to see yet though!

stackotter commented 1 year ago

Awesome, I’ll keep an eye on it 👀

stackotter commented 1 year ago

Your wrapper looks cool so far, I think adding an LVGL backend won’t be too hard 👌 I look forward to giving it a go when I get home

lhoward commented 1 year ago

It’s not actually working yet 😂 but hopefully not too far off.

lhoward commented 1 year ago

I did look at OpenCombine support, but some controls (e.g. slider) sent it into an endless redraw loop. More work needed :)

https://github.com/PADL/swift-cross-ui/tree/opencombine-revive

stackotter commented 1 year ago

Ah right, i've had some other infinite update loop issues in the past; usually they can be fixed pretty easily by not calling setters if the old value matches the new value. I can take a look an your branch when I get the time (may be a few days until that happens)