-1

I have a FridgeVC inside which I search for some ingredients and add them to the selectedIngredients array. For this I use Ingredient model. and also I have a childVC there. On childVC I have findRecipes button. For now I can search for ingredients and append them to the selectedIngredients array. Then I want to use a different endpoint of my API and search recipes related to these selected ingredients by using FindByIngredients model but I fail. I use UICollectionViewDiffableDataSource for this. When I tap on findRecipes button I want the ingredients to be removed and show the recipes along with their images and titles. The same cell (FridgeVcCell) I am using for ingredients would also work for this purpose. In the configureDataSource() function I am configuring the data source for the Ingredient model.

If I want to reuse the same dataSource for both Ingredient and FindByIngredients models, what should I do? How to combine these two models into one?

I tried some things but they didn't work. I asked ChatGPT and it advised to use a protocol named DisplayableItem and then make both Ingredient and FindByIngredients conform to it. But it gives me this following error:

Use of protocol 'DisplayableItem' as a type must be written 'any DisplayableItem'

Some parts of my code are below:

Ingredient model:

struct Ingredient: DisplayableItem, Codable, Hashable {
    let name: String
    let image: String
    
    var imageURL: String? {
        return "https://spoonacular.com/cdn/ingredients_100x100/\(image)"
    }
}

FindByIngredients model:

// MARK: - RecipeSearchElement
struct FindByIngredients: DisplayableItem, Codable, Hashable {
    let id: Int
    let title: String
    let image: String
    let imageType: String
    let usedIngredientCount, missedIngredientCount: Int
    let missedIngredients, usedIngredients: [SedIngredient]
    //let unusedIngredients: [JSONAny]
    let likes: Int
    
    enum CodingKeys: String, CodingKey {
            case id, title, image, imageType, usedIngredientCount, missedIngredientCount, missedIngredients, usedIngredients, likes
        }
}

// MARK: - SedIngredient
struct SedIngredient: Codable, Hashable {
    let id: Int
    let amount: Double
    let unit, unitLong, unitShort, aisle: String
    let name, original, originalName: String
    let meta: [String]
    let image: String
    let extendedName: String?
}

Beginning of my VC. Here I get lots of errors:

import UIKit

protocol DisplayableItem: Hashable {
    
}

class FridgeVC: UIViewController, UISearchBarDelegate {
    
    enum Section { case main }
    
    
    let ingredientsVC = IngredientsVC()
    var user: User?
    private var ingredients = [String]()
    var ingredientsArray: [DisplayableItem] = []
    var recipesArray: [DisplayableItem] = []
    var selectedIngredients: [DisplayableItem] = []
    var hasMoreIngredients = true
    var page = 1
    var isLoadingMoreIngredients = false
    var dataSource: UICollectionViewDiffableDataSource<Section, DisplayableItem>!
HangarRash
  • 7,314
  • 5
  • 5
  • 32
asduskun
  • 17
  • 5
  • *Use of protocol 'DisplayableItem' as a type must be written 'any DisplayableItem'* So write it that way. Example: `var ingredientsArray: [any DisplayableItem] = []` – matt Aug 14 '23 at 12:11
  • So this is the right way for my purpose? I added the keyword any there before I tried like that too but i got another error which i don't remember now. But I'll try and tell the result soon – asduskun Aug 14 '23 at 12:33
  • Ok when i add "any" i get this error although there protocol itself is hashable "Type 'any DisplayableItem' cannot conform to 'Hashable'" – asduskun Aug 14 '23 at 12:50
  • Yes but that is not what you asked. (Though to be honest I'm not sure what you asked.) – matt Aug 14 '23 at 12:55
  • i have two models and 1 diffable data source for a ViewController. it works with one model without a problem but later I added another model for a different endpoint. now I can't use them together for my diffable datasource. this is my datasource with Ingredient model but how will I add the other model to this datasource? var dataSource: UICollectionViewDiffableDataSource
    !
    – asduskun Aug 14 '23 at 15:22
  • 1
    The problem is that your data source is too simple minded. You have specified `UICollectionViewDiffableDataSource
    ` but that is now a lie. What I would do is keep the data somewhere else and just make the diffable data source an `` or similar so that when you populate the cell you can key into your real data based on the section Int and the item UUID.
    – matt Aug 14 '23 at 15:31
  • i am new to diffable datasource that's why I am having problems. before I read your comment I used enums and added two different cases for my two different models and modified the rest accordingly now it seems like it works.but I just tried on Ingredient model for now. later I ll try to make it work on FindByIngredient model too to find the recipes related to the selected ingredients. By the way inside the brackets
    is not a default usage? can I customize it as you said like ?
    – asduskun Aug 14 '23 at 16:08
  • 1
    You can store anything you like inside the diffable data source, as long as it corresponds to the _structure_ of the data you want to display. What _you_ are doing is to store your entire model inside the diffable data source. What _I_ am saying is: there is no need to do that, so don't do it. Just store enough information to allow you to populate the cells. – matt Aug 14 '23 at 16:27

0 Answers0