All pages
Powered by GitBook
1 of 7

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

A4: ChefOS

Original Author: Vin Bui

Midpoint Due: Sunday November 12, 2023 11:59pm Final Due: Thursday November 16, 2023 11:59pm

If you are not enrolled in the course but would still like to complete the assignments, you can download the ZIP file below (note that you will not be able to enter any Git commands). Otherwise, we will create a repository for you.

79KB
intro_ios_assignments.zip
archive
Open

Overview


In this assignment, you will be creating a recipe book app. You will be able to fetch recipes from a server, filter by category, and save them for later!

Learning Objectives


Developer Skills

  • How to organize your project directory

  • How to use Postman to test HTTP requests

  • How to read code written by other developers

  • How to read data received from the backend to structure frontend code

Course Material

  • How to set up multiple collection views and communicate between them

  • How to filter data using higher order functions

  • How to save data locally using UserDefaults

Academic Integrity


As with any other course at Cornell, the Code of Academic Integrity will be enforced in this class. All University-standard Academic Integrity guidelines should be followed. This includes proper attribution of any resources found online, including anything that may be open-sourced by AppDev. The University guidelines for Academic Integrity can be found .

This assignment can be done with ONE partner. You are also free to come to the instructors or any course staff for help. Programming forums like Stack Overflow or Hacking with Swift are allowed as long as you understand the code and are not copying it exactly. The majority of code (excluding external libraries) must be written by you or your partner. Code written through AI means such as ChatGPT is NOT ALLOWED. However, you may use these resources for assistance, although we highly encourage consulting Ed Discussion or office hours instead.

Getting Help


If you are stuck or need a bit of guidance, please make a post on Ed Discussion or visit . Please do not publicly post your code on Ed Discussion. If you are using an external resource such as Stack Overflow, keep in mind that we are using UIKit with Swift 5. If you see anything with @IBOutlet or any weird syntax, then you are most likely looking at a different version.

Grading Rubric


Due to the shrinking of the course, the features implemented up to the midpoint submission will be worth more than after.

The feedback form link is located in the section of this handout.

  • UI: implements the user interface

  • F: implements the functionality

  • EC: extra credit

Getting Started


Using Postman

You are encouraged to use to test out HTTP requests. Please take a look at the .

Using Figma

Similar to A2 and A3, we will be using Figma for the design sketches. You can find the link to the Figma . If you do not have an account, you can create one under your Cornell email. If you need a refresher, check out the .

Using Git

If you are having trouble understanding how we will be using Git in this course, please read the A1 handout under section, or visit office hours so we can assist you. As a reminder:

  1. Stage: git add .

  2. Commit: git commit -m "YOUR MESSAGE HERE"

  3. Push: git push

Cloning the Repository

Navigate to a folder on your device where you will keep all of your assignments. You can navigate to the folder using cd in Terminal.

Clone the repository on GitHub:

  • Replace NETID with your NetID

  • Replace SEM with the semester (such as fa23 or sp24)

If you have a partner, replace NETID1 and NETID2. Try changing the order if the former does not work.

If you are lost or getting any kind of error, create a post on Ed Discussion or come to office hours.

Opening the Project

Navigate to the repository located on your local computer drive. Inside of the folder NETID-a4 should contain an Xcode project called A4.xcodeproj. Open up the project.

Locating the Source Code

Once you have the project opened, on the left side of the screen you should see the Navigator which contains all of the folders and files in the directory. If not, press CMD + 0 (that’s a zero) on your keyboard. You may notice that there is less starter code than in A2 and A3. As developers, directory organization is very important! Look at A2/A3 to see how we organized our directory. Remember to use those // MARK comments!

Assignment Files


As mentioned earlier, there is less starter code. You will be required to create your own files and organize them properly. However, there are only two files provided for you.

UIColor+Extension.swift

In contrast to A3, you are free to edit this file if you want to change the colors. This file contains colors that are featured in the design. To use the colors, simply type UIColor.a4.<color_name>. It is good practice to implement the design system before starting any project, making it very easy to use throughout the entire project. Look over this file to understand how it works and keep note of the colors available for you to use.

UIFont+Extension.swift

This extension allows you to use the SF Pro Rounded font which is used in the Figma design. To use this font, simply add .rounded to the end of the UIFont. For example, you can do .systemFont(ofSize: 12, weight: .semibold).rounded.

External Libraries


The starter code should have Alamofire, SnapKit, and SDWebImage installed. To use these libraries, use the import statement at the top of the file. You are not required to use SnapKit, but it would save you a lot of time learning how to use it over NSLayout.

Source: All of the recipes used in this assignment are from .

Part I: Recipe CollectionView


Your task is to create a UICollectionView to display the recipes. We will not guide you as much as we did with the other assignments, but keep the following in mind:

  • You are not required to implement the bookmark icon until Part V, but you are free to do so now.

  • You will not be implementing the filters until Part III.

  • You will need to create dummy data. For the sake of time and convenience, I have them written out for you in this . Make sure your model aligns with the given dummy data since the JSON you will be fetching from follows this format.

While creating this assignment, I ran into a bug with the collection view. Make sure to set the collection view’s alwaysBounceVertical property to true.

Using SDWebImage

There are many ways to download images in Swift, but the easiest way in my opinion is using SDWebImage. Using this library is very simple.

  1. Import the library using import SDWebImage at the top of the file.

  2. Given a UIImageView, simply use the .sd_setImage(with: <URL>) function. Here is an example:

Once you are done, stage, commit, and push to GitHub.

Part II: Detailed Recipe View


Your task is to create a view controller representing a detailed recipe view. You will push this view controller when tapping on the collection view cell. This detailed view will be unique to the recipe.

This is very straight-forward and there aren’t any tricks. Just make sure that your Recipe model aligns with the given dummy data in this (the data type of your fields matter). Remember to use SDWebImage to download the images and to implement the correct function to handle tapping on a cell. You also need to figure out which labels will have multiple lines. Click on every single cell to check for edge cases.

Once you are done, stage, commit, and push to GitHub.

Part III: Filtering


Your task is to create a horizontally scrolling collection view that represents the filter pills as well as adding filtering functionality.

Here is a quick demo of what we’re expecting:

Handling Multiple Collection Views

The tricky part to this task is that there are now two collection views inside of this view controller. Since it’s not possible to create multiple cellForItemAt functions, for example, then you need to handle the logic within the function itself. You can do this with an if statement and checking to see if the parameter collectionView is equal to the collection view property.

Filter Collection View

  • You want the collection view to span over the entire screen’s width so the leading and trailing anchors need to equal to the parent view. To add an inset to the collection view’s content, you can configure the contentInset property.

  • There are 4 filters: All, Beginner, Intermediate, and Advanced. You can create an array of strings as the data model and use the string to configure the collection view cell which you can use a UIButton to represent.

  • If you want, you can disable the scroll indicator for a cleaner scrolling view.

Filtering Logic

  • You do not need to handle filter stacking. This is somewhat advanced so we will leave that for extra credit.

  • There are many ways to determine if a cell is selected, so I will leave this up to you to decide. Make sure that the currently selected tab is highlighted with a white text color. If you are lost and have no idea where to start, feel free to ask on Ed Discussion or come to office hours.

  • There are also many ways to change the value of the selected filter. You can configure didSelectItemAt or use delegation to communicate from the cell’s button to the view controller.

