Im working on a project which uses GraphQL to get product information from a shopify store. I query data by searching the products ProductID and get the data in the form Storefront.Product. However my view model requires it to be in the form Storefront.ProductEdge.
Im trying to adding two different model types (Storefront.Product and Storefront.ProductEdge) in the same view model (ProductViewModel).
Heres my code:
import Foundation
import Buy
final class ProductViewModel: ViewModel {
typealias ModelType = Storefront.ProductEdge
typealias ModelType1 = Storefront.Product
let model: ModelType
let model1: ModelType1
let cursor: String
var id: String
var title: String
var summary: String
var price: String
var images: PageableArray<ImageViewModel>
var variants: PageableArray<VariantViewModel> ///Ive changed let to var here so i can assign values in HomeController
// ----------------------------------
// MARK: - Init -
//
required init(from model: ModelType) {
self.model = model
self.cursor = model.cursor
let variants = model.node.variants.edges.viewModels.sorted {
$0.price < $1.price
}
let lowestPrice = variants.first?.price
self.id = model.node.id.rawValue
self.title = model.node.title
self.summary = model.node.descriptionHtml
self.price = lowestPrice == nil ? "No price" : Currency.stringFrom(lowestPrice!)
self.images = PageableArray(
with: model.node.images.edges,
pageInfo: model.node.images.pageInfo
)
self.variants = PageableArray(
with: model.node.variants.edges,
pageInfo: model.node.variants.pageInfo
)
}
required init(from model1: ModelType1){
self.model1 = model1
self.cursor = ""
let variants = model1.variants.edges.viewModels.sorted {
$0.price < $1.price
}
let lowestPrice = model1.variants.edges.first?.viewModel.price
self.id = model1.id.rawValue
self.title = model1.title
self.summary = model1.descriptionHtml
self.price = lowestPrice == nil ? "No price" : Currency.stringFrom(lowestPrice!)
self.images = PageableArray(
with: model1.images.edges,
pageInfo: model1.images.pageInfo
)
self.variants = PageableArray(
with: model1.variants.edges,
pageInfo: model1.variants.pageInfo
)
}
}
extension Storefront.ProductEdge: ViewModeling {
typealias ViewModelType = ProductViewModel
}
It is saying
Return from initializer without initializing all stored properties
Is this possible to do?
please help?
EDIT:
By making model and model1 options or using Enums on model or model1, I get the error
Type 'ProductViewModel' does not conform to protocol 'ViewModel'
Do I need to somehow do an If statement or enum on Storefront.ProductEdge and Storefront.Product??
here is the ViewModel protocol:
import Foundation
protocol ViewModel: Serializable {
associatedtype ModelType: Serializable
var model: ModelType { get }
init(from model: ModelType)
}
extension ViewModel {
static func deserialize(from representation: SerializedRepresentation) -> Self? {
if let model = ModelType.deserialize(from: representation) {
return Self.init(from: model)
}
return nil
}
func serialize() -> SerializedRepresentation {
return self.model.serialize()
}
}
. I am unable to change this protocol.
Please help?
In Swift you are required to assign a value to all properties before exiting an initializer. It appears that in both cases you're either not assigning a value to model
or model1
. If it's intentional for on our the other to be used, but not both, I'd recommend an enum with an associated value. Something like this:
enum ModelObject {
case model(Model)
case model1(Model1)
}
Then in your initializer you can do:
self.modelObject = .model1(model1)
or
self.modelObject = .model(model)
If for some reason that doesn't work, you could also make them both optional and assign one to nil
and the other to the value it was initialized with.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.