Milestone requirements can also be found in the Group Project page.
Unit 5 - Building Instagram Part 1
Overview
In this unit, you'll be building the first part of an instagram-like app that allows users to take and post pics. You'll setup and utilize a custom backend database using Parse to store and retrieve user posts.
Here's What You'll be Building
Assignment 5 - Instagram Part 1
Build the first part of an instagram-like app that allows users to take and post pics. More details in the Assignment Tab

Lab 5 - Yelpy Chat
Implement chat feature into our Yelpy app to talk with other people using parse server backend!
More details in the Lab Tab

Lesson Slides
Session Recordings
Group Milestone Requirements (10pts)
A complete Group Milestone must have the following items. Submit your Group Milestone at the top of this page.
- Creation of GitHub Organization and Group Project Repo (2pt)
- Using the Unit 5 Group Milestone README Template as a starting point, update your Group Project
README.mdwith the following items. (Example README for reference)- App Overview: Description and evaluation (Mobile, Story, Market, Habit & Scope) (3pts)
- App spec: user stories, screens & navigation flows (3pts)
- Updated group info in the Course Portal: Group Name + App Description. (2pt)
Group Activity - Product Spec
In this activity, you'll meet with your group to decide on the app idea you want to move forward with. Once your app idea is finalized you'll get started on designing your product spec. This is about working with your team to define "What does our app do?" -- Screens, Navigation Flows and User Stories are all different aspects of describing how your app behaves and defining the things your app does from a user perspective. Everything from, logging in to posting new content can be represented as user stories.
Activity Agenda (60 min)
- Meet your group!
- Finalize your app idea
- App evaluation attributes (Mobile, Story, Market, Habit & Scope)
- Design a product spec
- Create a GitHub Organization and project repo
- Update group GitHub repo README to include product spec
- Update your app info in the course portal
1. Meet Your Group
If you're meeting with your group for the first time, take a few minutes for everyone to introduce themselves and get to know each other.
2. Finalize your app idea
The group formation postings included an app idea which was the app idea your group had most in common. This app idea is only a suggestion to get the conversation started, your group can use that app idea or come up with an entirely new one. However, keep in mind that you only have this week and the next for the app design phase so you'll want to finalize an app idea ASAP in order to move forward with the rest of the design steps and activities.
Come up with your top 3 app ideas and as a group, finalize the app you think would be the most fun to design and build, keeping in mind the framework for evaluating apps introduced in the App Brainstorming Guide.
3. Evaluate your app
- Create a HackMD document for your group to collaborate on. Share the link with each group member.
- Copy/paste the contents of the Unit 8 Group Milestone README Template into your group's shared HackMD document. Update each section as you work through each activity in this session. In the end, you'll copy/paste this doc into your Group Project's README.
- Add the name of your and and write up a general description of your app.
- Apply the Evaluating Ideas Protocol from the App Brainstorming Guide to your app and record your answers respective section of the HackMD. Here's an example.
4. Design your product spec
- Reference the Product Spec Guide for a detailed overview and example of a product spec.
- As a team, work through the following three aspects of the product spec, filling out the respective sections of your HackMD doc.Check out this Product Spec Intro & Demo Video for a detailed walkthrough of the process.
User Stories
Think of your user stories in 2 categories, required and optional. Required user stories should include only the most essential features your app needs to "do it's thing". This is what is known as a Minimum Viable Product or MVP. Optional user stories are any features that would enhance your app and would be really "nice to have", but are not absolutely essential for the main objective of your app.
Screens
Every app is composed of many different screens. Based on your required user stories, the next step is identifying the core screen archetypes, the different screens your app will need in order to function.
Navigation Flows
Next we want to take our screen archetypes and required user stories and define the navigation within our apps. This includes both the tabs in your app bar, and the flows from one screen to another.
Be sure to check out the product spec guide here for an example of each step of this process.
5. Create Group GitHub Organization
As you know, GitHub is an online platform that allows teams to collaborate for project and software development. In this section, you will create an organization for your group and then create a repo to manage your project.
- Designate a group member to create an organization on Github
- Choose a name for your organization.
- Select the Free plan.
- Invite each group member to the organization, making sure they have write access permissions.
- Create a new repo
- Choose a name for your repo
- Choose, "initialize with README"
6. Update Group Project README - App Description & Spec
Copy/paste the contents of your group's HackMD doc from this activity into your GitHub README. Check out this Unit 8 Example README for reference.
7. Update Group Info - Course Portal
Follow this Update Group Info Guide to update your group's information on the course portal. Update your group info anytime your app's name or description change or after your build to add your demo video.
Parstagram Part 1
Overview
Build an Instagram-like client with a custom backend server that allows users to post photos and view their feed.
Required User Stories
- User sees app icon in home screen and styled launch screen.
- User can sign up to create a new account.
- User can log in.
- User can take a photo, add a caption, and post it to the server.
- User can view the last 20 posts.
Bonus User Stories
- User can pull to refresh.
- User can load past photos infinitely.
Let's Get Building!
Now that we know what user stories we need to build, it's time to start actually building something! Complete each required user story below by clicking on its walkthrough video and following along.
- Download the Parstagram image assets: instagram_assets.zip
Required User Stories
1. Parstagram Overview
Introduction Video
2. Setup Parse Server
Setup Cocoapods and follow the guide below to setup your own Parse Server on Back4app, and configure your iOS app to communicate with your server.
-
Set up dependencies β-> Setting up Cocoapods
-
Before you move on, make sure your Podfile looks something like this:
target 'MyApp' do ... # Add Parse pods and install pod 'Parse' pod 'AlamofireImage' end -
Next, you will no longer be working on same project file. You will be working on the
.xcworkspacefile from now on: -
-
- Set up Parse Server --> Parse Setup Guide
3. Signing up and Logging In
Follow the video below to learn how to authenticate with Parse.
Walkthrough Video
Reference links
4. Posting a Photo
Follow the videos below to launch the camera on the simulator or phone, and allow the user to create a new post with the picture and a caption.
Walkthrough Videos
Launching Camera
Saving the Post
βοΈ at 8:35 - 9:20 in this video, you'll need to replace the instructor's Line 30 with the following updated line of code:
let file = PFFileObject(name: "image.png", data: imageData!)
5. Loading the feed
Follow the video below to query Parse for posts, and display them in a table view. Note, for the final step, you'll have to configure your iOS app to allow downloading of non-secure (http) images. The relevant reference link is included below.
Walkthrough Video
β NOTE: On 19:00 in the video, it won't be necessary to update your App Transport Security (ATS) settings anymore due to recent updates π. Also, cell.posterView.af_setImage is deprecated (old syntax). To fix this warning, make sure to change it to cell.posterView.af.setImage
1. Push your project to GitHub
Congratulations π, you've completed all the required user stories for this project! Check out the following walkthrough videos in order to push your project to GitHub and prepare it for submission.
- Push your project to GitHub βοΈ Use this Unit 5 Assignment - README Template in the above Adding a README step.
π‘ Stuck using Xcode Git Tools? Check out our new tutorials for using tools like GitHub Desktop or through Good'ol terminal + Git commands!
7. Submit your assignment
Now that your project is pushed to GitHub with a README and GIF, the last step is to submit your project to us for review. Here's how to submit your assignment:
- Scroll up to the top of this page and click the Submit button at the upper right.

