HipstuCAU / nyam_nyam

오늘 먹을 메뉴를 고민하고 있는 학우들을 위해 만들었습니다.
2 stars 0 forks source link

Haksik 도메인 구현과 MealPlanDTO, MealPlan 을 재구성하였습니다. #107

Closed TaekH closed 9 months ago

TaekH commented 9 months ago

1. MealPlanDTO의 재구성, MealPlan 을 구현하였습니다.

배경

ServerDrivenUI 를 도입함에 따라서 JSON 구조가 중앙대를 위한 구조가 아닌 다양한 학식 데이터를 포함할 수 있도록 확장성 있게 수정되었습니다.

따라서, 그에 맞추어 MealPlanDTO 또한 재구성하였습니다.

MealPlanDTO

JSON 학식 데이터를 파싱하기 위한 Codable구조체로, JSON과 같은 구조를 지닙니다.

여기서 MenuDTO 의 경우, 기존 중앙대 학식을 포함하여 몇몇 데이터가 없는 경우 (카우버거, 카우잇츠 등) 에 대해 해결하기 위해서 init(from decoder: Decoder)을 직접 구현하여 처리하도록 하였습니다.

struct MenuDTO: Codable {
    let menuType: String
    let price: String
    let startTime: String
    let endTime: String
    let menu: [String]
    let calories: String

    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        menuType = (try container.decodeIfPresent(String.self, forKey: .menuType)) ?? ""
        price = (try container.decodeIfPresent(String.self, forKey: .price)) ?? ""
        startTime = (try container.decodeIfPresent(String.self, forKey: .startTime)) ?? ""
        endTime = (try container.decodeIfPresent(String.self, forKey: .endTime)) ?? ""
        menu = try container.decode([String].self, forKey: .menu)
        calories = (try container.decodeIfPresent(String.self, forKey: .calories)) ?? ""
    }
}

옵셔널로도 가능한 부분이지만, 기본값을 반환해야하는 상황에서 옵셔널을 통해 추가적인 조건문을 구현하는 것보다 간결하게 처리가 가능하다고 판단하여 decodeIfPresent로 처리하였습니다.

그외에 MenuDTO 의 상위 DTO들은 모두 고정된 데이터를 가지고 들어와야하기 때문에, 따로 init(from decoder: Decoder) 를 구현하지 않았습니다.

MealPlan

HaksikService 를 통해 MealPlanDTO 를 파싱하여 학식 데이터를 UI에 그려주기 위한 데이터 구조입니다. MealPlanDTO 구조와 유사하게 구성하였습니다.

struct MealPlan: Equatable {
    let date: Date
    let cafeterias: [Cafeteria]
}

struct Cafeteria: Equatable {
    let cafeteriaID: String
    let meals: [Meal]
}

struct Meal: Equatable {
    let mealType: String
    let shouldShowTime: Bool
    let startTime: Date
    let endTime: Date
    let menus: [Menu]
}

struct Menu: Equatable {
    let menuType: String
    let price: Int
    let startTime: Date
    let endTime: Date
    let menu: [String]
    let calories: Double
}

2. HaksikService 를 구현하였습니다.

MealPlanDTO 를 MealPlan으로 바꿔주는 HaksikService 를 구현하였습니다. MealPlan이 MealPlanDTO 와 비슷한 구조로 수정되었기 때문에 HaksikService 또한 단순히 map을 활용하여 최종적으로는 Single<[MealPlan]> 을 반환하게 됩니다.

3. 흐름

image

MealPlanDTO 가 JSON 전체를 파싱하는 것이 아닌 하루치 식단 JSON 만을 파싱하도록 변경 되었습니다. 따라서 기존 구조에서 MealPlanRepository 는 MealPlanDTO 가 아닌 [MealPlanDTO] 를 반환하도록 수정, HaksikDomain 에서는 이를 [MealPlan]으로 재구성 하고 UI에서 쓰이게 됩니다.