You will be creating an app that tracks the amount of time you are working on a particular job for a client to accurately invoice them for based on how much you charge per hour.
Please look at the screen recording below to get an idea of how the finished project should look and function:
Please fork and clone this repository. It contains a starter project with the storyboard already completed for you.
Be regularly committing and pushing your code as appropriate.
-
Create a new
NSObject
subclass and call itTimedTask
with (your personal 3 letter prefix at the beginning). -
In the header, create properties for the following and remember to add the
*
to the ones that need it:- The client
- The summary of the work you did
- The hourly rate charged
- The amount of hours worked
- The total
-
Think about which property attributes each of these should have and add them. For example, we can calculate the total from the hourly rate multiplied by the hours worked. We could make the total have a
readonly
property so it doesn't create a setter. Later on in the getter, you can just perform that math in the getter. Think of it as the Objective-C version of a Swift computed property. -
Still in the header, define a standard memberwise initializer that takes in the four non-read only properties.
-
In the .m file of the
TimedTask
implement the initializer by:- Calling the super initializer
- Checking if self isn't nil
- Setting the
_
version of your fourreadwrite
properties (_client
, etc.) - Returning self.
-
Implement the getter method for your total property by multiplying the timed task's hourly rate with the hours worked. This method should autocomplete if you start typing out the name of the property. For example, it should look something like this
- (double)total
.
Create a new Cocoa Touch NSObject
subclass called TimedTaskController
(again with your prefix).
-
In the header file, Create a property that is an
NSMutableArray
of yourTimedTask
s. What property attributes should this have? -
Also in the header define a
createTimedTaskWith
function that takes in each of the 4 settable properties of aTimedTask
. -
Going to the .m file of this
TimedTaskController
, call the basicinit
initializer. Follow the same pattern for implementing an initializer. Set the_timedTasks
to a new instance ofNSMutableArray
. -
Implement the
createTimedTaskWith
method. This should initialize aTimedTask
, then add it to thetimedTasks
array. Remember that there is noappend
method in Objective-C, but the function that does the same thing is called something else.
Create a new Cocoa Touch subclass of UIViewController
called TimeTrackerViewController
(with your prefix attached).
- Adopt the
UITableViewDataSource
protocol in the header file of this view controller. Protocol adoption goes in between pair of angle brackets (<
and>
) after the subclass. For example:
@interface LSITimeTrackerViewController : UIViewController <YourProtocolHere>
In the .m file of this view controller, you'll notice that there is an @interface
here as well. You will learn about these in greater detail later on, but this is where you should add the outlets to your UI elements and any other properties you'd like to be private and only accessible to this class.
-
Add outlets from the four text fields and your table view in this
@interface
. Add an action from the button in the storyboard to the@implementation
calledlogTime
. -
In the same
@interface
add a property of typeTimedTaskController
. -
In order to be able to access the
TimedTaskController
property you created, we must give it an instance of the model controller. Defining the property does not give it a value. In theviewDidLoad
, set the property to a new instance of your model controller. -
Also in the
viewDidLoad
set the view controller as the data source for the table view. -
Implement the
numberOfRowsInSection
andcellForRowAtIndexPath
methods just as you would in Swift. The cell's text label should show theTimedTask
's client, and the detail text label should show the total. Try to format the total so it has the same format as$231.40
. -
In the
logTime
action, pull out each value from the 4 text fields and pass them in to the model controller'screateTimedTaskWith
method. After that, reload the table view and set the text fields' text to be an empty string. -
Test the app to make sure it works.
- Commit your final working version with the above requirements, then add the ability to tap on a saved
TimedTask
and have it fill in the text fields to allow you to update it, making sure you do not create a new timed task.