- Complete the submission form as follows and click Submit.

π WHOOP WHOOP!!! At this point your submission is complete! π
Bonus User Stories
Click to see!
1. User can pull to refresh
- Reference guide: Using UIRefreshControl
2. User can load past posts infinitely
When the user scrolls down and reaches the bottom of the feed, the app should fetch older posts. The user should be able to scroll through all past posts.
- Walkthrough Video - Implementing loading more tweets (use the same technique for Parstagram)
Some other ideas for your app
These following is just for inspiration and to explore some additional feature possibilities. Please note that we don't have explicit resources or instructions for these features.
- Style the login page to look like the real Instagram login page.
- Style the feed to look like the real Instagram feed.
- User can use a tab bar to switch between all "Instagram" posts and posts published only by the user. AKA, tabs for Home Feed and Profile
- Add a custom camera using the CameraManager library.
- Show the username and creation time for each post
- Hint: If you use TableView Section Headers to display the the username and creation time, you'll get "sticky headers" similar to the actual Instagram app.
- After the user submits a new post, show a progress HUD while the post is being uploaded to Parse
- User Profiles:
- Allow the logged in user to add a profile photo
- Display the profile photo with each post
- Tapping on a post's username or profile photo goes to that user's profile page
- Run your app on your phone and use the camera to take the photo
- NOTE: Make sure to configure your privacy settings to allow taking pictures on a real device:
- Configuring app privacy settings for camera
- Additional camera on real device tutorial
- Add push notifications to your app!
Helpful Pods
-
Custom Camera
- Allows for incorporating camera functionality into any view. This would allow you to create a custom camera experience you can style like the the Instagram camera or any way you want!
-
TextView with Placeholder
- The UITextView allows for multi line input but lacks the ability to add placeholder text. After adding this pod, you can select any regular UITextView in the storyboard and change class to
RSKPlaceholderTextView. You will then have the ability to add text placeholder text to the text field in Interface Builder.
- The UITextView allows for multi line input but lacks the ability to add placeholder text. After adding this pod, you can select any regular UITextView in the storyboard and change class to
Lab 5 Yelp Chat
Parse Chat
In this lab you will build a chat client using Parse to explore the features of its ORM and backend service. We'll explore how to authenticate a user, design schema, and save and retrieve data from a Parse server.
At the end of the exercise your app will look like this:
Getting Started
- The checkpoints below should be implemented using the Pair Programming method
Milestone 1. Project Setup and Initialize Parse π·β
- Use the Yelp Project Starter.
- If you want to build off your old project you will need to implement a Tab Bar, Login View, and a Chat View along with their associated files to use them.
- AppDelegate
- SceneDelegate
- LoginVC
- ChatVC
- In this lab, we'll be sharing a Parse Server that has already been created for us. To use this account, the
applicationIdandserverare provided in the code snipped below:-
In any Swift file that you're using Parse, add
import Parseto the top of the file. -
In the AppDelegate, register Parse in the
application:didFinishLaunchingWithOptions:method:Parse.initialize(with: ParseClientConfiguration(block: { (configuration: ParseMutableClientConfiguration) in configuration.applicationId = "CodePath-Parse" configuration.server = "http://45.79.67.127:1337/parse" }))
-
Milestone 2: Login and Sign Up βοΈ
- New user can tap "Sign Up" button to sign up
Sign Up
In the sign up function we need to check to see that is the username and password is not empty. Once this is verified we need to store the user info to the PFUser() by setting the username and password attributes. Next we can pass the user info to the newUser.signUpInBackground
Log In
Existing user can tap "Login" button to login this function will follow a similar format to the sign up function. First we will set the user info and pass it in to PFUser.logInWithUsername
User sees an alert if either username or password field is empty when trying to sign up
- π‘ Use the
isEmptyproperty of a text field's text to check if it's empty. Use the||operator to require one condition or the other.
User sees an alert with error description if there is a problem during sign up or login
Milestone 3: Display the chatView πΌ
Because we only want to display the login screen when the user first signs in and we dont want to display a back button on all the views we will go into the SceneDelegate.swift and control all the scenes.
- Create a listener
In the scene function lets add a listener for when the user logs-in and lets have it call a function called login() when we receive a notification
- Change the view
After a successful sign up or login from the Login View, we need to change the view programmatically.
Milestone 4: Send a Chat Message π¬

