Our application aims to provide small scale businesses an outlet to recommend their products to both new and existing customers.
- Category: Shopping
- Mobile: Our application would be designed to predominately run on mobile devices.
- Story: Evaluates users grocery item requests and recommends a variety of options from different retailers.
- Market: Individuals that need a method of organizing their shopping list before going out to make purchases.
- Habit: Our application focuses on convenience and accessibility, making it a viable tool to use anytime our users require grocery items.
- Scope: Our application eventually aims to further enhance user experience by enabling more personable services. One of these services includes recommending products related to frequent purchases made by the user.
Required Must-have Stories
- The user must be able to search for items
- The user must be able to log in upon opening application
- The system must display each item's price, location, and picture
- The user must be able to create a shopping list
- The user must be able to edit and delete a shopping list
- The user must be able to add and remove items to their shopping list
Optional Nice-to-have Stories
- The user should be able to review products
- The system should be able to recommend related products
- The user should be able to customize their account
- The system should organize products into categories
- The user should be able to favorite specific products
- Login - User logs in or registers for an account
- When user opens application, the system must prompt the user to enter login credentials
- List Screen - User can manage created shopping lists
- Allows user to create new grocery lists
- Allows user to edit and delete current lists
- Search Screen - Displays a variety of potential options of item
- Permits user to view available options of required item
- Product Screen - Displays product information
- Display product's price, picture and location
- Allows user to add it to their shopping list
- Single List Screen - Displays all products from a specific list
- Allows users to add items to grocery list
- Allows users to remove items from the shopping list
- Allows users to select a product to display more information about it.
Tab Navigation (Tab to Screen)
- Lists
- Browse
Optional:
- Settings
- Favorites
Flow Navigation (Screen to Screen)
- Landing page
- Login / Signup
- Login / Signup:
- Homepage
- Homepage
- Create new list
- Access a list
- Delete a list
- Logout
- Single List Screen
- Logout
- Homepage
- Logout
- Product Screen
- Add item
- Logout
- Single List page
- Search product
- List page
- Product
- Logout
https://www.figma.com/file/uuzEEKftJPLsdXoHxjeNd8/List-App-Wireframe?node-id=0%3A1
Property | Type | Description |
---|---|---|
listID | String | Identification for one list in the various lists we use. |
listName | String | A specific name for a list in use. |
listArray | Array of products | An array of the products. |
productID | String | Every item carries an identification point of some kind. |
productPrice | Double | This is the price of the item. |
productID | String | Every item carries an identification point of some kind. |
productImage | File | This involves an image of the product. This will be found using the api. |
productName | String | This is the name of the item. |
quantity | Int | This represents the amount of a specific item the user wishes to purchase. |
caloriesVal | Int | Number of calories in a unit. |
List of network requests by screen
- Homepage:
- (GET) Retrieve all lists
let query = PFQuery(className: "Lists") //query.includeKey("author") query.includeKeys(["listid", "listname"]) query.limit = 20 query.findObjectsInBackground { (lists, error) in if lists != nil { self.lists = lists! self.tableView.reloadData() } }
- (DELETE) Delete a list
- (GET) Retrieve all lists
- Accessing API:
- (GET) Item name, ID, image
let url = URL(string: "_______")! var request = URLRequest(url: url, cachePolicy: .reloadIgnoringLocalCacheData, timeoutInterval: 10) // Insert API Key to request request.setValue("Bearer \(apikey)", forHTTPHeaderField: "Authorization") let session = URLSession(configuration: .default, delegate: nil, delegateQueue: OperationQueue.main) let task = session.dataTask(with: request) { (data, response, error) in // This will run when the network request returns if let error = error { print(error.localizedDescription) } else if let data = data { let dataDictionary = try! JSONSerialization.jsonObject(with: data, options: []) as! [String: Any] let restDictionaries = dataDictionary["_______"] as! [[String: Any]] var lists: [List] = [] for dictionary in restDictionaries { let list = List.init(dict: dictionary) lists.append(list) } return completion(lists) } } cell.productn.text = list["productn"] as? String ?? "" cell.productid.text = restaurant["productid"] as? String ?? "" if let imageUrlString = restaurant["image_url"] as? String { let imageUrl = URL(string: imageUrlString) cell.productImage.af.setImage(withURL: imageUrl!) }
- (GET) Item name, ID, image
- Create List Page:
- (POST) Create new list
let list = PFObject(className: "Lists")
list["name"] = listName.text
list["products"] = [PFObject]() //array of products
list["author"] = PFUser.current()!
list.saveInBackground { (success, error) in
if success {
print("List saved successfully") }
else{
print("Error: \(error)")
}
}
- Search Page:
- (GET) Search a product by its name
let query = PFQuery(className:"catalogItems")
query.whereKey("name", equalTo: "nameLabel.text")
query.findObjectsInBackground { (objects: [PFObject]?, error: Error?) in
if let error = error {
print(error.localizedDescription)
} else if let objects = objects {
print("Item found, found \(objects.count) unique entries of the item with the name")
for object in objects {
//Oliver note: hopefully this prints only once
print("Product name: \(Object.name), Product price: \(Object.price), Product image: \(Object.image)")
Break
}
}
}
- (POST) Add product to a specific list
let product = PFObject(className: "Products") //Oliver note: Create a new “blank” Products object
product["name"] = nameLabel.text //Oliver note: Use text input fields for the new Products object
product["quantity"] = quantity.text //Oliver note: Same thing
product["price"] = price.text //Oliver note: Same thing
selectedList.add(product, forKey: "Products") //Oliver note: append a (the new) Products object to the current shopping list
selectedList.saveInBackground { (success, error) in //Oliver note: This simply saves it…
if success {
print("Product saved successfully")
} else {
print("Error: \(error)")
}
}
*Single List Page:
- (GET) Get all products in a specific list
Let productList = selectedList["Products"] as? [PFObject] //Oliver note: return array(?) of products assigned to a specific shopping list
- (DELETE) Delete a product from a list
selectedList.remove(product, forKey: "Products")
(Specifics were done using the github repository itself.
Sprint Plan in place using GitHub project management flow. GitHub Project created (1pt) https://github.com/Tommy-Las/MobileApps-FinalProject
GitHub Milestones created (1pt) https://trello.com/b/gdfqPBj5/shoppy-board (This will be used for every sprint!) (Currently set up as issues on the repository!)
Week 1: All classes and main storyboards will be set in place.
Week 2: Implementation of API requests and progression between boards.
Week 3: Continuing to work on the progression between board and a base working version of the project.
Week 4: Polish the existing application. Deal with any existing bugs with current deployment.
GitHub Issues created from user stories (2pts) In our github project.
Issues added to project and assigned to specific team members (1pt) In our github project.
Chomp Food & Recipe Database API
- Base URL: https://chompthis.com/api/v2/
HTTP Verb | Endpoint | Description |
---|---|---|
GET | /food/branded/name.php | Get a branded food item by name. |
Sprint 11:
http://g.recordit.co/6UHWyQ7vND.gif http://g.recordit.co/8jKR94fAf0.gifSprint 12:
https://submissions.us-east-1.linodeobjects.com/ios_university/rFieX10j.gifSprint 13:
Additional changes done after Spring 14 (before Demo):
Images of items load properly, and quantities can be changed with decrement/increment buttons in Items View Controller, and as well as in a text input on Searched Product View Controller (decrement/increment buttons are here too)
Item deletion implemented