Giter VIP home page Giter VIP logo

grocerylist's Introduction

GroceryList Build Status

GroceryList is a simple iPhone application built to serve two basic needs:

  1. Creating and managing a grocery list
  2. Synchronizing that grocery list between multiple people

The app also serves as an example project for a few different frameworks. It is not meant to be feature-complete, polished, or worth any kind of payment.

If you're only interested in using the app, you can jump straight to getting it built.

App icon

(Icon created by @brender.)

Synchronization

The app stores and synchronizes its grocery list using a GitHub repository, since it's easier than writing a synchronization service, and because Git and the GitHub API already support atomic changes. This also means the list is editable from the web, without any need to build a custom web app.

List Format

The grocery list repository follows a fairly simple structure. Each grocery store is represented by a text file of the same name, and those files contain newline-separated lists of grocery items.

For example, the repository could be comprised of these files:

Costco
Safeway
Target

Each file will contain items like this:

Bread
~Crackers~
Peanut butter

Item names with a tilde on either side (~Crackers~ in the above example) have been "crossed off" of the list, but not yet deleted.

The same item name may appear in multiple store files. Those separate entries will be collapsed into one visible item within the app.

Frameworks

The GroceryList app was built partly as a "real world" demonstration of several frameworks, including:

Specific libraries aside, the app also serves as a general example of functional reactive programming (FRP) and Model-View-ViewModel (MVVM) in Cocoa.

Using the App

GroceryList is a personal project, not an App Store-quality download. To actually use it, and share your list with specific people, there are a few hoops you'll need to jump through first.

Before anything else, make sure to run script/bootstrap in your local copy of the repository. This will automatically clone all submodules used in the project.

Starting the List

Since the app is built on GitHub, it requires a GitHub repository that all users (you, and anyone you want to share the list with) will have permission to push to.

First, create the repository. It can be public or private—just keep in mind the privacy setting when adding grocery items or stores.

Due to a known bug in the app, you must have at least one file in the repository before using it. You can choose to initialize it with a README, or create the file by hand (following the list format), just as long as the repository is not empty.

Finally, add anyone with whom you want to share the list as collaborators on the repository.

Creating an OAuth Application

To be able to log in through the app, it must be configured as a GitHub OAuth application. Simply register a new application, making sure to enter grocery-list://auth as the "Authorization callback URL."

After registration, you'll have to add the client ID and secret to the project's build settings.

Required Build Settings

Because the author is lazy, the project won't build until (effectively) hardcoded with certain settings. This is accomplished with a custom Xcode configuration file that is specifically ignored by Git.

In your local clone of the repository, inside the Configuration folder, create a file named UserSettings.xcconfig. In it, add a line like the following:

GCC_PREPROCESSOR_DEFINITIONS=$(inherited) GCY_LIST_REPOSITORY=username/grocery-lists GCY_CLIENT_ID= GCY_CLIENT_SECRET=

Replace the value of GCY_LIST_REPOSITORY with the actual full name of the repository containing the list you created. Fill in GCY_CLIENT_ID and GCY_CLIENT_SECRET with the details from the OAuth application you registered.

After the configuration file has been saved, you should be able to open the project and build.

Distribution

The most straightforward way to get up and running with your customized version of the app is to build it directly to the device of anyone interested in sharing your grocery list.

However, it may be easier over the long term to use a (totally optional) service like HockeyApp or TestFlight for distributing builds.

License

This project is released under the MIT license.

grocerylist's People

Contributors

jspahrsummers avatar tnm avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

grocerylist's Issues

Write a real README

Explain the project's:

  • Purpose
  • Basic functionality
  • Underlying technology
  • Grocery list format (and setting up the list repo)
  • UserSettings.xcconfig

Build errors in Xcode 5.1

Xcode 5.1 (5B130a)

$ clang --version
Apple LLVM version 5.1 (clang-503.0.38) (based on LLVM 3.4svn)
Target: x86_64-apple-darwin13.1.0
Thread model: posix

Deprecated compiler flags in .xcconfigs

clang: error: argument '-fcatch-undefined-behavior' is deprecated, use '-fsanitize=undefined-trap -fsanitize-undefined-trap-on-error' instead

In these files:

  • ./External/ReactiveCocoaLayout/External/Archimedes/Configuration/Base/Configurations/Debug.xcconfig
  • ./External/OctoKit/External/ReactiveCocoa/external/xcconfigs/Base/Configurations/Debug.xcconfig
  • ./External/OctoKit/External/Mantle/Configuration/Base/Configurations/Debug.xcconfig
  • ./External/ReactiveCocoaLayout/External/ReactiveCocoa/external/xcconfigs/Base/Configurations/Debug.xcconfig
  • ./External/ReactiveViewModel/External/ReactiveCocoa/external/xcconfigs/Base/Configurations/Debug.xcconfig

Unused consts in Mantle when compiling with DEBUG

./External/OctoKit/External/Mantle/Mantle/MTLManagedObjectAdapter.m:39:24: error: unused variable 'MTLManagedObjectAdapterErrorExceptionThrown' [-Werror,-Wunused-const-variable]`
./External/OctoKit/External/Mantle/Mantle/MTLJSONAdapter.m:19:24: error: unused variable 'MTLJSONAdapterErrorExceptionThrown' [-Werror,-Wunused-const-variable]`