Once you are done, stage, commit, and push to GitHub.

✋🏻 This is the stopping point for the midpoint submission. We will grade you for completion based on your GitHub commit history.

No further action is required, but if you would like for us to read over it, create an Ed Discussion post. Otherwise, you can keep working.

Part IV: Fetching Recipes


Your task is to create a GET request to fetch all recipes from this API:

You can use Postman to test the HTTP request. You will need to create a NetworkManager class with a shared singleton instance. You will be using Alamofire so make sure to import this library. See the lecture, textbook, or A3 for reference.

Error handling is not required but is nice to have. You will know if you integrated it correctly if there are more recipes than the dummy data. As a reminder, the JSON uses snake_case but Swift uses camelCase.

Networking is one of the most important but difficult concepts to learn and implement. We want you to get as much practice as you can to prepare you for the Hack Challenge. If you are confused, please create a post on Ed Discussion or visit office hours.

Make sure that filtering still works properly!

Once you are done, stage, commit, and push to GitHub.

Part V: Bookmark Recipes


Your task is to implement bookmarking functionality for these recipes. You will need a way to keep track of bookmarked recipes to save them locally via UserDefaults.

  • First, figure out what data structure you will use to keep track of bookmarked recipes. Then, think of a key that you will use to access through UserDefaults.

  • Recipes that are bookmarked should have a bookmark icon in their cell. See the Figma for UI details.

  • You will need to create a UIBarButtonItem to represent the bookmark button. This button will be in the detailed recipe view on the top right corner. If the recipe is already saved, the bookmark button will be filled and tapping on it will remove it from the saved recipes.

Here is a quick demo of what we are looking for:

Once you are done, stage, commit, and push to GitHub.

✋🏻 If you reach this point, you are done with the assignment. However, feel free to challenge yourself with the extra credit features.

Extra Credit


Extra credit will only be given if the features are fully implemented. These are unordered and you can choose as many as you like.

1: Custom Back Button (+1 pt)

Your task is to create a custom back button. The has a possible design for this, but you are free to use any button you like. This should be a freebie if you finished the task in Part V.

2: Stacking Filters (+1)

Right now, you can only select one filter at a time. Your task is to allow for filter stacking. All selected filters should be highlighted and the collection view should contain all selected filters.

3: Nesting CollectionViews (+1)

Right now, you have two separate collection views: one for the filters and the other for the recipes. Because these collection views have different scrolling directions, if we wanted to make them both scrollable vertically, then we will have to nest collection views. Your task here is to nest collection views so that the filters scroll with the recipes. In other words, if I scroll up, the filters should scroll up as well while maintaining its horizontal scrolling attribute.

4: Separate Bookmark Page (+2)

Your task here is to create a page listing out all bookmarked recipes. The design is up to your creativity, but there needs to be some way to push the detailed recipe view where you can then bookmark/unbookmark. You may also need to use delegation to update this bookmark list, similar to what you did in Part V.

Once you are done, stage, commit, and push to GitHub.

Submission


  1. Double check that all of your files are properly pushed to GitHub.

  2. Clone your repository into a separate folder on your local computer drive.

  3. Run your project and make sure that your code does not crash and everything works as needed.

  4. If you are satisfied, download this TXT file and fill it out. Make sure to use the

  1. Confirm that your submission.txt is formatted like the following and submit it on .

  1. Fill out this (worth 1 point).

If you are partnered, make sure to create a group on CMS and put both names in the submission.txt file. Both students must fill out the feedback survey to receive credit.

Assignments

