# A3: ChatDev

{% hint style="danger" %}
**Due: Monday, April 13, 2026 11:59 pm**
{% endhint %}

{% hint style="info" %}
**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 follow the setup instructions.**
{% endhint %}

{% file src="<https://1509678725-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Lwk7443W4ukbAF9S07e%2Fuploads%2FmldAokRj80vqCMK9Ro3V%2FA3.zip?alt=media&token=5782dd3b-be22-438b-84c7-b36fdc166b70>" %}

### Setup <a href="#setup" id="setup"></a>

***

If you prefer to use your personal GitHub account instead (not recommended), please make a private Ed post and we’ll provide instructions.

Note: After your assignment has been graded, you’re welcome to copy or upload your repo to your personal GitHub for portfolio purposes.

Read these steps carefully, and reach out on ed if you encounter any problems:

**1. Go to the course organization**

Navigate to: 👉 <https://github.coecis.cornell.edu/cs1998-601-sp26>

**2. Open the template repo**

Click on:

```
a3-template
```

**3. Create your own repo**

* Click the green **“Use this template”** button
* Select:
  * **Owner:** `cs1998-601-sp26`
  * **Repository name:** `NETID-a3` (replace NETID with your NetID)
* Click **“Create repository”**
* Choose **"private"**

**4. Clone your repo**

On your newly created repo page:

* Click the green **“Code”** button
* Copy the SSH URL

Then run in your terminal (from the directory you want your files to end up in):

```
git clone <PASTE_URL_HERE>
cd NETID-a3
```

**5. Start working**

Open the project and begin coding.

**6. Save your work (commit + push)**

Whenever you make changes:

```
git add .
git commit -m "your message"
git push
```

