For this project i was tasked with providing a list of meals based on the API and also alowing the user to get further detail about the meal by using the details API.
For the project i used the MVVM architecture to allow for great separation of the business logic from the views and models.
-
Models: 1. For the
Mealspresented in the list, i used theMealResponse&Mealmodels, to decode the data retrieved to represent each meal. 2. For theMeals Detailspresented after the user taps a meal, I usedMealDetailResponse&MealDetailto represent these 3. Also I added an additional computer property calledMealDetail.ingredientsAndMeasurementsto allow for ease of use when handling the multiple different ingredients and measurements for the meal. 4. Also created a struct for modeling the Ingredients & Measurements data calledIngredientMeasurement -
ViewModels:
1. Created the `MealsViewModel` to handle the business logic and dependecies(`MealServices`) for the `MealsView` 2. From here we used the service dependency to fetch data and pass it to the view 3. Also hanlded the sorting by alphabetical order ### MealRowViewModel 1. Used within the row of each view in the `MealsView` 2. Uses the `ImageCacheService` to check if an image was already downloaded and saved locally to the `cachedImageDictionary`, if not we download the image and then save it1. Created to fetch the details for the selected meal, by using the `mealID`
1. `MealsView` - shows the list of all the meals provided by the API
2. `MealRowView` - view that represents each meal inside the List in `MealsView`
3. `MealDetailsView` - shows the details for a specific meal allow with its ingredients, directions and measurements
4. `MealDetailRowView` - used to show the Ingredeint & measurements for the meal in the detail screen
1. `MealsService` - used to fetch the list of meals provided by the API and also the details for a specific meal
2. Provides custom errors `MealServiceError`, allow with a readable error message using `errorMessage` property it has
Originally i was using AsyncImage, but since this doesnt provide caching I used a basic local caching dictionary. This is used for storing already downloaded UIImages allow with their URL as a key.
- After an image is downloaded it is saved to the local dictionary cache
- If we need it again we fetch from the dictionary instead of redownloading
Note: I could also have used a 3rd Party for handling caching like SDWEbImageSwiftUI
1. `MealCategories` - An enum used to represent the various types of categories that can be passed in the request for the API
Endpoints- enum used to handle getting the specific endpoints needed for: Fetching all meals based on a category: "https://themealdb.com/api/json/v1/1/filter.php?c=\(mealCategory)" Fetching details about a specifc meal by using an ID: "https://themealdb.com/api/json/v1/1/lookup.php?i=\(mealID)"