I added #ifdef DEBUG to work around it quick’n’dirty

Floating point conversion error

  • ./GroceryList/GCYViewController.m:55:64: error: implicit conversion loses floating-point precision: 'double' to 'CGFloat' (aka 'float') [-Werror,-Wconversion]

Configuration file not being found

The README says to put the file in the Configuration directory of the project, but the ./Configuration/GroceryList.xcconfig includes it differently. Should be

#include "Configuration/UserSettings.xcconfig"

Error when adding/editing items

I'm receiving the following error whenever I add/edit items within a list.

Error Domain=OCTClientErrorDomain Code=667 "base_tree is not a tree oid" UserInfo=0x95ad7f0 {OCTClientErrorOAuthScopesStringKey=repo, user, OCTClientErrorHTTPStatusCodeKey=422, NSLocalizedDescription=base_tree is not a tree oid, OCTClientErrorRequestURLKey=https://api.github.com/repos/czeluff/czGroceries/git/trees, NSUnderlyingError=0x91a97a0 "Expected status code in (200-299,304), got 422"}

I am testing in the simulator, and my repo is located here. https://github.com/czeluff/czGroceries

Doesn't seem to update after creating a new item

This is such a cool project. Just what I've always wanted for dealing with my lists.

For some reason, my Simulator isn't updating the main listing when I add a new item to the list. This is what I saw after I created the item "Wheat Bread":

screen shot 2014-02-08 at 9 34 15 pm

Pulling to update didn't help. Is this lag on GitHub's side?

Initial Launch with Items already in a Store List

I created a file in my repo as suggested and added 1 item. I added "Wheat Bread," then quit the simulator and re-built & ran a debug session in the simulator. The first thing shown in the simulator was this (before I touched anything):

screen shot 2014-02-08 at 9 39 19 pm

It contains "Milk," and "Wheat Bread," but the former is hidden.

Crashes when offline

2014-01-19 19:43:07.953 GroceryList[94402:1303] Unexpected JSON for error response: (null)
2014-01-19 19:43:07.954 GroceryList[94402:1303] *** Assertion failure in __54-[RACSignal(Operations) setKeyPath:onObject:nilValue:]_block_invoke542(), /Users/stevemoser/Code/iOS/Examples/GroceryList/External/OctoKit/External/ReactiveCocoa/ReactiveCocoaFramework/ReactiveCocoa/RACSignal+Operations.m:683
2014-01-19 19:43:07.955 GroceryList[94402:1303] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Received error from <RACDynamicSignal: 0x8f90380> name: [[[RACObserve(<GCYUserController: 0x8f86fe0>, client)] -ignore: (null)] -map:] -switchToLatest in binding for key path "repository" on <GCYGroceryListViewModel: 0x8f860d0>: Error Domain=OCTClientErrorDomain Code=668 "There was a problem connecting to the server." UserInfo=0x9189680 {OCTClientErrorHTTPStatusCodeKey=0, NSLocalizedDescription=There was a problem connecting to the server., OCTClientErrorRequestURLKey=https://api.github.com/repos/stevemoser/groceryWIki?per_page=100, NSUnderlyingError=0x8f9cda0 "The Internet connection appears to be offline."}''

Question – Regarding using subscribe:nil

In GCYGroceryListViewModel.m you have this code:

[[[[self.didBecomeActiveSignal
    flattenMap:^(GCYGroceryListViewModel *viewModel) {
        return [[[[viewModel.signInAction
            signalWithValue:nil]
            ignoreValues]
            concat:[RACSignal return:viewModel]]
            catchTo:[RACSignal empty]];
    }]
    flattenMap:^(GCYGroceryListViewModel *viewModel) {
        return [[[viewModel.loadItemsAction
            signalWithValue:nil]
            concat:[RACSignal return:RACUnit.defaultUnit]]
            catchTo:[RACSignal empty]];
    }]
    take:1]
    subscribe:nil];

I'm curious in particular about the subscribe:nil. I wondered how you handled this type of need to execute some actions/signals without really needing to subscribe to their values. I was doing the same thing with subscribe:nil but felt a little dirty about it. Anything wrong with this practice?

Add screenshots to README

It ain't pretty, but it might help convey what the app does and how it flows (without doing all the nonsense that it requires to build).

Edit Item screen

Allow the names and stores of items already in the list to be edited from within the app.

Can't build with a fresh clone

Hey Justin - great app, learnt tons of RAC tricks by reading the source, but I just tried to get it running on my Mac and can't get it to compile :) / :(

I've:

  • cloned
  • created a new, non-empty repo & a new GitHub app
  • filled in the UserSettings.xcconfig file
  • ./script/bootstrap'd
  • Build

The error I get is in GroceryList-Prefix.pch - 'UIKit/UIKit.h' file not found. If I comment out that line I get the same error when it gets to MobileCoreServices.h.

I'm still new to iOS development so not sure if the error is a project config error or something on my end - any ideas?

I see that the frameworks are being included in the project settings; not sure what to do next.
grocerylist xcodeproj 2014-03-09 12-44-29 2014-03-09 12-44-39

Thanks!

List doesn't refresh

This change would appear to be the culprit. The list is loaded only once, when the repository is assigned to initially.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.