How to work with Git and GitHub for version control

  • How to read documentation from outside resources

  • How to format and structure your code to follow MVC design pattern

  • How to follow common styling conventions used in industry

  • How to implement designs created on Figma

  • How to represent lists of data using a UICollectionView and a UICollectionViewCell

  • How to send GET requests to a backend API using Alamofire

  • How to write callbacks (completion handlers) to handle asynchronous calls

  • How to create a NetworkManager singleton class to contain network calls

  • How to decode a JSON using a JSONDecoder in Swift

  • How to handle errors with networking calls

  • _ / 1

    F: Tapping on a Recipe cell pushes a detailed view

    _ / 1

    PART III: Filtering

    _ / 3

    UI: Collection view for filters WITH horizontal scrolling

    _ / 1

    UI: Selected filter is highlighted (separate from functionality)

    _ / 1

    F: Tapping on a filter filters the recipe data (one at at time; stacking filters is extra credit)

    _ / 1

    PART IV: Fetching Recipes

    _ / 1

    F: GET Request to Fetch Recipes

    _ / 1

    PART V: Bookmark Recipes

    _ / 2

    F: Bookmarking from the detailed view updates the collection view using delegation

    _ / 1

    F: Saved recipes are stored locally via UserDefaults (restart app to check)

    _ / 1

    OTHER

    _ / 2

    Feedback Survey

    _ / 1

    Styling: viewDidLoad calls helper functions

    _ / 1

    SUBTOTAL

    _ / 15

    EC: Custom back button

    + 1

    EC: Stacking filters

    + 1

    EC: Nesting collection views

    + 1

    EC: Separate bookmark page

    + 2

    Deduction: Crash Tax

    -1 point

    GRAND TOTAL

    _ / 15 (+5)

    We want the collection view to be scrollable even when not full. Simply set alwaysBounceVertical = true.
  • You do not have to worry about dynamic cell size. Set the text labels’ line limit to 2 lines and the height of the cell to around 216. The width, however, will depend on the size of the screen. Remember, we want to have two columns. Hint: We can multiply/divide the screen’s width by a certain factor.

  • Do not save recipe images in the Assets catalog. We will be using SDWebImage to download images from URLs.

  • You do not have to handle dynamic cell width. A height of 32 and width of 116 should work.

  • The filter collection view does not have to scroll vertically with the recipe collection view. This requires nesting collection views inside each other which is a very tedious process. You can have the recipe collection view cut off like this if scrolled:

  • To filter the array of recipes, you can use the filter higher order function. As a hint, you should have two properties containing the array of recipes: one for all recipes and another for filtered recipes.

    The bookmark icon should change immediately on press. You will also need to use delegation to reload the recipe collection view so that the cells will be properly updated. Remember to use a weak reference!

  • All saved recipes should be stored locally. You can check by restarting the app. If the saved recipes do not reset, then you are good to go.

  • Clone SSH path
    .

    PART I: Recipe CollectionView

    _ / 4

    UI: Name, Image, Time, Rating

    _ / 2

    UI: 2 columns, Dynamic number of cells (adding a new item to the array creates a new item/cell)

    _ / 1

    UI: Each cell is unique and represents a different Recipe

    _ / 1

    PART II: Detailed Recipe View

    _ / 3

    UI: Image

    _ / 1

    here
    office hours
    Submission
    Postman
    Postman guide
    here
    Figma guide
    Understanding Git and GitHub
    Figma
    allrecipes.com
    Pastebin
    Pastebin
    30MB
    a4_part5.mp4
    Open
    Figma
    129B
    submission.txt
    Open
    CMS
    feedback survey
    From the Figma Design

    UI: Name and Description

    git clone [email protected]:cs1998-601-SEM/NETID-a4.git
    # Ex: git clone [email protected]:cs1998-601-fa23/vdb23-a4.git
    git clone [email protected]:cs1998-601-SEM/NETID1-NETID2-a4.git
    // Given a UIImageView called `imageView` and a Recipe object with
    // the property `imageUrl`
    imageView.sd_setImage(with: URL(string: recipe.imageUrl))
    if collectionView == collectionViewOne {
        // Do something here for collectionViewOne
    } else if collectionView == collectionViewTwo {
        // Do something here for collectionViewTwo
    }
    https://api.jsonbin.io/v3/b/64d033f18e4aa6225ecbcf9f?meta=false
    Name: Vin Bui
    NetID: vdb23
    GitHub Repository: [email protected]:cs1998-601-SEM/NETID-a4.git
    Extra Credit:
    +1 : ____
    +1 : ____
    +1 : ____
    +1 : ____
    +2 : ____

    Hack Challenge

    Original Author: Vin Bui

    Midpoint Due: Sun Nov 19, 2023 11:59pm Final Due: Fri Dec 1, 2023 11:59pm

    Add the Google Calendar

    What is the Hack Challenge?

    The Hack Challenge is an AppDev courses tradition where students across our 4 courses (iOS, Android, Backend, and DPD) come together to create their own mobile app in 2 weeks.

    Why a Hack Challenge as a final project?

    The purpose of our courses is to help our students gain skills that they can take into industry. The best way to develop these skills is by pursuing projects, especially with a team. Additionally, you will be able to put this on your portfolio, which will be an important factor when applying for internships.

    How will the groups be assigned? Where will we find teams?

    This depends on the number of students we have across all courses. However, most teams typically consist of 2-3 frontend members, 1-2 backend members and 1 designer. We will do a team matching mixer when the Hack Challenge begins. During this mixer, you will meet students in other courses and form a team.

    Each team will also have a frontend mentor as well as a backend mentor to provide any help if needed.

    How will grading work?

    As a reminder, the Hack Challenge is worth 30% of your final grade. For iOS, you are required to have the following:

    Midpoint Submission

    • Multiple screens that you can navigate between OR at least one scrollable view.

    Final Submission

    • Multiple screens that you can navigate between.

    • At least one scrollable view.

    • Networking integration with a backend API.

    Note that you can use either UIKit or SwiftUI for the Hack Challenge.

    Do we win prizes?

    Yes! We have prizes and awards for the following:

    • 🏆 Best Overall

    • 💻 Best Backend

    • 📱 Best UI

    • 🎨 Most Creative

    Past Projects

    A1: Swift Basics

    Original Author: Vin Bui

    Assignment Due: Tuesday October 17, 2023 11:59pm

    If you are not enrolled in the course but would still like to complete the assignments, you can download the ZIP file below (note that you will not be able to enter any Git commands). Otherwise, we will create a repository for you.

    79KB
    intro_ios_assignments.zip
    archive
    Open

    Overview


    The goal of this assignment is to help you become familiar with basic Swift syntax and version control with Git and GitHub.

    Learning Objectives


    Developer Skills

    • How to implement functions according to a specification

    • How to read documentation from outside resources

    • How to read, create, and use functions to organize code

    • How to work with Git and GitHub for version control

    Course Material

    • How to use string interpolation to combine variables with strings

    • How to convert data types using type casting

    • How to create and work with arrays and dictionaries

    • How to use conditionals to control program flow

    Academic Integrity


    As with any other course at Cornell, the Code of Academic Integrity will be enforced in this class. All University-standard Academic Integrity guidelines should be followed. This includes proper attribution of any resources found online, including anything that may be open-sourced by AppDev. The University guidelines for Academic Integrity can be found .

    This assignment must be done individually. However, we do encourage limited collaboration. You are also free to come to the instructors or any course staff for help. Programming forums like Stack Overflow or Hacking with Swift are allowed as long as you understand the code and are not copying it exactly. Code written through AI means such as ChatGPT is NOT ALLOWED. However, you may use these resources for assistance, although we highly encourage consulting Ed Discussion or office hours instead.

    Getting Help


    If you are stuck or need a bit of guidance, please make a post on Ed Discussion or visit . Please do not publicly post your code on Ed Discussion. If you are using an external resource such as Stack Overflow, keep in mind that we are using UIKit with Swift 5. If you see anything with @IBOutlet or any weird syntax, then you are most likely looking at a different version.

    Grading Rubric


    The grading for TODOs 1-9 are based on the number of test cases that you pass. We will convert the values to a decimal and their sum will be your subtotal (out of 10). The feedback form link is located in the section of this handout.

    Getting Started


    Understanding Git and GitHub

    First, if you have not installed Git yet, please do so now. You can follow the guide . Then, watch this very short about Git. If you are still confused, that is totally fine. You will understand it better as you use it. For the sake of time, I will quickly go over everything about Git and GitHub that you need for this and future assignments. If you are interested in learning more in depth (highly recommended), feel free to read our guide .

    Git is a version control system. You can think of this as Google Drive but for code. Your code is stored in a “folder” called a repository. For every assignment, we will provide the repository for you. You will clone this repository from GitHub using git clone [CLONE URL]. You can think of GitHub as a library containing a bunch of repositories. Cloning a repository is like checking out a book.

    Git and GitHub are not the same. You can think of GitHub as the library that manages the Git repositories (the books). When you clone a repository, the files could be brand new or have already been modified by someone else. Think of this as checking out a book that may have already been written in by another person who previously checked out the book.

    Now, with that repository, you can do whatever you want to it— edit the files, create new files, delete old files, etc. Once you have done whatever you needed to do, you can send it back to the GitHub repository where it can store and keep track of the changes you have made. First, you need to stage your changes. In other words, tell Git what files to upload to GitHub. You can use the command git add . to stage your changes.

    Okay, so once you’ve selected the files you wanted to upload, now you need to wrap these files into a box with a message about the contents. This is known as making a commit. You are committing to send these files back to the GitHub repository. You can use the command git commit -m "YOUR MESSAGE HERE" to make a commit.

    So you’ve selected your items and wrapped it into a box with a message about the items. Now it is time to send that box to GitHub. All you have to do is type the command git push.

    That’s it! When working on these assignments, remember these 3 things:

    1. Stage: git add .

    2. Commit: git commit -m "YOUR MESSAGE HERE"

    3. Push: git push

    Cloning the Repository

    Navigate to a folder on your device where you will keep all of your assignments. You can navigate to the folder using cd in Terminal.

    Clone the repository on GitHub:

    • Replace NETID with your NetID

    • Replace SEM with the semester (such as fa23 or sp24)

    If you are lost or getting any kind of error, create a post on Ed Discussion or come to office hours.

    Opening the Project

    Navigate to the repository located on your local computer drive. Inside of the folder NETID-a1 should contain an Xcode project called A1.xcodeproj. Open up the project.

    Locating the Source Code

    Once you have the project opened, on the left side of the screen you should see the Navigator which contains all of the folders and files in the directory. If not, press CMD + 0 (that’s a zero) on your keyboard.

    If you expand everything underneath A1 you should see the following:

    You will be working on MainApp.swift and A1Tests.swift.

    Part I: Assignment Files


    MainApp.swift

    You will be implementing the functions provided in this file. There are a total of 9 TODOs. If you click on this red box at the top of your Xcode, there should be a dropdown menu.

    If you click on the clipboards, you will directed to the TODOs. The stars (⭐️) represent the difficulty level of each function. At the top of each function header is the specification. Your goal is to implement the function according to the specification. DO NOT CHANGE THE FUNCTION HEADER. We have given you hints to help you complete the tasks.

    A1Tests.swift

    This file contains the test cases for each function. DO NOT EDIT THIS FILE.

    There are two ways to run the test cases:

    1. You can run the entire test suite by clicking on the button in the blue box next to final class A1Tests: XCTestCase in the Editor or A1Tests in the Navigator on the left.

    2. You can run test cases for a specific function by clicking on the button in the blue box next to the function (such as func testIntroduce()) in the Editor or in the Navigator on the left.

    When you run the test suite for the first time, it may take about 30 seconds to 1 minute to load. After the first launch, it should not take that long. If the Simulator opens up, keep it open as it is required to run the test suite (for some reason). You will get a popup saying “Build Succeeded”, but this does not mean that you have passed the test cases. A passed test case will have green checkmarks and no error messages.

    The yellow box above indicates an error message. The value pointed by the pink arrow is the “Received” output which is what your implementation returned. The value pointed by the green arrow is the “Expected” output which is what your function should return. The console will also output the error message.

    Make sure you are using an iPhone simulator at the top of Xcode.

    Part II: Implementing the Functions


    There are a total of 9 functions that you need to implement with varying levels of difficulty (indicated by a ⭐️). Follow these steps when working on the assignment:

    1. Begin TODO 1 and implement the function.

    2. Run the test function for TODO 1. If failed, fix your function and try again. If passed, move on to the next step.

    3. Stage, commit, and push your changes to GitHub. In terminal, make sure you are in your working directory. Run these commands in the following order:

    Submission


    1. Double check that all of your files are properly pushed to GitHub.

    2. Clone your repository into a separate folder on your local computer drive.

    3. Run your project and make sure that your code does not crash and everything works as needed.

    4. If you are satisfied, download this TXT file and fill it out. Make sure to use the

    1. Confirm that your submission.txt is formatted like the following and submit it on .

    1. Fill out this (worth 1 point).

    How to use methods provided by Swift

  • How to use loops to repeat code

  • How to work with optionals

  • How to use higher order functions to simplify code

  • _ / 4

    TODO 8: uppercaseLead

    _ / 6

    TODO 9: filterImposter

    _ / 6

    Feedback Survey

    _ / 1

    SUBTOTAL

    _ / 10

    Deduction: Crash Tax

    -1 point

    GRAND TOTAL

    _ / 10

    Stage: git add .

  • Commit: git commit -m "YOUR MESSAGE HERE"

    • A good message could be “Completed TODO 1: introduce"

  • Push: git push

  • Double check on the Cornell Enterprise GitHub that your changes have been updated. If you receive an errors, create a post on Ed Discussion or visit office hours.

  • Repeat for TODOs 2-9.

  • Clone SSH path
    .

    TODO 1: introduce

    _ / 2

    TODO 2: getStudentInfo

    _ / 1

    TODO 3: countEvens

    _ / 4

    TODO 4: capitalizeStrings

    _ / 4

    TODO 5: repeatString

    _ / 4

    TODO 6: countWords

    _ / 6

    here
    office hours
    Submission
    here
    video
    here
    129B
    submission.txt
    Open
    CMS
    feedback survey

    TODO 7: containsNum

    git clone [email protected]:cs1998-601-SEM/NETID-a1.git
    # Ex: git clone [email protected]:cs1998-601-fa23/vdb23-a1.git
    Name: Vin Bui
    NetID: vdb23
    GitHub Repository: [email protected]:cs1998-601-SEM/NETID-a1.git

    FA23 Winners

    Fall 2023

    - Best Backend

    Frank Dai, Qiandao Liu, James Tu, Huajie Zhong

    • Account login and registration (with profile image)

    MapKit integration with WeatherAPI

  • Create a post and upload images

  • Like and delete a post

  • Ithaca Traveller
    Ithaca Traveller Team

    Latte Link - Best UI

    Lucy Yang, Kyle Chu, Nicole Qiu, Nathan Chu, Mihili Herath

    A scheduling app that allows Cornell students to connect with coffee chatters and arrange coffee chats from a range of campus organizations.

    • Simple yet effective user interface

    • Easy on the eyes, not too much information at once

    • Consistent design system - typography, colors, etc.

    • Lots of explorations on Figma -> seems like everything was thought through pretty well

    Latte Link
    Latte Link Team

    ShelterSwipe - Most Creative

    Ilyssa Yan, Claire Wang, Cassidy Xu, Ronald Leung, Andrew Qian, Emily Silkina

    ShelterSwipe is an application where you can swipe through pets available for adoption at local shelters. We hope to match every potential pet-owner with their perfect animal to foster loving relationships and decrease the number of shelter animals.

    • Very creative, cute, and wholesome idea

    • Have never seen a swipe gesture used in a Hack Challenge before

    • Animations when swiping was pretty sick

    ShelterSwipe
    ShelterSwipe Team

    truscoop - Best Overall

    Aidan Talreja, Peter Bidoshi, Daniel Chuang, Daniel Lee, Satya Datla

    AI news platform that determines the political meaning of the news article based on AI and user ratings.

    • Summary generated with AI using NLP (natural language processing)

    • Clean and slick/simple UI

    • Can read articles within the app using WKWebView

    • User ratings + ML generated ratings

    • Share articles

    truscoop
    truscoop Team
    Ithaca Traveller
    FA23 Winners

    A2: Profile

    Original Author: Vin Bui

    Assignment Due: Tuesday October 24, 2023 11:59pm

    If you are not enrolled in the course but would still like to complete the assignments, you can download the ZIP file below (note that you will not be able to enter any Git commands). Otherwise, we will create a repository for you.

    79KB
    intro_ios_assignments.zip
    archive
    Open

    Overview


    In this assignment, you will be creating your first ever iOS application using UIKit programmatically. You will be creating a Profile and Edit Profile page, commonly seen in many apps today.

    Learning Objectives


    Developer Skills

    • How to format and structure your code to follow MVC design pattern

    • How to follow common styling conventions used in industry

    • How to implement designs created on Figma

    • How to work with Git and GitHub for version control

    Course Material

    • How to create classes such as a UIViewController

    • How to create and customize a UIView and position them with NSLayout

    Academic Integrity


    As with any other course at Cornell, the Code of Academic Integrity will be enforced in this class. All University-standard Academic Integrity guidelines should be followed. This includes proper attribution of any resources found online, including anything that may be open-sourced by AppDev. The University guidelines for Academic Integrity can be found .

    This assignment can be done with ONE partner. You are also free to come to the instructors or any course staff for help. Programming forums like Stack Overflow or Hacking with Swift are allowed as long as you understand the code and are not copying it exactly. The majority of code (excluding external libraries) must be written by you or your partner. Code written through AI means such as ChatGPT is NOT ALLOWED. However, you may use these resources for assistance, although we highly encourage consulting Ed Discussion or office hours instead.

    Getting Help


    If you are stuck or need a bit of guidance, please make a post on Ed Discussion or visit . Please do not publicly post your code on Ed Discussion. If you are using an external resource such as Stack Overflow, keep in mind that we are using UIKit with Swift 5. If you see anything with @IBOutlet or any weird syntax, then you are most likely looking at a different version.

    Grading Rubric


    The feedback form link is located in the section of this handout.

    • UI: implements the user interface

    • F: implements the functionality

    • EC: extra credit

    Getting Started


    Setting up Figma

    You can find the link to the Figma . If you do not have an account, you can create one under your Cornell email. I will provide details on how to navigate through Figma later.

    Using Git

    If you are having trouble understanding how we will be using Git in this course, please read the A1 handout under section, or visit office hours so we can assist you. As a reminder:

    1. Stage: git add .

    2. Commit: git commit -m "YOUR MESSAGE HERE"

    3. Push: git push

    Cloning the Repository

    Navigate to a folder on your device where you will keep all of your assignments. You can navigate to the folder using cd in Terminal.

    Clone the repository on GitHub:

    • Replace NETID with your NetID

    • Replace SEM with the semester (such as fa23 or sp24)

    If you have a partner, replace NETID1 and NETID2. Try changing the order if the former does not work.

    If you are lost or getting any kind of error, create a post on Ed Discussion or come to office hours.

    Opening the Project

    Navigate to the repository located on your local computer drive. Inside of the folder NETID-a2 should contain an Xcode project called A2.xcodeproj. Open up the project.

    Locating the Source Code

    Once you have the project opened, on the left side of the screen you should see the Navigator which contains all of the folders and files in the directory. If not, press CMD + 0 (that’s a zero) on your keyboard.

    If you expand everything underneath A2 you should see the following:

    You will be working on ProfileVC.swift, EditProfileVC.swift, and Assets.xcassets.

    Assignment Files


    ProfileVC.swift

    You will be creating the main profile page in this file, primarily in Parts I and II. You are responsible for creating the UI design based on the . This view controller is the root view controller inside of a UINavigationController located in SceneDelegate.swift. You will be asked to push EditProfileVC onto this navigation stack.

    EditProfileVC.swift

    You will be creating the edit profile page in this file, primarily in Parts III and IV. You will be implementing the UI design based on the . This view controller will be pushed by ProfileVC onto the navigation stack. You will be asked to implement popping functionality as well as delegation to save changes from the text field.

    UIColor+Extension.swift

    DO NOT EDIT THIS FILE! This file contains colors that are featured in the Figma design. To use the colors, simply type UIColor.a2.<color_name>. It is good practice to implement the design system before starting any project, making it very easy to use throughout the entire project. Look over this file to understand how it works and keep note of the colors available for you to use.

    Using Figma and Importing Assets


    For the scope of this course, we will be teaching you the skills necessary to read a design implemented on Figma. This is widely used both on AppDev and in industry, so it’s important to have this skill in your toolkit. Please read over the now.

    Styling


    Throughout the provided files, you may have noticed the // MARK comments. These are used to keep the code organized.

    • Properties (View) are used for UIView objects such as UILabel, UIImageView, etc. You should mark these properties as private and make them constants (use let).

    You are not limited to these sections and are free to add more (and you should). Because many of your data properties are marked as private, you may need to create an init function.

    Follow these steps when implementing the UI:

    1. Create the view

    2. Initialize the view

    3. Constrain the view

    4. Run, confirm, and repeat

    Your viewDidLoad method should contain mostly function calls to helper functions. We will be grading you on this.

    Part I: Creating the Profile Page


    Your task is to create the UI for the main profile page in ProfileVC. This profile can be for you, your partner, or if you want you can use me (Vin). Do not worry about any functionality here. We will do that in Part II. Your profile will have the following:

    • Profile Image: UIImageView

      • You will need to add the image to Assets.xcassets. Refer to the Figma guide.

      • To get a perfect circle, set the

    Don’t forget to set the title of the view controller to “My Profile” and background color.

    Once you are done, stage, commit, and push to GitHub.

    Part II: Push the Edit Profile Page


    You task is to create the “Edit Profile” button as well as pushing EditProfileVC onto the navigation stack.

    Edit Profile Button: UIButton

    • To change the text, use setTitle(<text>, for: .normal)

    • To change the text color, use setTitleColor(<color>, for: .normal)

    • To change the background color, use backgroundColor = <color>

    Once you are done, stage, commit, and push to GitHub.

    Part III: Create the Edit Profile Page


    Your task is to create the UI for the edit profile page in EditProfileVC. Do not worry about any functionality here. We will do that in Part IV. Consult Part I for hints on how to implement these views. This page will have the following:

    • Profile Image: UIImageView

    • Name: UILabel

    • Bio: UILabel (or

    You will need to create a data property to store some information. Mark these properties as private and create an init function. Make sure to include the following line after initializing your properties: super.init(nibName: nil, bundle: nil). The values for these properties will be passed in from ProfileVC.

    If you haven’t realized it yet, for most of the setup functions you can copy and paste from the previous and make slight modifications!

    Don’t forget to set the title of the view controller to “Edit Profile” and background color.

    Once you are done, stage, commit, and push to GitHub.

    Part IV: Pop the Edit Profile Page


    You task is to create the “Save” button as well as popping EditProfileVC from the navigation stack.

    Save Button: UIButton

    • See Part II for implementation hints

    If you implemented Part II correctly, this should be as simple as copy and pasting!

    Once you are done, stage, commit, and push to GitHub.

    Part V: Delegation


    You task is to use delegation to update information from ProfileVC based on the text fields in EditProfileVC. Remember these steps:

    1. Create a protocol with a function

    2. Conform ProfileVC to the protocol (delegate)

      • Implement the function

    If you have forgotten how to implement delegation, view the lecture notes or textbook.

    To access the text from a UITextField, use the text property of the text field. Note that this gives you an optional.

    Double check that your main profile updates when you click save. Then click on “Edit Profile” again and make sure that the text fields in the edit profile page are also updated.

    Once you are done, stage, commit, and push to GitHub.

    If you reach this point, you are done with the assignment. However, feel free to challenge yourself with the extra credit features.

    Extra Credit


    Extra credit will only be given if the features are fully implemented. These are unordered and you can choose as many as you like.

    1: Custom Back Button (+1 pt)

    When using a UINavigationController, there is a default back button. However, it does not look nice with our design so your task is to customize the back button. The Figma contains the design for this feature. As a hint, the icon used is known as an SF Symbol called chevron.left. You do not need to export this icon; it is built-in.

    2: Edit Profile Picture (+1 pt)

    This one is a lot more challenging than the previous feature. Your task here is to allow the user to edit their profile picture. You can access their camera roll, photo library, or both.

    Once you are done, stage, commit, and push to GitHub.

    Submission


    1. Double check that all of your files are properly pushed to GitHub.

    2. Clone your repository into a separate folder on your local computer drive.

    3. Run your project and make sure that your code does not crash and everything works as needed.

    4. If you are satisfied, download this TXT file and fill it out. Make sure to use the

    1. Confirm that your submission.txt is formatted like the following and submit it on .

    1. Fill out this (worth 1 point).

    If you are partnered, make sure to create a group on CMS and put both names in the submission.txt file. Both students must fill out the feedback survey to receive credit.

  • How to read documentation from outside resources

  • UILabel, UIButton, UIImageView, UIImage, UITextField
  • How to navigate between view controllers using a UINavigationController and popping/pushing

  • How to use delegation to communicate between view controllers

  • How to implement design system using UIFont and UIColor

  • _ / 1

    PART III: Create the Edit Profile Page

    _ / 3

    UI: Profile Image

    _ / 1

    UI: Name, Bio

    _ / 1

    UI: Hometown and Major TextFields

    _ / 1

    PART IV: Pop the Edit Profile Page

    _ / 2

    UI: Save Button

    _ / 1

    F: Pops EditProfileVC

    _ / 1

    PART V: Delegation

    _ / 3

    F: Clicking on Save updates the main Profile page

    _ / 3

    OTHER

    _ / 2

    Feedback Survey

    _ / 1

    Styling: viewDidLoad calls helper functions

    _ / 1

    SUBTOTAL

    _ / 15

    EC: Custom back button

    + 1

    EC: Edit profile picture

    + 1

    Deduction: Crash Tax

    -1 point

    GRAND TOTAL

    _ / 15 (+2)

    Properties (Data) are used for data types such as String, Int, delegates, etc. Again, mark these properties as private but it is up to you to decide if they are constants or variables.

  • The Set Up Views section should be used for initializing your view properties.

  • layer.cornerRadius
    of the
    UIImageView
    to the radius (set it to the width of the image divided by 2) and set
    layer.masksToBounds
    to
    true
    .
  • Name: UILabel

    • You can get the colors from Figma under the “Inspect” section. To use the color, type: UIColor.a2.<color_name>

    • You can get the font weight and size from Figma under the “Inspect” section. Set the “Code” to iOS. To set the font, type: .systemFont(ofSize: <size>, <weight>). Do not use the code. You should only look at the font name and size.

      • Make sure you use the weight from the font name instead of the number. For example, even though Figma says a weight of 600, the weight should be .semibold.

    • If any of these fields are too long, you can set the numberOfLines property to 0 for unlimited lines.

  • Bio: UILabel (or UITextView)

    • To make the text italic, use: .italicSystemFont(ofSize: <size>)

  • Hometown: UIImageView for the icon, UILabel for the text

  • Major: UIImageView for the icon, UILabel for the text

  • To change the corner radius, use layer.cornerRadius = <radius>. You can get this under “Inspect > Properties” in Figma on the right hand side.

  • As a hint, you will need to add the following constraints: leading, trailing, bottom, and height (not width)

  • To add functionality to this button when tapped, use addTarget(self, #selector(<function_to_call>), for: .touchUpInside)

  • UITextView
    )
  • Hometown: UILabel for the text, UITextField for the text field

    • To set the border width, use layer.borderWidth = <width>

    • To set the border color, use layer.borderColor = <color>

      • The color must be a CGColor. Use the following line: UIColor.a2.silver.cgColor

    • To set the corner radius, use layer.cornerRadius = <radius>

    • For the text field, you will need to set following constraints: top, leading, trailing, and height (not width)

    • Creating the padding before the text inside of the textfield is not as straight forward, so it’s okay to not have it. However, if you are interested, check out.

  • Major: UILabel for the text, UITextField for the text field

  • Create a property in EditProfileVC to reference EditProfileVC (delegator)
    • Make sure it has weak before it. If this property is private, make sure to initialize it in the init function.

  • Call the function in EditProfileVC

  • Clone SSH path
    .

    PART I: Creating the Profile Page

    _ / 3

    UI: Profile Image

    _ / 1

    UI: Name, Bio

    _ / 1

    UI: Hometown and Major

    _ / 1

    PART II: Push the Edit Profile Page

    _ / 2

    UI: Edit Profile Button

    _ / 1

    here
    office hours
    Submission
    here
    Understanding Git and GitHub
    Figma
    Figma
    Figma guide
    129B
    submission.txt
    Open
    CMS
    feedback survey
    From the Figma Design

    F: Pushes EditProfileVC

    git clone [email protected]:cs1998-601-SEM/NETID-a2.git
    # Ex: git clone [email protected]:cs1998-601-fa23/vdb23-a2.git
    git clone [email protected]:cs1998-601-SEM/NETID1-NETID2-a2.git
    Name: Vin Bui
    NetID: vdb23
    GitHub Repository: [email protected]:cs1998-601-SEM/NETID-a2.git
    Extra Credit:
    +1 : ____
    +1 : ____
    this
    https://calendar.google.com/calendar/u/0?cid=MGMwMWNjNGVkM2RkNjhhMDg1ZDY3ZTBkNDkxMzgxZTNkM2RiMWVhYzQ0NmI4OWEyNTQwZjVmZWU1MTkzOWEyZUBncm91cC5jYWxlbmRhci5nb29nbGUuY29tcalendar.google.com

    A3: ChatDev

    Original Author: Vin Bui

    Midpoint Due: Tuesday October 31, 2023 11:59pm Final Due: Tuesday November 7, 2023 11:59pm

    If you are not enrolled in the course but would still like to complete the assignments, you can download the ZIP file below (note that you will not be able to enter any Git commands). Otherwise, we will create a repository for you.

    79KB
    intro_ios_assignments.zip
    archive
    Open

    Overview


    In this assignment, you will be creating a “social media” app. You will be using Alamofire to send HTTP requests to a backend endpoint to fetch information.

    Learning Objectives


    Developer Skills

    • How to use Postman to test HTTP requests

    • How to read code written by other developers

    • How to read data received from the backend to structure frontend code

    • How to work with Git and GitHub for version control

    Course Material

    • How to represent lists of data using a UICollectionView and a UICollectionViewCell

    • How to send GET requests to a backend API using Alamofire

    • How to send POST requests to a backend API using Alamofire

    Academic Integrity


    As with any other course at Cornell, the Code of Academic Integrity will be enforced in this class. All University-standard Academic Integrity guidelines should be followed. This includes proper attribution of any resources found online, including anything that may be open-sourced by AppDev. The University guidelines for Academic Integrity can be found .

    This assignment can be done with ONE partner. You are also free to come to the instructors or any course staff for help. Programming forums like Stack Overflow or Hacking with Swift are allowed as long as you understand the code and are not copying it exactly. The majority of code (excluding external libraries) must be written by you or your partner. Code written through AI means such as ChatGPT is NOT ALLOWED. However, you may use these resources for assistance, although we highly encourage consulting Ed Discussion or office hours instead.

    Getting Help


    If you are stuck or need a bit of guidance, please make a post on Ed Discussion or visit . Please do not publicly post your code on Ed Discussion. If you are using an external resource such as Stack Overflow, keep in mind that we are using UIKit with Swift 5. If you see anything with @IBOutlet or any weird syntax, then you are most likely looking at a different version.

    Grading Rubric


    The feedback form link is located in the section of this handout.

    • UI: implements the user interface

    • F: implements the functionality

    • EC: extra credit

    Getting Started


    Using Postman

    You are encouraged to use to test out HTTP requests. Please take a look at the .

    Using Figma

    Similar to A2, we will be using Figma for the design sketches. You can find the link to the Figma . If you do not have an account, you can create one under your Cornell email. If you need a refresher, check out the .

    Using Git

    If you are having trouble understanding how we will be using Git in this course, please read the A1 handout under section, or visit office hours so we can assist you. As a reminder:

    1. Stage: git add .

    2. Commit: git commit -m "YOUR MESSAGE HERE"

    3. Push: git push

    Cloning the Repository

    Navigate to a folder on your device where you will keep all of your assignments. You can navigate to the folder using cd in Terminal.

    Clone the repository on GitHub:

    • Replace NETID with your NetID

    • Replace SEM with the semester (such as fa23 or sp24)

    If you have a partner, replace NETID1 and NETID2. Try changing the order if the former does not work.

    If you are lost or getting any kind of error, create a post on Ed Discussion or come to office hours.

    Opening the Project

    Navigate to the repository located on your local computer drive. Inside of the folder NETID-a3 should contain an Xcode project called A3.xcodeproj. Open up the project.

    Locating the Source Code

    Once you have the project opened, on the left side of the screen you should see the Navigator which contains all of the folders and files in the directory. If not, press CMD + 0 (that’s a zero) on your keyboard. You should see something like this:

    Assignment Files


    There is already code written in this file. As developers, we often build on top of what others have written which is why it is important that you practice this skill. You will often see code that you have never seen before, and it is your job to understand it.

    FeedVC.swift

    This file contains the main view controller that you will be working with throughout the entire assignment. The “Create Post” cell has already been implemented but you will notice that you cannot see it. You will need to finish setting up the collection view. The lecture does not go over how to create different sections; however, the process is very similar to what we went over in lecture and we will guide you in this handout. There are TODO comments to help guide you.

    CreatePostCollectionViewCell.swift

    This file represents the cell to create a post. You are free and encouraged to look over this file to help you implement your own custom collection view cell. You can also reference the lecture or textbook chapter . In addition, you will be asked to write code to send a network request to create a post. There is a TODO comment indicating where you should implement this logic.

    NetworkManager.swift

    This file will contain the Alamofire code to send HTTP requests to the backend. Refer to the lectures or textbook chapters .

    Date+Extension.swift

    DO NOT EDIT THIS FILE! This file contains a function convertToAgo that returns a string representation of the Date object indicating how long ago this post was created. You will call this function on the property holding the post’s date when you create your custom collection view cell.

    UIColor+Extension.swift

    DO NOT EDIT THIS FILE! Similar to A2, this file contains colors that are featured in the design. To use the colors, simply type UIColor.a3.<color_name>. It is good practice to implement the design system before starting any project, making it very easy to use throughout the entire project. Look over this file to understand how it works and keep note of the colors available for you to use.

    Styling


    Throughout the provided files, you may have noticed the // MARK comments. These are used to keep the code organized.

    • Properties (View) are used for UIView objects such as UILabel, UIImageView, etc. You should mark these properties as private and make them constants (use let).

    You are not limited to these sections and are free to add more (and you should). Because many of your data properties are marked as private, you may need to create an init function.

    Follow these steps when implementing the UI:

    1. Create the view

    2. Initialize the view

    3. Constrain the view

    4. Run, confirm, and repeat

    Your viewDidLoad method should contain mostly function calls to helper functions. We will be grading you on this.

    Endpoints


    • Endpoint:

    Type
    Route
    Request Body

    Part I: Creating the UICollectionViewCell


    Your task is to create a custom UICollectionViewCell for the post. Create this file inside of the Views folder. You will need to create a struct or class (struct recommended) to represent a post. Create this file inside of the Models folder. As a reference, this is an example post object in JSON fetched from the backend.

    You will need to figure out the name and type of your properties for this object. However, the time property will be a Date object (even though it’s a string in the JSON). I will show you how to decode this in Part III.

    Because you have not implemented networking yet, you will need to create dummy data to test the UI. When creating these dummy data, you can use the code Date() for the time property. For the other fields, you can customize it however you like.

    Your custom cell class will have the following:

    • Name (”Anonymous”)

    • Date

    • Image (AppDev Logo)

    • Post message body

    Keep in mind the background color, text color, font style, corner radius, etc. You should already have practice in A2 implementing views so I will not guide you as much as A2. Feel free to Google or look at the CreatePostCollectionViewCell class as a reference. However, your custom cell class differs in that it will need a configure method. You can use the convertToAgo function for the date object and assign it to the label’s text to format the “time ago” string.

    Once you are done, stage, commit, and push to GitHub.

    Part II: Creating the UICollectionView


    Your task is to create a UICollectionView representing the feed. There is already some code written that you will need to look over. There is also a custom cell class called CreatePostCollectionViewCell that represents the “Create Post” cell already implemented for you. You will need to register and use this cell along with the other custom cell you created in Part I.

    This collection view contains 2 sections, each section containing different cell classes.

    • Similar to items, sections are zero-indexed meaning that the first section has index 0. Use this information to implement the functions required to conform to UICollectionViewDataSource, UICollectionViewDelegate, and UICollectionViewFlowLayoutDelegate.

    • When creating your FlowLayout, keep in mind the spacing between each item is 16px and between each section is 24px. To add the spacing between sections, implement the insetForSectionAt function in the

    The first section contains only 1 cell and there is no data model associated with it. Again, the custom cell class for this section is CreatePostCollectionViewCell. I highly recommend that you read and understand the code written in this class. Once you are able to see this cell in your collection view, begin implementing the second section.

    The second section contains a variable number of cells indicating that you will need a data model representing the posts. Because you have not implemented networking yet, you will need to create dummy data to test this. If you can see both sections and their cells, you should be good to go.

    Note: For the scope of this course, we will not be handling self-sizing cells. The height for each cell is fixed and there are a maximum of three lines for the post message.

    Once you are done, stage, commit, and push to GitHub.

    ✋🏻 This is the stopping point for the midpoint submission. We will grade you for completion based on your GitHub commit history.

    No further action is required, but if you would like for us to read over it, create an Ed Discussion post. Otherwise, you can keep working.

    Part III: Fetching Posts


    Your task is to send a GET request using Alamofire to fetch all posts from the backend. Currently, your posts are all hard coded dummy data. Of course, we want to be able to receive posts created by other people so we must integrate networking. In Part I, you were given an example JSON representing a post, and you created your model object based on this JSON. The reason for this is that it makes decoding the JSON received from the backend to your model very simple.

    If you have not installed Postman yet, you can install it . Read on how to use Postman for this assignment. Then, add a new GET request with the URL: https://ios-course-backend.cornellappdev.com/api/posts/. This should return a list of all posts from the backend with a 200 status code.

    Your job is to integrate these posts into the frontend. You can decode the time field to a Date object if you set the decoder’s dateDecodingStrategy to .iso8601. For example:

    Your callback (completion handler) will take in an array of Post objects ([Post]). It will also be very helpful to have proper error handling in your code. Refer to the lecture or textbook chapter .

    Once you are able to fetch all posts from the backend, your next task is to add pull to refresh to your collection view. Follow these steps:

    Once you are done, stage, commit, and push to GitHub.

    Part IV: Creating a Post


    Your task is to send a POST request using Alamofire to add a post to the backend.

    A good rule of thumb is to always use Postman before writing the code.

    1. Add a new request to your collection with a POST method

    2. Enter the URL https://ios-course-backend.cornellappdev.com/api/posts/create/.

    3. Click on the Body tab, select raw, and change the blue dropdown from “Text” to

    If successful, the server returns a 201 status code with the above JSON data representing the post that was just created. You do not need to do anything with this information for this assignment, but it is a common practice for the backend to return this data. If you fetch all posts again, either through Postman or your app, you should see the new post that you created.

    Similar to Part III, you will integrate this network call within your app. Follow these steps:

    1. Create a function in NetworkManager that uses Alamofire to make the call. Remember that this is a POST request with a request body parameter called message. Proper error handling is highly recommended!

    2. Call this function inside of CreatePostCollectionViewCell.createPost. There should be a TODO comment. As a hint, there is a text field in this class that you will need to use.

    Once you are done, stage, commit, and push to GitHub.

    Part V: Liking a Post


    Your task is to send a POST request using Alamofire to like a post.

    Before you integrate networking, configure the like button to be filled with the color ruby if the post’s liked users contains your NetID.

    Just like before, use Postman to test the backend call.

    1. Add a new request to your collection with a POST method

    2. Enter the URL: https://ios-course-backend.cornellappdev.com/api/posts/{postId}/like/

      1. Note that {postId} is the ID of the post. Use string interpolation here.

    You will use your NetID (all lowercase). If the call is successful, you should receive the updated post.

    There are many ways you can go about this. My recommendation for you is to pass a boolean to the callback to indicate whether or not the call was successful, similar to Part IV. If the call is successful, make the like button filled and increment the count by 1. Additionally, you should only be able to tap on the button if the button is not already filled red, so you will need to wrap your network request in an if statement.

    You may notice that there is a delay before the button turns red when tapping on it. In apps like Instagram, usually the UI changes even if the API call fails. However, for the sake of simplicity and grading, we want the button to only turn red if the network call succeeds.

    Once you are done, stage, commit, and push to GitHub.

    ✋🏻 If you reach this point, you are done with the assignment. However, feel free to challenge yourself with the extra credit features.

    Extra Credit


    Extra credit will only be given if the features are fully implemented. These are unordered and you can choose as many as you like.

    1: Unlike a Post (+1 pt)

    Your task is to send a POST request using Alamofire to unlike a post. This may seem similar to Part V, but it requires some additional frontend logic. When grading for this, we will unlike a post and refresh to make sure the backend is actually updated. If you try to unlike a post in which the given NetID does not already like it, you will get an error. You can test this out on Postman. The URL is https://ios-course-backend.cornellappdev.com/api/posts/{postId}/unlike/.

    2: Sort by Top/New Posts (+1)

    If you take a look at the file, you should see a design containing the text “Top” and “New”. Your task here is to sort the posts by the # of likes (top) and the most recent (new). For example, if the selected tab is “Top”, the post with the most likes will be at the top. If the selected tab is “New”, the most recent post will be at the top. Make sure that the color of the tab changes depending on what is selected.

    3: Like Animation (+1)

    Your task here is to add some animation when liking a post. You could add a scaling animation similar to most social media apps or do some other cool animation. As long as there is some animation when liking a post, you will get full credit.

    Once you are done, stage, commit, and push to GitHub.

    Submission


    1. Double check that all of your files are properly pushed to GitHub.

    2. Clone your repository into a separate folder on your local computer drive.

    3. Run your project and make sure that your code does not crash and everything works as needed.

    4. If you are satisfied, download this TXT file and fill it out. Make sure to use the

    1. Confirm that your submission.txt is formatted like the following and submit it on .

    1. Fill out this (worth 1 point).

    If you are partnered, make sure to create a group on CMS and put both names in the submission.txt file. Both students must fill out the feedback survey to receive credit.

  • How to read documentation from outside resources

  • How to format and structure your code to follow MVC design pattern

  • How to follow common styling conventions used in industry

  • How to implement designs created on Figma

  • How to write callbacks (completion handlers) to handle asynchronous calls

  • How to create a NetworkManager singleton class to contain network calls

  • How to decode a JSON using a JSONDecoder in Swift

  • How to handle errors with networking calls

  • _ / 1

    PART III: Fetching Posts

    _ / 3

    F: GET Request to Fetch Posts

    _ / 2

    F: Refresh Control

    _ / 1

    PART IV: Creating a Post

    _ / 3

    F: POST Request to Create a Post

    _ / 3

    PART V: Liking a Post

    _ / 2

    F: POST Request to Like a Post

    _ / 1

    F: ❤️ turns red if liked, # likes goes up

    _ / 1

    OTHER

    _ / 2

    Feedback Survey

    _ / 1

    Styling: viewDidLoad calls helper functions

    _ / 1

    SUBTOTAL

    _ / 15

    EC: POST Request to Unlike a Post

    + 1

    EC: Sort by Top/New posts

    + 1

    EC: Animation when liking a Post

    + 1

    Deduction: Crash Tax

    -1 point

    GRAND TOTAL

    _ / 15 (+3)

    Properties (Data) are used for data types such as String, Int, delegates, etc. Again, mark these properties as private but it is up to you to decide if they are constants or variables.

  • The Set Up Views section should be used for initializing your view properties.

  • /api/posts/{postId}/like/

    netId (String)

    Unlike a post

    POST

    /api/posts/{postId}/unlike/

    netId (String)

    Like button (use non-filled heart for now)

  • Number of likes

  • UICollectionViewDataSource
    extension.
    JSON
  • This request expects the following body:

  • (Optional) If the call is successful, clear the the textfield. You can pass true to the callback if successful or false otherwise.

  • Run the app and try to create a post. For the scope of this assignment, you do not need to have the collection view updated as soon as you create the post. However, refreshing the collection view should contain the new post.

  • Click on the Body tab, select raw, and change the blue dropdown from “Text” to JSON

  • This request expects the following body:

  • Clone SSH path
    .

    PART I: Creating the UICollectionViewCell

    _ / 2

    UI: Header (name, date, image)

    _ / 1

    UI: Post Message, Like Button, # Likes

    _ / 1

    PART II: Creating the UICollectionView

    _ / 3

    UI: Multiple sections

    _ / 1

    UI: Dynamic number of items/cells (adding a new Post to the array adds a new item/cell)

    _ / 1

    Fetch all posts

    GET

    /api/posts/

    None

    Create a post

    POST

    /api/posts/create/

    message (String)

    Like a post

    here
    office hours
    Submission
    Postman
    Postman guide
    here
    Figma guide
    Understanding Git and GitHub
    here
    here
    Figma
    https://ios-course-backend.cornellappdev.com/
    here
    this short chapter
    here
    Figma
    129B
    submission.txt
    Open
    CMS
    feedback survey
    From the Figma Design

    UI: Each cell is unique and represents a different Post

    POST

    git clone [email protected]:cs1998-601-SEM/NETID-a3.git
    # Ex: git clone [email protected]:cs1998-601-fa23/vdb23-a3.git
    git clone [email protected]:cs1998-601-SEM/NETID1-NETID2-a3.git
    {
        "id": "7m03J198pyXFBvCOLNbw",
        "likes": ["vdb23", "rs929"],
        "messsage": "Howdy!",
        "time": "2023-06-12T22:03:23Z"
    }
    let decoder = JSONDecoder()
    decoder.dateDecodingStrategy = .iso8601
    // 1. Create a UIRefreshControl view property
    private let refreshControl = UIRefreshControl()
    
    // 2. Add a function to be called as a target
    refreshControl.addTarget(self, action: #selector(fetchAllPosts), for: .valueChanged)
    
    // 3. Assign the collection view’s refresh control
    collectionView.refreshControl = refreshControl
    
    // 4. Stop refreshing after the network call is complete
    refreshControl.endRefreshing()
    {
        "message": "<Enter some message here>"
    }
    {
        "netId": "<Enter your NetID>"
    }
    Name: Vin Bui
    NetID: vdb23
    GitHub Repository: [email protected]:cs1998-601-SEM/NETID-a3.git
    Extra Credit:
    +1 : ____
    +1 : ____
    +1 : ____