* you can also use [**github desktop**](https://desktop.github.com/download/)**,** but we encourage you to play with the command line interface.

## Overview

***

In this assignment, you will be creating a “social media” app. You only have to worry about the UI for now!

## 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 [here](https://theuniversityfaculty.cornell.edu/academic-integrity/).

**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 [office hours](https://ios-course.cornellappdev.com/course-content/office-hours). **Please do not publicly post your code on Ed Discussion.**&#x20;

## Grading Rubric

***

The feedback form link is located in the [Submission](#submission) section of this handout.

* <mark style="color:red;">`UI`</mark>: implements the user interface
* <mark style="color:red;">`F`</mark>: implements the functionality
* <mark style="color:red;">`EC`</mark>: extra credit

<table data-header-hidden><thead><tr><th width="374"></th><th></th></tr></thead><tbody><tr><td><mark style="color:blue;"><strong>PART I: Creating the Post model</strong></mark></td><td><mark style="color:blue;"><strong>_ / 2</strong></mark></td></tr><tr><td>F: Post has all required properties (name, text, likes, timestamp)</td><td>_ / 1</td></tr><tr><td>F: Mock data created (at least 4 posts in <code>posts</code> array)</td><td>_ / 1</td></tr><tr><td><mark style="color:blue;"><strong>PART II: Building PostView</strong></mark></td><td><mark style="color:blue;"><strong>_ / 3</strong></mark></td></tr><tr><td>UI: Header (name, date, image)</td><td>_ / 1</td></tr><tr><td>UI: Post Message</td><td>_ / 1</td></tr><tr><td>UI: Like Button + Number of Likes</td><td>_ / 1</td></tr><tr><td><mark style="color:blue;"><strong>PART III: Wiring up the feed</strong></mark></td><td><mark style="color:blue;"><strong>_ / 2</strong></mark></td></tr><tr><td>F: ForEach renders posts dynamically</td><td>_ / 1</td></tr><tr><td>UI: Each cell is unique and represents a different Post</td><td>_ / 1</td></tr><tr><td><mark style="color:blue;"><strong>PART IV: Creating a New Post</strong></mark></td><td><mark style="color:blue;"><strong>_ / 2</strong></mark></td></tr><tr><td>F: post button adds a new post and adds it to the feed</td><td>_ / 1</td></tr><tr><td>F: NewPostView can modify the posts array in ContentView</td><td>_ / 1</td></tr><tr><td><mark style="color:blue;"><strong>OTHER</strong></mark></td><td><mark style="color:blue;"><strong>_ / 1</strong></mark></td></tr><tr><td>Feedback Survey</td><td>_ / 1</td></tr><tr><td><mark style="color:green;"><strong>SUBTOTAL</strong></mark></td><td><mark style="color:green;"><strong>_ / 10</strong></mark></td></tr><tr><td>Deduction: Crash Tax</td><td>-1 point</td></tr><tr><td>Deduction: Submitting Empty Posts</td><td>-1 point</td></tr><tr><td><mark style="color:green;"><strong>GRAND TOTAL</strong></mark></td><td><mark style="color:green;"><strong>_ / 10</strong></mark></td></tr></tbody></table>

## Getting Started

***

### Using Figma

Similar to A2, we will be using Figma for the design sketches. You can find the link to the Figma [here](https://www.figma.com/file/kzgaF8pBYQLgjyWDyIzKSh/A3%3A-ChatDev?type=design\&node-id=1%3A1199\&mode=design\&t=zCm1ZPIQJyLxedca-1). If you do not have an account, you can create one under your Cornell email. If you need a refresher, check out the [Figma guide](https://ios-course.cornellappdev.com/resources/tool-guides/figma).

You shouldn't worry about the extra credit frames!

### Using Git

If you are having trouble understanding how we will be using Git in this course, please read the A1 handout under [Understanding Git and GitHub](https://ios-course.cornellappdev.com/course-content/week-4-or-swiftui/broken-reference) section, or visit office hours so we can assist you. As a reminder:

1. **Stage:** <mark style="color:red;">`git add .`</mark>
2. **Commit:** <mark style="color:red;">`git commit -m "YOUR MESSAGE HERE"`</mark>
3. **Push:** <mark style="color:red;">`git push`</mark>

### Opening the Project

Navigate to the repository located on your local computer drive. Inside of the folder <mark style="color:red;">`NETID-a3`</mark> should contain an Xcode project called <mark style="color:red;">`A3.xcodeproj`</mark>. 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 <mark style="color:red;">`CMD + 0`</mark> (that’s a zero) on your keyboard.

## Extension Files

***

### `Date+Extension.swift`

**DO NOT EDIT THIS FILE!** This file contains a function <mark style="color:red;">`convertToAgo`</mark> that returns a string representation of the <mark style="color:red;">`Date`</mark> 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 [Figma](https://www.figma.com/file/kzgaF8pBYQLgjyWDyIzKSh/A3%3A-ChatDev?type=design\&node-id=1%3A1199\&mode=design\&t=zCm1ZPIQJyLxedca-1) design. To use the colors, simply type <mark style="color:red;">`UIColor.a3.<color_name>`</mark>. 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.**

<figure><img src="https://1509678725-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Lwk7443W4ukbAF9S07e%2Fuploads%2Fq5I0dUR2sGvei9vwAJJl%2FUntitled.png?alt=media&#x26;token=0d1e2ed0-6665-44de-8807-4e4392a9cb82" alt="" width="226"><figcaption><p>From the Figma Design</p></figcaption></figure>

## Part I: Creating `Post` Model

***

Your first task is to define the `Post` model in `Post.swift`.

You'll notice the struct already has `let id = UUID()` and conforms to `Identifiable`. This is required so that SwiftUI can uniquely identify each `Post` when rendering a list, each post automatically gets its own unique ID.

You will need to add properties for the post's name, body, likes, and timestamp. You must figure out the appropriate type for each property. However, the timestamp property should use the `Date` type. Calling `Date()` returns the current date and time at the moment it's created. For example:

```swift
let now = Date() // captures the current date and time
```

To display a `Date` as a human-readable relative string (e.g. "10 min. ago"), use the provided `convertToAgo()` extension:

```swift
someDate.convertToAgo() // → "10 min. ago"
```

Because you have not implemented networking yet, you will need to create dummy data to test the UI. When creating your mock posts, use `Date()` for the timestamp. For the other fields, you can customize however you like. Create at least 4 mock posts and store them in the `posts` array in `ContentView`.

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

## Part II: Building `PostView`

***

Your task is to build `PostView` in `PostView.swift`. This view represents a single post in the feed.

`PostView` should accept a `Post` as a property (input) and display the following:

* Name (e.g. "Anonymous")
* Profile Picture (you can use any image you like! Either import it through the asset library, or use a system image)
  * Look at [SF Symbols](https://developer.apple.com/design/human-interface-guidelines/sf-symbols) where you can find system images (or ask AI)
  * This image will be identical for all posts (that's why our post model doesn't include it)
* Timestamp: use the provided `convertToAgo()` function on your `Date` property to format it as a relative time string (e.g. "10 min. ago")
* Post message body: limit to 3 lines of text
* Like button: use a non-filled heart icon (`Image(systemName: "heart")`) for now
* Number of likes

Use the provided color extensions for styling. Colors are accessed via `Color(UIColor.a3.ruby)`, `Color(UIColor.a3.white)`, `Color(UIColor.a3.silver)`, etc. Keep in mind the background color, text color, font weight, corner radius, and padding. Look at `NewPostView` as a reference for styling conventions.

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

## Part III: Wiring Up the Feed

***

Your task is to connect everything together in `ContentView`.

There is already some code written that you will need to look over. `NewPostView` represents the "Create Post" card and is already implemented for you. Read and understand the code written in this view.

1. Consider making posts something that SwiftUI can observe so updates propagate automatically.
2. Pass the corresponding `Post` to each `PostView`.
   1. Hint: go through wednesday's demo if you get stuck
3. Make sure posts are showing up correctly
   1. add/delete posts from the array, does it behave as expected?

If you can see the `NewPostView` at the top followed by your list of mock posts, you should be good to go.

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

## Part IV: Creating a Post

***

Your task is to hook up the "Post" button in `NewPostView` so that it creates a new post and adds it to the feed. We need this post to NOT be empty. You will lose 1 point if you can submit empty posts.

Think about the following as you work on this:

* How can `NewPostView` let the parent view know when a new post is added? (think about property wrappers)
* When creating `NewPostView` in the parent, how can it stay in sync with the parent’s list of posts?
* What should happen when the user taps “Post” so the feed updates correctly and the input is ready for a new post? (how do we add an element to an array?)
* How can the button know when it should be active or disabled? (should I be able to submit empty posts?)
  * Use this modifier `.disabled(Boolean_Value)` on the button (disables the button if `Boolean_Value == true` )

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 **Clone SSH path**.

{% file src="<https://1509678725-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-Lwk7443W4ukbAF9S07e%2Fuploads%2FSmSuQsq97Yp51Vwk2QOD%2Fsubmission.txt?alt=media&token=a08d3c7d-3bb2-401b-bb94-be7481c896f2>" %}

5. Confirm that your <mark style="color:red;">`submission.txt`</mark> is formatted like the following and submit it on [CMS](https://cmsx.cs.cornell.edu/web/guest/).

```
Name: Vin Bui
NetID: vdb23
GitHub Repository: git@github.coecis.cornell.edu:cs1998-601-fa23/vdb23-a3.git
Extra Credit:
+1 : ____
+1 : ____
+1 : ____
```

6. Fill out this [feedback survey](https://docs.google.com/forms/d/e/1FAIpQLSf-82p3c7K85EZqG6-cSB-jASQvrT7-I8Dcr_i_99EASST6EQ/viewform?usp=sharing\&ouid=118188825185295730350) (worth 1 point).

{% hint style="info" %}
**If you are partnered, make sure to create a group on CMS and put both names in the&#x20;**<mark style="color:red;">**`submission.txt`**</mark>**&#x20;file. Both students must fill out the feedback survey to receive credit.**
{% endhint %}