The Chat Screen will allow the user to compose and send a message.
- We will need an array to store our messages and a chat message object
var messages: [PFObject] = []
- When the user taps the "Send" button, create a new Message of type PFObject and save it to Parse
-
Use the class name:
Message(this is case sensitive).let chatMessage = PFObject(className: "Message") -
Store the text of the text field in a key called
text. (Provide a default empty string so message text is nevernil)chatMessage["text"] = chatMessageField.text ?? "" -
Call
saveInBackground(block:)and print when the message successfully saves or any errors.chatMessage.saveInBackground { (success, error) in if success { print("The message was saved!") } else if let error = error { print("Problem saving message: \(error.localizedDescription)") } } -
On successful message save, clear the text from the text chat field.
-
Milestone 4: View a List of Chat Messages
- Setup the a TableView to display the Chat Messages
- Add a tableView to the Chat View Controller and a custom cell that will contain each message.
- For now, the cell will only contain a UILabel (multi-line) for the message.

- For now, the cell will only contain a UILabel (multi-line) for the message.
- Create a new file for the custom cell, "ChatCell" as a subclass of UITableViewCell and associate it with the Chat Cell in storyboard.
- Set the "Reuse Identifier" to "ChatCell".
- Create an outlet for the table view and set it's delegate property.
- Declare the Chat View Controller to be a
UITableViewDataSourceand conform to the data source protocol by implementing the required methods.
- Add a tableView to the Chat View Controller and a custom cell that will contain each message.
- Pull down all the messages from Parse:
-
Create a refresh function that is run every second.
-
Query Parse for all messages using the
Messageclass. -
You can sort the results in descending order with the
createdAtfield.query.addDescendingOrder("createdAt") -
Once you have a successful response, save the resulting array,
[PFObject]in a property (instance variable) of the Chat View Controller and reload the table view data.
-
Milestone 5: Associating Users with Messages
-
When creating a new message, add a key called
userand set it toPFUser.current() -
Add a
usernamelabel to the Chat cell to display the chat message author's username.

