Description
Feature request
Generated Fragment objects should also have init
methods with the necessary strictly-typed fields from the struct
instead of just having the DataDict
init
, just like InputObjects
Motivation
The Fragment models generally contain the necessary data for the Views and ViewModels that will consume them, so I use them directly instead of creating mirror models and converting the dto into them (since that would just bloat the code).
So we avoid this:
class ViewModel {
let model: MyModel
public init(model: MyModel) {
self.model = model
}
}
struct MyModel {
let id: String
let someField: Int
public init(from dto: MyFragment) {
self.id = dto.id
self.someField = dto.someField
}
}
And do something like this instead:
class ViewModel {
let dto: MyFragment
public init(dto: MyFragment) {
self.dto = dto
}
}
When implementing previews for these Views, we need some easy Mock data and we used to be able to initialize these fragments with a normal init
which just took the fields as arguments. With the new generation engine, this feature has been removed and has been made available only on InputObjects
, so the only way to initialize these fragments is through a DataDict
, and you can see how this is cumbersome (as stated in the test docs). The official Mock architecture is also available but it's a little overkill when all we need to do is:
let viewModel = ViewModel(dto: .init(id: "0", someField: 43))
Besides, using Mocks means that they'd need to be embedded into the main target of the application, which isn't desirable since we have a separate target for testing.
Proposed solution
Investigating the source code, InputObjectTemplate
has its own functions that are used to define the convenient inits
, so those would need to be externalized somehow so that they'd be able to be reused in more than one place. FragmentTemplate
defines the inits
by calling the SelectionSetTemplate
's BodyTemplate
function, the inits
are defined in the SelectionSetTemplate.DataFieldAndInitializerTemplate
function.
I'm not sure if it's desirable to implement this convenient init
in the DataFieldAndInitializerTemplate
function since I don't know to what extent that would affect other templates, so a solution to that may be needed