I'm developing an app with Swift and SwifUI where GoogleCast framework is needed only for one flavor.
Imagine the view where I instantiate the GoogleCastButton:
import SwiftUI
import GoogleCast
struct NavBarView: View {
@ObservedObject private var viewModel: NavBarViewModel
init(viewModel: NavBarViewModel) {
self.viewModel = viewModel
}
var body: some View {
HStack {
Text("Home")
//other view stuff...
if viewmodel.showCastButton {
GCKUICastButton()
}
}
}
}
With the following approach, I have to use conditional compilation (#if flavourA) in the view to reuse the rest of the view and is something I don't wanna do because the app can become very complicated
I need to find a way in which I can inject a view interface or something like that in my composition root depending on the flavor but I'm not sure if this is the correct approach using MVVM + clean architecture and if so I'm not sure on how to do it properly
On the other hand, if I follow the dependency injection approach that I mentioned I will need to implement a FakeGoogleCastButton: GoogleCastButton which returns an empty view no?
If yes I would also need to create a FakeGoogleCastService: CastService to use in the data layer?
I have the feeling that I am not understanding how to correctly apply the principles of clean architecture in this case.
Maybe there is another type of interface adapter for this situation?
I created a CastRepository and a CastService interfaces to use the Google Cast data in my use cases but I don't know how I should approach the UI
In SwiftUI the
Viewstruct already is the view model, thus it already is MVVM and already is clean. SwiftUI automatically manages the UI layer (i.e. UIKit UIView objects) from theseViewstruct lightweight descriptions and keeps them up to date. If you try to code view model objects on top you'll just run into major issues so it's best to just learn theViewstruct, and howbodyis called when ever any@State var,@Binding varorletchanges. You'll also need to use computed vars to transform data as you pass it in to a childView. If you want to group related vars with testable logic you can make a@Statecustom struct but have to learn aboutmutating func.For your service, usually those are
EnvironmentKeystructs, that way they can be easily replaced with a mock for Previews. Usually they have an async func you can call from.taskthat returns results you can store in@State. See Apple's@Environment(\.authorizationController)for an example.