- Delivery app that fetches a list of restaurants from Firebase.
- When tapping on a restaurant can see a list of food items on the Restaurant view.
- When tapping on an item, you can choose the quantity of the item.
- Some foods can be customized with up to three additional ingredients.
- After choosing your desired food items, you can move to the Order view.
- After placing an order, it is added to Firebase database and you see a success screen.
- When you go to the History view, the list of placed orders is fetched.
- You can click on each order to see what it contains.
Content
- Lesson 1 - Setup & Splash View
- Lesson 2 - Home View
- Lesson 3 - Restaurant View
- Lesson 4 - Ingredient, Food View, Navigation
- Lesson 5 - Item & Order
- Lesson 6 - Firebase
- Lesson 7 - History View
- Lesson 8 - Status, Discount, Flavor
- UI/UX Designs (Figma)
- Icon, Assets, and data.json (Google Drive)
Views | Previews |
---|---|
HomeView | RestaurantPreview |
RestaurantView | FoodPreview |
OrderView | ItemPreview |
StatusView | StatusPreview |
HistoryView | OrderPreview |
FoodView | N/A |
- Components
- Navigation
- Firebase
- In-N-Out Burger
- Five Guys
- Subway
Task | Time |
---|---|
Introductions & Deliverfly demo | 20 min |
Setup Github & Fork | 50 min |
Break | 10 min |
[Task 0] Create Project + Import Icon & Assets | 10 min |
[Task 1] SplashView | 30 min |
- Check macOS version -> apple (top-left corner) -> About This Mac -> macOS (last item on bottom) -> must be Sonoma 14+
- Check if Xcode is installed -> if not Google "Xcode" -> find in App Store and start downloading
- Agree to Terms & Conditions -> type user password
- Select Platform to develop for: iOS (e.g. iOS 17.4 --- 7.23 GB)
- Wait for download to complete
- Join via the invite link (TUMO-SwiftUI)
- Sign in or make an account
Explore & explain Figma designs here
We'll setup a new Github repository and download Fork together. Students who don't have a Github account will make one.
- Google "fork" https://git-fork.com
- Click on Download Fork for Mac
- Double-click and drag "dmg" file to "Applications" folder
- Open Fork, right-click icon -> Options -> Keep in Dock
- Top-left corner Fork -> Accounts... -> GitHub
- Log in -> Authentication Type: Log in on GitHub.com (OAuth) (not Personal Access Token) -> Login: username or email -> input password
- Enable notifications in menu bar -> Close
- Go to Fork -> Settings... -> Git -> input your name or nickname ->
⚠️ make sure the email matches your github email
- Go to github.com -> New (top-left green button)
- Repository name: Deliverfly-GivenName-FamilyName (e.g. Deliverfly-Neli-Shahapuni)
- Repository can be Public or Private (your choice)
- Enable Add a README file
- Add .gitignore -> template: Swift
- Create Repository (green button)
- Go to main (top-left gray dropdown)
- Find or create branch... -> type "develop" (all lowercase)
- Click: Create branch develop from main
- Go to Settings (list on top, last item) -> Default Branch (currently: main) -> click: switch to another branch (2 arrows) -> choose "develop" from dropdown -> Update
- Go to repository -> click Code (top-right green button) -> Copy URL (post the URL via Slack channel)
- Open Fork -> File -> Clone...
- Location: /Documents OR /Desktop -> Open
- Click Clone
- Go to fork & checkout 'develop'
- Right-click 'develop' -> New Branch... -> name it feature/splash-view
- Create New Project... -> App -> Next
- Product Name: Deliverfly
- Team: FirstName LastName (Personal Team) (e.g. Neli Shahapuni (Personal Team)) - it can also be the apple account or current user on the computer
- Organization Identifier: givennamefamilyname (e.g. nelishahapuni)
- Interface: SwiftUI
- Language: Swift
- Storage: None
- Disable Include Tests
- Save project inside the folder named Deliverfly-GivenName-FamilyName (e.g. Deliverfly-Neli-Shahapuni)
- Increase Font size (if needed)
- Show File Navigator
- Run the app for the first time (click on the triangle, top-left) or Command + R
- Click on the rectangle to stop running (wait for simulator to load if 1st time, don't close it)
- Go to Google Drive -> click on "Deliverfly" dropdown -> download Google Drive
- Go to downloads -> Double-click to unzip
- Go to Xcode -> Assets -> Drag 'Assets' folder to list
- Click on 'AppIcon' and drag the "icon" image
- Delete "Preview Content" folder
- Run the app (click on the triangle, top-left)
- When you get an error, click on the error, double-click on the "Deliverfly/Preview Content" and click on the minus (-) to remove it
- Make a commit on the feature/splash-view branch named [Task 0] Create Project + Import Icon & Assets -> Commit
- Click Push (UP arrow) -> Push
- Go to Xcode -> Find 'Deliverfly' folder (top-left) -> right-click -> New File... -> SwiftUI View -> name it 'SplashView'
- Go to 'SplashView' file & follow along (code should look like this)
- Click on the 'DeliverflyApp' file -> replace 'ContentView' with 'SplashView'.
- Click on 'ContentView' file -> right-click 'delete' -> Move to Trash
- Inside 'DeliverflyApp' file & follow along (code should look like this)
- Choose simulator (top-middle of Xcode) -> Run app (wait for simulator to load if 1st time)
- Stage changes & make commit named: [Task 1] SplashView -> commit
- Push to remote (arrow up 'push' button)
- Go to github.com -> find repository (list on left) -> click on 'Compare and pull request' (if you can't see it, then go to 'Pull Requests' -> New Pull Request (green button))
- base: develop <- compare: feature/splash-view
- Click on 'Create pull request'
- Click on 'Merge pull request' -> click on 'Confirm merge'
- Go to Fork -> click 'Fetch' (arrow down outline) -> go to Branches -> right-click Checkout 'develop' -> Click 'Pull' (arrow down fill)
Task | Time |
---|---|
[Task 2] RestaurantPreview | 40 min |
[Task 3] HomeView | 40 min |
Break | 10 min |
[Task 4] Add Five Guys and Subway | 15 min (independently) |
Check Work | 15 min |
- Go to fork & checkout 'develop'
- Right-click 'develop' -> New Branch... -> name it feature/home-view
- Double-click on 'Home' -> New File... -> SwiftUI View -> Next -> RestaurantPreview -> Create
- Add headerImage, restaurantName, menuItems, and details (code should look like this)
- Add image, name, items, rating, time (code should look like this)
- Stage changes & make commit named: [Task 2] RestaurantPreview -> commit
- Go to Xcode -> Find 'Deliverfly' folder (top-left) -> right-click -> New File... -> SwiftUI View -> name it 'HomeView'
- Select both 'SplashView' and 'HomeView' -> right click 'New Group from Selection' -> name it 'Views'
- Open 'HomeView' file & follow along (code should look like this)
- Inside 'DeliverflyApp' replace Text("home") with HomeView()
- Stage changes & make commit named: [Task 3] HomeView -> commit
- Push to remote (arrow up 'push' button)
- Add 2 more 'RestaurantPreview's with the following info:
image | name | items | rating | time |
---|---|---|---|---|
.inNOut | In-N-Out Burger | Double Double - Chocolate Shake - French Fries | 5.0 | 20 |
.fiveGuys | Five Guys | Cheeseburger - Fries - Milkshake - Sandwich | 4.7 | 45 |
.subway | Subway | Wrap - Footlong - Salad - Cookie | 3.5 | 50 |
- Check Work together
- Stage changes & make commit named: [Task 4] Add Five Guys and Subway -> commit
- Push to remote (arrow up 'push' button)
- Go to github.com -> respository -> feature/home-view had recent pushes X seconds ago -> click Compare and pull request (title is not important)
- base: developer <- compare: feature/home-view
- Click on 'Create pull request'
- Click on 'Merge pull request' -> click on 'Confirm merge'
- Go to Fork -> Fetch -> right-click 'develop' -> Check out 'develop' -> Pull
Task | Time |
---|---|
[Task 5] Food model | 10 min |
[Task 6] FoodPreview | 20 min (independently) |
Check Work | 20 min |
Break | 10 min |
[Task 7] Restaurant model | 10 min |
[Task 8] RestaurantView | 20 min (independently) |
Check Work | 30 min |
- Go to fork & checkout 'develop'
- Right-click 'develop' -> New Branch... -> name it feature/restaurant-view
- Go to Xcode -> Find 'Deliverfly' folder (top-left) -> right-click -> New File... -> Swift File -> name it 'Food'
- Inside the 'Food' file, follow along so that the code looks like this
- Copy the Food data.
- New File... -> SwiftUI View -> name it 'FoodPreview'
- Select 'RestaurantPreview' and 'FoodPreview' -> right click 'New Group from Selection' -> name it 'Previews'
- Inside 'FoodPreview' add the property let food: Food and add .previewData to the #Preview
- In the place for the ingredients add a Text("Standard"), which will be modified later
- Make the FoodPreview following the Figma design here (20 min)
- Check the work together (code should look like this)
- Commit [Task 6] FoodPreview
- New File... -> Swift File -> named 'Restaurant'
- Select the 'Food' and 'Restaurant' files -> right click 'New Group from Selection' -> name it 'Models'
- Create 'Restaurant' model (should look like this), edit HomeView (like this) and RestaurantPreview (like this)
- Stage & make commit [Task 7] Restaurant model
- Select 'Views' folder -> right-click -> New File... -> SwiftUI View -> named 'RestaurantView'
- Follow the figma design here (20 min)
- Check work (your code should look like this)
- Right-click on the 'Deliverfly' folder -> New File... -> SwiftUI View -> named 'Components' (code should look like this)
- Stage changes and commit [Task 8] RestaurantView
- Go to github.com -> find repository (list on left) -> click on 'Compare and pull request' (if you can't see it, then go to 'Pull Requests' -> New Pull Request (green button))
- base: develop <- compare: feature/restaurant-view
- Click on 'Create pull request'
- Click on 'Merge pull request' -> click on 'Confirm merge'
- Go to Fork -> click 'Fetch' (arrow down outline) -> go to Branches -> right-click Checkout 'develop' -> Click 'Pull' (arrow down fill)
Task | Time |
---|---|
[Task 9] Ingredient enum | 10 min |
[Task 10] FoodView | 10 min (setup) + 30 min (independently) |
Break | 10 min |
Check Work | 30 min |
Navigation Logic | 10 min |
[Task 11] Navigation | 20 min |
- Go to fork & checkout 'develop'
- Right-click 'develop' -> New Branch... -> name it feature/food-view
- Select 'Models' folder -> right-click -> New File... -> Swift File -> named 'Ingredient'
- Create 'Ingredient enum (code should look like this)
- Uncomment ingredients (command + /) in the 'Food' model (code should look like this)
- Go to 'FoodPreview' -> var hasExtras: some View -> check if the ingredients for that item is empty (code should look like this)
- Stage changes and commit [Task 9] Ingredient enum
- Select 'Views' folder -> right-click -> New File... -> SwiftUI View -> named 'FoodView'
- Setup properties (dismiss, selectedIngredients, quantity, total, food)
- Setup: @ViewBuilder func foodView(_ item: Food) -> some View and and .sheet to ScrollView (code should look like this)
- Work independently following the figma design here
- Check work together (code should look like this)
- Stage changes and commit [Task 10] FoodView
- Select the 'Deliverfly' folder -> create a new Swift File named 'Navigation'
- Inside Navigation, create a @Published var navPath, and three funcs: goTo(), goBack(), goToRoot() - code should look like this
- Inside 'DeliverflyApp' create an @ObservedObject var navigation = Navigation() and NavigationStack (with .environmentObject(navigation)) - code should look like this
- Add EnvironmentObject navigation inside 'HomeView' and go to restaurant view - code should look like this
- Add EnvironmentObject navigation inside 'RestaurantView' and go back - code should look like this
- Commit [Task 11] Navigation
- Go to github.com -> 'Compare and pull request' (or 'Pull Requests' -> New Pull Request)
- base: develop <- compare: feature/food-view
- Click on 'Create pull request'
- Click on 'Merge pull request' -> click on 'Confirm merge'
- Go to Fork -> click 'Fetch' (arrow down outline) -> go to Branches -> right-click Checkout 'develop' -> Click 'Pull' (arrow down fill)
Task | Time |
---|---|
[Task 12] Item model | 10 min |
[Task 13] Order model | 10 min |
[Task 14] ItemPreview | 10 min (independently) |
[Task 15] OrderView | 30 min (independently) |
Break | 10 min |
Check work for all tasks | 50 min |
- Go to fork & checkout 'develop'
- Right-click 'develop' -> New Branch... -> name it feature/food-view
- Select 'Models' folder -> right-click -> New File... -> Swift File -> named 'Item'
- Add properties, the code should look like this
- Stage and commit changes [Task 12] Item model
- Select 'Models' folder -> right-click -> New File... -> Swift File -> named 'Order'
- Add properties, the code should look like this
- Stage and commit changes [Task 14] Order model
- Select 'Previews' folder -> right-click -> New File... -> SwiftUI View -> named 'ItemPreview'
- Follow the figma design here
- Check the work together (later), code should look like this
- Stage and commit changes [Task 13] ItemPreview
- Select 'Views' folder -> right-click -> New File... -> SwiftUI View -> named 'OrderView'
- Follow the figma design here
- Create: OrderView
- Modify: Navigation, DeliverflyApp, RestaurantView, FoodView
- Inside 'OrderView' the code should look like this
- Inside 'Navigation' add 'case order' and additional configurations (should look like this)
- Inside 'DeliverflyApp' add 'case order...' (should look like this)
- Inside 'RestaurantView' add 'hasCartItems', 'order', init() {...}, .onChange(of: ...) {...} and 'cartIcon' (code looks like this)
- Inside 'FoodView' add @Binding var orderItems: [Item] and func addToCartTapped() (code looks like this)
- Stage and commit changes [Task 15] OrderView
- Go to github.com -> 'Compare and pull request' (or 'Pull Requests' -> New Pull Request)
- base: develop <- compare: feature/order-view
- Click on 'Create pull request'
- Click on 'Merge pull request' -> click on 'Confirm merge'
- Go to Fork -> click 'Fetch' (arrow down outline) -> go to Branches -> right-click Checkout 'develop' -> Click 'Pull' (arrow down fill)
Task | Time |
---|---|
Create Firebase Project | 10 min |
[Task 16] Setup Firebase | 20 min |
Input Data | 20 min |
Break | 10 min |
[Task 17] Fetch Foods | 30 min |
[Task 18] Fetch Restaurants | 30 min |
- Go to http://console.firebase.google.com -> Sign in
- Sign in with your account or create an account
- Go to "+ Add project"
- Enter Project name -> Deliverfly-GivenName-LastName (e.g. Deliverfly-Neli-Shahapuni) -> Continue
- Disable "Enable Google Analytics for this project" -> Create Project
- Go to fork & checkout 'develop'
- Right-click 'develop' -> New Branch... -> name it feature/firbase
- Register app
- Bundle Identifier -> go to Xode -> Deliverfly (blue top-left file) -> Signing & Capabilities -> copy Bundle Identifier
- App nickname: Deliverfly -> Register app
- Download config file
- click on: Download 'GoogleService-Info.plist'
- Find it in downloads & drag it in bottom of project files
- In Xcode -> Enable 'Copy items if needed' -> Finish
- Back to firebase -> click 'Next'
- Add Firebase SDK
- Go to Xcode -> File -> Add Package Dependencies...
- Paste this link in the top-right: https://github.com/firebase/firebase-ios-sdk -> Add Package
- Select packages:
- FirebaseDatabase
- FirebaseDatabseSwift
- FirebaseFirestore
- FirebaseFirestoreSwift
- Click 'Add Packages'
- Press 'Command + B' to build
- Add initialization code
- Go to 'DeliverflyApp' file:
- import FirebaseCore
- under the properties, paste this code (should look like this)
- Go to 'DeliverflyApp' file:
init() {
FirebaseApp.configure()
}
- Next steps
- click 'Continue to console'
- Commit [Task 16] Setup Firebase and push commit (if you receive any emails, ignore them)
- Build -> 'Realtime Database' -> click on 'Create Database'
- Realtime Database location -> Belgium (europe-west1) -> Next
- Start in test mode -> Enable
- Hover over the url and click on the "+" on the right
- Type "Foods" (don't click enter) and click on "+"
- id: 100
- name: "Double Double" (write without the quotes "")
- description: "Freshly baked buns, American cheese, two beef patties, fleshly sliced or grilled onions, lettuce, spread, and tomatoes." (write without the quotes "")
- image: doubleDouble
- price: 3.95
- ingredients
- 0: salt
- 1: patty
- 2: onion
- 3: tomato
- 4: pepper
- 5: mayo
- 6: cheese
- 7: ketchup
- id: 100
- Type "Restaurants" (don't click enter) and click on "+"
- id: 1
- name: "In-N-Out Burger"
- description: "From the first bite of your burger to your last french fry, quality is the most important ingredient at In-N-Out Burger."
- image: inNOut
- rating: 5
- time: 20
- foods
- 0: "101"
- 1: "102"
- 2: "103"
- 3: "104
- id: 1
- Click on the 3 dots in the top-right corner -> Import JSON -> upload 'data.json' from the Assets folder (can also be found here)
- Click 'Import'
- Now you have both 'Foods' and 'Restaurants' data
- Click on 'Deliverfly' folder -> Right-click 'New File...' -> Swift File -> named 'Firebase'
- Inside 'Firebase' -> fetch foods from firebase (code should look like this)
- Go to 'DeliverflyApp' and add @ObservedObject firebase, initialize it & .environmentObject (should look like this)
- Go to 'HomeView' and add @EnvironmentObject firebase. To the ScrollView add a .onAppear { ... } (code should look like this)
- Run the app (command + R) and see the log
- Commit [Task 17] Fetch Foods and push commit
- Inside 'Firebase' -> fetch restaurants from firebase (code should look like this)
- Inside 'HomeView' add ProgressView() and replace list with firebase.restaurants (code should look like this)
- Commit [Task 18] Fetch Restaurants and push commit
- Go to github.com -> 'Compare and pull request' (or 'Pull Requests' -> New Pull Request)
- base: develop <- compare: feature/firebase
- Click on 'Create pull request'
- Click on 'Merge pull request' -> click on 'Confirm merge'
- Go to Fork -> click 'Fetch' (arrow down outline) -> go to Branches -> right-click Checkout 'develop' -> Click 'Pull' (arrow down fill)
Task | Time |
---|---|
[Task 19] Place Order | 15 min |
[Task 20] OrderPreview | 10 min (Independently) |
[Task 21] HistoryView | 10 min (Independently) |
[Task 22] Fetch Orders | 25 min (Independently) |
Break | 10 min |
Check Work | 50 min |
- Go to fork & checkout 'develop'
- Right-click 'develop' -> New Branch... -> name it feature/history-view
- Go to 'Firebase' file -> add func placeOrder (code should look like this)
- Go to 'OrderView' and add @EnvironmentObject firebase. Inside 'placeOrder' add Task { firebase.placeOrder(order) } (code should look like this)
- Select 'Previews' folder -> right-click -> New File... -> SwiftUI View -> named 'OrderPreview'
- Follow the Figma design here
- Inside 'OrderPreview' follow along (code should look like this)
- Stage & commit [Task 19] OrderPreview and push commit
- Select 'Views' folder -> right-click -> New File... -> SwiftUI View -> named 'HistoryView'
- Follow the figma design here
- Inside 'HistoryView' follow along (code should look like this)
- Inside 'Navigation' uncomment 'case history'
- Inside 'DeliveryApp' add case .history: HistoryView() (code should look like this)
- Inside 'HomeView' when you click the history button, add 'navigation.goTo(view: .history)' (code should look like this)
- Stage & commit [Task 20] HistoryView and push commit
- Inside 'Firebase' add @Published var orders, func fetchOrders(), func resetOrders(), and func decodeOrder (code should look like this)
- Inside 'HistoryView' remove 'orders' and replace it with 'firebase.orders'. Inside .task call fetchOrders() and inside .onDisappear call resetOrders() (code should look like this)
- Go to github.com -> 'Compare and pull request' (or 'Pull Requests' -> New Pull Request)
- base: develop <- compare: feature/history-view
- Click on 'Create pull request'
- Click on 'Merge pull request' -> click on 'Confirm merge'
- Go to Fork -> click 'Fetch' (arrow down outline) -> go to Branches -> right-click Checkout 'develop' -> Click 'Pull' (arrow down fill)
Task | Time |
---|---|
[Bonus 1] Status | 20 min |
[Bonus 2] Discount | 40 min (Independently) |
Break | 10 min |
[Bonus 3] Flavor | 50 min (Independently) |
- Go to fork & checkout 'develop'
- Right-click 'develop' -> New Branch... -> name it feature/bonus
- Make Status enum, StatusPreview, and StatusView.
- Add StatusView(status: .success) when pressing "Place Order" in Order View.
- Add StatusPreview(status: .error) (instead of Text("No orders")) if there are no orders in the databse.
- All changes should look like this
- (optional) Make a pull-request & merge to develop.
- Check-out feature/bonus to continue
- This task is done fully independently and doesn't have a ready solution.
- Hint: Use environment object to persist the discount info across different views (similar to navigation & firebase)
- Follow the figma designs here
- This task is done fully independently and doesn't have a ready solution.
- Hint: Create a Flavor enum (similar to Ingredient)
- Follow the figma designs here