Search code examples
iosswiftuikit

Returning an Object "Type of expression is ambiguous without more context"


I want to return my RecipeModel object but get an error of 'Type of expression is ambiguous without more context'. I did use all the properties I have created in my struct. I already tried removing ",json:[String: Any]" and checked if I missed a bracket. What am I missing? Thank you for help.

func parseRecipes(forJSON json: [String: Any]) -> [RecipeModel] {
    guard let recipesData = json["recipeTiles"] as? [[String: Any]] else { return [] }

    let recipes = recipesData.compactMap({ (recipesDictionary) -> RecipeModel? in
    let recipeTypeString = recipesDictionary["type"] as? String
    let imageString = recipesDictionary["image"] as? String
    let bgTypeString = recipesDictionary["backgroundType"] as? String
    let bgType = BackgroundType(rawValue: bgTypeString ?? "")
    let title = recipesDictionary["title"] as? String
    let ingredients = recipesDictionary["ingredients"] as? [[String: String]]
    let directions = recipesDictionary["directions"] as? [[String: String]]

        
        return RecipeModel(type: recipeTypeString, image: imageString, title: title, ingredients: ingredients, directions: directions, bgType: bgType) // Error pops up here

        })
      
      return recipes
      
  }

This is my RecipeModel struct where all the let properties are listed

struct RecipeModel {
var viewMode: CardViewMode = .card
var type: String
var title: String
var ingredients: [IngredientModel]
var directions: [DirectionModel]
var image: String
var backgroundType: BackgroundType = .light


init(type: String, title: String, ingredients: [String: Any], directions: [String: Any], image: String, bgType: BackgroundType, json: [String: Any]) {
    self.type = type
    self.title = title
    self.image = image
    self.backgroundType = bgType
    self.ingredients = []
    if let jsonIngredients = json["ingredients"] as? [String: Any] {
        for jsonIngredient in jsonIngredients {
            self.ingredients.append(IngredientModel(json: jsonIngredient as? [String: Any] ?? [:]))

            }
        }

    self.directions = []
    if let jsonDirections = json["directions"] as? [String: Any] {
        for jsonDirections in jsonDirections {
            self.directions.append(DirectionModel(json: jsonDirections as? [String: Any] ?? [:]))
        }
     }
  }

}


Solution

  • An initializer is a function. A function declaration is a contract. When you call the function you must keep that contract. I appreciate that it is not a very helpful error message, and it might be worth filing a bug report about that, but the nature of the actual error is quite simple.

    So, the error is on the line where you call a RecipeModel initializer like this:

    RecipeModel(type: recipeTypeString, image: imageString, title: title, ingredients: ingredients, directions: directions, bgType: bgType)
    

    Well, there is no such initializer. The initializer is this:

    init(type: String, title: String, ingredients: [String: Any], directions: [String: Any], image: String, bgType: BackgroundType, json: [String: Any]) {
    

    Your call must include all of those parameters. They must be in that order (type:, then title: — you've put image: instead — and so on) and it must not omit any of them (you have omitted json: entirely). (EDIT And of course the types of the passed arguments must match the declared types of the corresponding parameters.)