-
Notifications
You must be signed in to change notification settings - Fork 14
Expand file tree
/
Copy pathBMDiningLocation.swift
More file actions
168 lines (145 loc) · 4.4 KB
/
BMDiningLocation.swift
File metadata and controls
168 lines (145 loc) · 4.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
//
// BMDiningLocation.swift
// bm-persona
//
// Created by Oscar Bjorkman on 4/24/20.
// Copyright © 2020 RJ Pimentel. All rights reserved.
//
import Firebase
import FirebaseCore
import UIKit
/// `BMDiningHall` is the representation for a dining hall used throughout the app. We fetch the dining halls from Firebase as `BMDininghallDocument` and convert them into `BMDiningHall`.
struct BMDiningHall: HomeDrawerSectionRowItemType, HasPhoneNumber, HasOpenClosedStatus, Hashable {
var id: String { docID }
var docID: String
var icon: UIImage?
var searchName: String { return name }
var imageURL: URL?
var name: String
var address: String?
var phoneNumber: String?
var isOpen = false
/// A private array of `String` representation of all the open time interval periods
private(set) var _hours: [String]
var hours: [DateInterval] {
return _hours.compactMap { $0.convertToDateInterval() }
}
var meals: [BMMeal.BMMealType: BMMeal]
var latitude: Double?
var longitude: Double?
init(
name: String,
address: String?,
phoneNumber: String?,
imageLink: String?,
meals: [BMMeal.BMMealType: BMMeal] = [:],
hours: [String],
latitude: Double?,
longitude: Double?,
documentID: String = ""
) {
self.name = name
self.address = address
self.phoneNumber = phoneNumber
self.imageURL = URL(string: imageLink ?? "")
self.meals = meals
self._hours = hours
self.latitude = latitude
self.longitude = longitude
self.icon = UIImage(systemName: "fork.knife")
self.docID = documentID
}
func getCategoriesAndMenuItems(for mealType: BMMeal.BMMealType) -> [BMMealCategory] {
return meals[mealType]?.categoriesAndMenuItems ?? []
}
}
// MARK: - Firebase Decode Struct Representations
struct BMDiningHallDocument: Codable, Identifiable {
@DocumentID var id: String?
let diningHall: BMDiningHallRepresentation
let scrapedAt: Timestamp?
}
struct BMDiningHallRepresentation: Codable {
let name: String
let status: String
let openHourPeriods: [String]
let serveDate: String
let meals: [BMMeal]
enum CodingKeys: String, CodingKey {
case name = "locationName"
case status
case openHourPeriods = "timeSpans"
case serveDate
case meals
}
func getMealsTypeDict() -> [BMMeal.BMMealType: BMMeal] {
var dict: [BMMeal.BMMealType: BMMeal] = [:]
meals.forEach { meal in
dict[meal.mealType] = meal
}
return dict
}
}
struct BMMeal: Codable, Hashable {
enum BMMealType: String, Codable {
case breakfast = "Breakfast"
case brunch = "Brunch"
case lunch = "Lunch"
case dinner = "Dinner"
case other = "Other"
static var regularMealTypes: [BMMealType] {
return [.breakfast, .brunch, .lunch, .dinner]
}
}
let mealType: BMMealType
let mealTypeName: String
let time: String?
let categoriesAndMenuItems: [BMMealCategory]
enum CodingKeys: String, CodingKey {
case mealType = "meal"
case mealTypeName = "rawTitle"
case time
case categoriesAndMenuItems
}
}
struct BMMealCategory: Codable, Hashable {
let categoryName: String
let menuItems: [BMMenuItem]
}
struct BMMenuItemDetail: Codable, Hashable {
let servingSize: String?
let nutrition: [String: String]?
let ingredients: String?
let allergens: [String]?
}
struct BMMenuItem: Codable, Hashable {
let name: String
let icons: [BMMealIcon]
let menuId: String?
let itemId: String?
let dataLocation: String?
let recipeDetails: BMMenuItemDetail?
}
struct BMMealIcon: Codable, Hashable {
let name: String
let iconURL: String
}
/// `BMDiningHallAdditionalData` includes static data not scrapable from the dining hall menus website
struct BMDiningHallAdditionalData: Codable {
let name: String
let address: String
let pictureURL: String?
let latitude: Double
let longitude: Double
let description: String?
let phoneNumber: String?
enum CodingKeys: String, CodingKey {
case name
case address
case pictureURL = "picture"
case latitude
case longitude
case description
case phoneNumber = "phone"
}
}