Skip to content

leopic/CountItApp

 
 

Repository files navigation

Banner Build Status codecov.io GitHub license

Count It

Never lose the count again. Dead simple App with Apple Watch integration that lets you count anything.

  • Laps while exercising.
  • How many beers you drink at the pub.
  • Days since you quit smoking.
  • Glasses of water you drink during the day.
  • People that enter your restaurant or club.
  • Sheep while you sleep 😜

Count It has two way communication between the App and the Watch, meaning that you can start your count on your Watch and continue it on your Phone and vice versa.

Tapping anywhere on the App or Watch face adds to the counter and gives you haptic feedback. You don't have to look at your Watch while counting!

To decrement or clear the counter, force press on your watch face.

Includes a watch complication and glance that lets you easily check and access the count.

You can also modify the look to several color options to fit your style.

The step count can also be modify so you can count in higher numbers not just one by one.

DownloadAppStore

Screenshots

Watch Screenshots

The Code

The idea of the app was to just play with WatchKit 2 and try to create something in a couple of days.

Perhaps, one of the most interesting parts its the two way communication between the App and the Watch.

TwoWayCommunication

All of these is wrapped into the WatchSessionManager.swift.

ApplicationContextChangedDelegate is use as a delegate pattern to let other objects 'register' to events from the WCSession.

//Add view model to the datasource delegate so we get application context changes
       watchSession.addDataSourceChangedDelegate(self)

This is the only thing something like a ViewModel will need to register to these events.

View Models

MVVM is use throughout the app. All of this ViewModels classes are shared along the iOS and Watch targets.

This makes it extremely easy to setup things like Glances and Interface Controllers in the WatchKit side of things.

All ViewModels expose RxSwift observables in the form of Drivers that are perfect to use in ViewModels because they:

  • can't error out
  • observe on main scheduler
  • sharing side effects (shareReplayLatestWhileConnected)

ViewControllers can later connect to this drivers and update UI Elements, for example:

viewModel.clickerCountDriver?
         .map { $0.description }
         .driveNext{ [weak self] count in

          self?.updateCountLabelWithAnimation(count)

         }.addDisposableTo(disposeBag)

This will update the counter label with an animation to latest information.

Data Storage

NSUserDefault is use as the Datastore since the data is really simple. All Model objects implement NSCoding and are saved by using the NSKeyedArchiver.

let data = NSKeyedArchiver.archivedDataWithRootObject(object)

defaults.setObject(data, forKey: key)

defaults.synchronize()

Protocols

There are several protocols like Dictionable and Timeable that encapsulates some good amount of functionality, making it very easy update models objects.

TODO

  • Set a Goal of counts, so when you know when you are near your Goal
  • Add a invert color option, so the numbers will show in color and use a black background.
  • Better code coverage
  • Improve animations on Watch
  • Watch UI Testing (Not supported by Apple)

👽 Author

Chris Jimenez - http://chrisjimenez.net, @chrisjimeneznat

License

Count It is released under the MIT license. See LICENSE for details.

About

Count It, Never lose the count again

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • Swift 85.8%
  • HTML 9.3%
  • Ruby 4.9%