- Note: You will need to adjust the autolayout constraints and cell layout to accommodate the username label. Try removing the chatTextLabel's top constraint to the cell content view and then creating a new top constraint to the username label. You can then pin the username label's leading, top and trailing constraints to the cell's content view.
-
When querying for messages, add an additional query parameter,
includeKey(_:)on the query to instruct Parse to fetch the related user.query.includeKey("user") -
In cellForRow(atIndexPath:), if a chat message has the user property set, set the username label to the user's username. Otherwise
if let user = chatMessage["user"] as? PFUser { // User found! update username label with username cell.usernameLabel.text = user.username } else { // No user found, set default username cell.usernameLabel.text = "π€" }
Milestone 6: Persist Logged in User
-
On app launch, if current user is found in cache, user is taken directly to Chat Screen
- In the SceneDelegate, check if there is a current logged in user in the scene function .
- Parse automatically caches the current user on sign up or login. The current user can be accessed using,
PFUser.current()
- Parse automatically caches the current user on sign up or login. The current user can be accessed using,
- In the SceneDelegate, check if there is a current logged in user in the scene function .
if PFUser.current() != nil {
login()
}
-
Programmatically load the Chat View Controller and set as root view controller.
let storyboard = UIStoryboard(name: "Main", bundle: nil) let chatViewController = storyboard.instantiateViewController(withIdentifier: "ChatViewController") window?.rootViewController = chatViewController
Optional Stories
-
Create a Setting page where a user can logout
-
User sees an activity indicator while waiting for authentication.
-
User can pull to refresh Chat feed
-
Add an "Adorable Avatar" for each user by requesting an avatar from the Adorable Avatars API.
- Pass in the username in the url
- Install the AlamofireImage Pod and use the
af_setImage(withURL:)UIImageView instance method to fetch and set the image at the specified url.
-
Chat Bubble Style Design
-
Remove table view row outlines in viewDidLoad()
tableView.separatorStyle = .none -
Add a view to serve as your speech bubble. Move the label as a subview of the bubble view and re-do autolayout constraints
-
Set desired color (In code or IB)
-
Configure rounded edges in code.
bubbleView.layer.cornerRadius = 16 bubbleView.clipsToBounds = true
-

-