iPhone Programming Tutorial – Creating a ToDo List Using SQLite Part 4

September 22nd, 2008 Posted by: (ELC) - posted under:Tutorials

This is the final installment of our 4 part series of creating a Todo list for the iPhone.  In this tutorial, I will detail how to add and delete new todo objects from the SQLite database.  Make sure that you have completed the following tutorials before you begin this one:

When you have completed this tutorial, you should have a main screen that looks something like this:

Let’s get started…

The first thing we need to do is add the UIBarButtonItem items to the NavigationBar so that we get the “Edit” and “Add” button.  Open up RootViewController.m and add the following code to the viewDidLoad method.

The first thing we see is the line that sets the leftBarButtonItem to self.editButtonItem.  This automatically adds the “Edit” button to the NavigationController.  Also, it sets up the functionality that allows the “delete” buttons to be displayed when the button is pressed.  You can see this functionality if you do a “Build and Go” at this step.  Next, I have manually created a UIBarButtonItem and added it to the navigationbar.  This can be done in Interface Builder, but I wanted to show you how to do it manually and assign an action to it (I’m sure you will require this functionality in a future program).  Here is a break down of the parameters:

  • initWithTitle – The text to be displayed on the button
  • style – How the button will look
  • target – The class object that handles the messages sent from this button
  • action – The method to be called when the button is passed.  We can use @selector and give it the name of the function to call.

Finally, we assign this button to the rightBarButtonItem.  If you do a Build and Go, it should error since we haven’t created the addTodo method. We will do that in a bit.  Now, let’s create a method inside of our Todo object that will add new Todos to the database.

Open up Todo.h and add the following code:

So in addition to the insertNewTodoIntoDatabase method, we also see the deleteFromDatabase method signature.  I have just added this so I don’t have to come back to it later.  We will be implementing this when I show you how to delete todos from the database.  One thing to note about the insertNewTodoIntoDatabase method is it has a “+” rather than a “-” sign.  This means that it is a static method.  Static methods are associated with the class not the instance meaning we can call this method without instanciating this class.  So we can do stuff like Todo.insertNewTodoIntoDatabase.  Now we will implement this method.

Before we can do this, we must declare a few more static sqlite3_statement’s.  Add the following statements to the top of Todo.m

Nothing new here…Now implement the following method:

This is similar to our update method.  Notice that we are inserting default values into the database.  This is so we don’t run into any problems with null or nil values.  The most important part of this method is the fact that it returns the primary key of the newly created todo object.  This will be used later so we can immediately transition to the todo when the “Add” button is pressed.  The last thing we need to do to the todo object is update the dehydrate method so that the todoText gets saved if it gets changed.  Update the dehydrate method to look like this:

There are only a few minor changes here.  First we see the “text = ?” part added to the sql statement.  This is simply so we can update the text of the todo.  The other change is we bound the self.text property to the 1st question mark in the sql statement.  One thing to notice is we call [self.text UTF8String].  This is because sqlite3_bind_text takes a (char *).  This will convert an NSString to an acceptable format.

Now we need to add a method inside of our RootViewController to add a todo.  This is the method that will be called when the user presses the “Add” button.  Inside of RootViewController.m add the following code:

First, we get a reference to the appDelegate object.  This is because we need to call its addTodo method.  Next, we instantiate the TodoViewController if it has not already been instantiated.  We need this around because we will push it on to the view stack and transition to it after we create our new todo object.  After this is done, we call the addTodo method of the appDelegate.  It will return the newly created todo object and the view will be transitioned to its detail screen in order to update its details.  Now we need to implement the method addTodo inside of our appDelegate.  Open up todoAppDelegate.h and add the following code to create the method signature.

Now, let’s implement this method.  Open up todoAppDelegate.m and add the following code:

First, we are calling the insertNewTodoIntoDatabase method of the Todo object.  Notice that we are simply calling the method without first building an instance of a todo object.  As I said in tutorial 3, this is because that method is static and gets called without building an instance of the class.  Next, we insatiate the todo object that was just created by calling its initWithPrimaryKey method.  This will give us reference to the new todo object.  Finally, we append this todo to the end of our todos array.  Since our UITableView is updated with this array, it will automatically include the new todo object.  The last line just returns this todo object.

Remember is the last tutorial we made it so the users could update the status and the priority of a todo?  Well, now we also need to give them the ability to update the text of the todo.  So open up TodoViewController.h and add the following code:


Ok, so I’m guessing you are wondering why the UITextView for the todoText object has been changed to a UITextField.  Well, I will tell you.  UITextView doesn’t have the methods that we need to save the text with our current design.  We will also be changing this on our Interface inside of Interface Builder.  So for now, just believe me and anywhere it says UITextView, change it to UITextField.  The only additional code we added here is the method signature for the updateText method.  It’s an IBAction that will get called when the user presses the “Done” button on the keyboard after setting the text for the todo.  Next, we need to implement this method.  Open up TodoViewController.m and add the following code:

All this does is update the text of the todo to the text that the user entered inside of the UITextField.  The last thing we need to do in order to add a todo is to replace the UITextView with a UITextField and connect it to our updateText method.  Double click on your TodoViewController.xib file to open it in Interface Builder.

Now click on the UITextView on your interface and press the delete key on your keyboard to delete it.  Now, drag a UITextField from the library and drop it onto your interface.  Resize it to fit.  When you have completed that, your interface should look something like this:

Now we need to connect this component.  Make sure it is selected and click Tools -> Connections Inspector to open up the connections inspector.  Drag from the circle next to the method “Did End On Exit” to the “File’s Owner” object.  The words udpateText should pop up.  Click on them to make the connection.  Next, click in the circle next to “New Referencing Outlet” and drag it to the “File’s Owner” object.  Select todoText  when it pops up.  The Connections Inspector should look like this:

Now we are done with Interface Builder.  Go ahead and close it.  We are now able to add todos.  The last thing we need to do is give the ability to delete todos from the list as well as our database.  This is all done in code, and we won’t need interface builder for this.

Let’s start by adding the methods to the appDelegate to handle the deletion of todos.  Open up todoAppDelegate.h and add the following code:

All we see here is a signature for the removeTodo method.  Also, be sure to add a #import “Todo.h” statement to the top of this file so that we can interface with the todo objects. Now let’s implement the removeTodo method.  Open up todoAppDelegate.m and add the following code:

The first line looks up the todo in the todos NSArray.  It returns the index in the array of the todo to be deleted.  Then, we call the deleteFromDatabase method on the todo object and then remove it from the todos array.  Since the UITableView is updated via this array, it will automatically remove the todo without any additional code on our part.

Now, let’s create the removeTodo method for the todo object. We have already written the method signature in Todo.h in a previous step, so open up Todo.m and add the following code:

Remember the delete_statement variable is a static sqlite3_stmt that we declared in a previous step.  First, we check to see if it is nil.  If it is we compile the statement using the sqlite3_prepare statement.  Next, we bind the primary key of the current todo to the “?” in the sqlite3 statement.  Next, we just step the statement to execute it and reset it.  The last thing we need to do to delete todos from the database is to specify what happens when the user presses the “delete” button.  Open up RootViewController.m and add the following code:

The first step (like the first step of many functions) is to get a reference to the appDelegate.  Next, we check to see if we are currently editing.  If so, call the removeTodo method on appDelegate.  The next line, removes the row from the UITableView at the given indexPath.

Now click Build and Go!  You should now be able to add and delete todo items from the database.  This concludes our four part series of creating a todo list for the iPhone.  As always, if you have any questions feel free to leave them in the comments section.  If you get lost at any time you can download the sample code here.

Happy iCoding!

  • arod

    This is an awesome tutorial. This really helps me understand how the edit functionality can be triggered and how saving to the database works.

    I have found one bug. You have not implemented a mechanism for setting the “dirty” BOOL to yes in the updateText method. You did this in the updatePriority and in the updateStatus. When I change a Todo’s text without also changing the status or the priority, the change is not saved to the database. Can I just declare the “dirty” BOOL in the ToDoViewController and add “dirty = YES” in the updateText method? Of will this need to be done inside the ToDo.m implementation?

    Also, in the deleteFromDatabase method, I suggest changing the NSAssert error to something like: @”Error: failed to delete todo with message ‘%s’.” since you’re trying to delete a todo not ‘save the priority”.

    I’m curious. Could you outline the changes that are needed to the project to support a textView. I’m not asking for you to redo the tutorial. I’m just wondering what is involved. I did notice in IB that there are no built in methods for the TextView as there are for TextField. Thanks,

    Alex

  • pfargo

    A nice wrap up. I was able to fix the omission of the updating text Alex mentioned without too much trouble. This series has been a great help.

    Looking forward to more :^)

  • http://www.icodeblog.com Brandon

    @alex,

    I realized this after publishing. I will update it when I have some time. Good job finding it… And the error message was just a lazy copy and paste error. No biggie, I should probably change them though.

    Also, with the UITextView, to allow it to save, we would have to change the design a bit. So rather than having each method update their respected property (updatePriority, updateStatus,etc…) we would just do one big update when the user presses the “Back” button. This would just retrieve the values in each of the UI components and update the todo from there. Not a bad design actually, I just didn’t do it this way from the beginning.

    Thanks for reading…

  • AdamJTP

    Firstly – Great work! I can’t find a more detailed set of tutorials on the web.

    Just one question – when are you going to show the world how to create these forms using table cells (like the data entry forms in iPhone -> settings)?

    BTW. Love the way the code snippets are graphics and not text. It forces us to type the code (which really helps to understand it – not just use it).

  • http://www.icodeblog.com Brandon

    @Adam

    One such tutorial is in the queue as that makes for much prettier interfaces. Also, that was exactly my intention with the code snippets. It has been my experience with tutorials that if you don’t type it yourself, it is really hard to learn and retain.

    Thanks for posting.

  • Mitchell

    Brandon,

    Thanks so much. I’ve been following along and so far and really appreciate what you are doing. Like many, I’m getting all the samples and tutorials I can find and you have put together a great series!

  • Mike

    Brandon-
    Again, this series has been a great help for me! One question, when I click in the text box to edit an existing name, it clears out the current value – is there a way to set it so the keyboard pops up with the previous value still intact?

  • http://moheban79@charter.net Dave

    Couple things:
    1. I get an ‘Assertion failure in -[Todo deleteFromDatabase] path…. error when I try to delete at the stepping command it throws an exception ‘failed to save priority’. Perhaps its a permission thing…

    2. When you add an item it doesn’t update the table view, so I guess you need a [self.tableview reloadData] at the end of the addTodo method in the rootviewcontroller.m.

    But I got to say that I’ll probably use this app when its done!

    Thanks.

  • http://www.icodeblog.com Brandon

    @Dave,

    That’s odd about your assertion failure. Does it give you any more detail (could be a type-o in your SQL statement). Also, the table should update when adding a todo item.

    The [self.tableview reloadData] inside of the viewWillAppear method should take care of that. Did you get that step from part 3 of this tutorial. Let me know if you need more help.

    thanks for reading…

  • Kevin

    This has been a great series. Thanks for an incredible amount of work. One great thing is the “safety net” this approach gives us. We can experiment within a framework we know works. For example, in RootViewController.m I switched the “Add” button to use the system “+” button type using the initWithBarButtonSystemItem:target:action: method, passing UIBarButtonSystemItemAdd.

  • Ulthor

    Great tutorial, Brandon. Thanks! I feel like I’m beginning to get the hang of it now.

  • MGC

    ” Next, we insatiate the todo object that was just created by calling its initWithPrimaryKey method.”

    what is “insatiate”?

  • MGC

    Why do methods of adding and deleting records need to be at the AppDelegate level? Other methods are within other files, what makes these two methods so special that they need to be part of the delegate? Why not other methods?

  • AdeC

    Any chance you could do something with the swipe-delete functionality???

    Also what is the cost of getting the records upfront over getting them when you need to, from the database. I wanted to add a filter function to the to do list where I could filter by completed/open etc My problem is that I dont know how many there are of each type before I tell the tableview. At the moment we tell the table view only the count of todos which is al of them not a filtered subset !!!!

    Any idea how I could implement this. I was thinking of creating a todos class which gets the resords from the database when you need them. Would that slow things down too much??

  • AdeC

    Also if you get them when you need them you can do searches ???

  • http://www.icodeblog.com Brandon

    @AdeC

    The swipe to delete functionality should already exists. By making this table editable, this functionality should work.

    Off hand, I’m not sure the cost trade-off. I would implement both solutions and test the load times with the tools apple provides.

    What are you asking about searches? I’m not sure I understand the questions…

  • http://www.icodeblog.com Brandon

    @MGC,

    what are you, my freaking English teacher? You really enjoy pointing out type-os ehh? No worries, I should be proof reading a little better.

    I structured this program using the design pattern that Apple used in the SQLBooks example. I’m not 100% sure why this structure was chosen, but Apple usually makes some solid apps so I think they know a thing or two about design patterns.

    Thanks for (proof)reading…

  • MGC

    No not an english teacher, but a newbee to all of this. One thing I learned is that one little character change, omission or capitalization change and code doesn’t work. I even forgot a ‘:’ one time and code compiled but crashed every time. Talk about difficult to debug.

    I looked at Apple’s SQLBooks example and I couldn’t figure it out either. So now my concern is that I am not sure Where I should declare methods for other programs.

    Thanks for the great tutorials.
    Do you have one on doing basic arithmetic?

  • Mateo

    Thanks Brandon! This was a really great tutorial. Before I got to this last part I tried to insert more todo items in the sqlite db via terminal. When I brought the new db into my project none of my new records showed up. I tried deleting previous builds of the project and that still didn’t help. So I was wondering if using an XML instead of sqlite has any benefits for storing records.

  • http://www.icodeblog.com Brandon

    @Mateo,

    The problem is you need to uninstall your app from the simulator. The app is still using to old db (because we copied it to the document folder). When you uninstall it, it clears it out.

    After you do this, drag your new db into your project and launch it again. It should then reinstall with the new db.

    Hope that helps…

  • Will

    I found a small bug in the code (or at least my code) that I thought might help everyone out as it took me a while to find.

    When you created a new todo and edited nothing else before switching back to the To Do Items tableview, if you exited the app the text would not be saved, this is because the updateText method didn’t change dirty to YES… I fixed this by doing:

    In todo.h

    -(void)updateText;

    In todo.m

    -(void)updateText {
    dirty = YES;
    }

    in todoViewController.m

    -(IBAction)updateText:(id)sender {
    self.todo.text = self.todoText.text;
    [self.todo updateText];
    }

    Works fine now. Hope I helped, let me know id it works for you.

  • Bill

    Great stuff!
    Does anybody on this forum know what might be causing the following?
    I did this tutorial and everything worked great!!! I then tried to implement the same sqlite3 type code into a separate program. The select statements work great. The problem is that the database will not update. I have the createEditableCopyOfDatabaseIfNeeded implemented just like in the todo example and as I step through it all is good. In my new code though, when I try an insert, it says it is successful, if I make a call to sqlite3_last_insert_rowid it indicates that all is good. But if in a terminal window, I look at the database file, it is not update and when I quit the app and come back in, the changes are not there. Interestingly enough, a ‘-journal’ file does get created on the insert, but it doesn’t seem to do anything for me.
    Does anybody have any ideas on this?

  • http://http? Vitor Almeida

    Great series. Thanks for the hard-work and dedication. Looking forward

  • http://www.vsoftgames.com Vitor Almeida

    Great series. Thanks for the hardwork and dedication. These tutorials are very detailed.

  • http://www.icodeblog.com Brandon

    @Bill,

    This could be because the database gets copied to the Documents folder of the iphone (simulated for the simulator). So the database in your project is not the database that gets modifed.

    This could be why you are not seeing the changes in the terminal.

  • Bill

    Thanks Brandon, it ended up being something as simple and yet elusive (since an error code is not returned) as the fact that I wasn’t reseting a statement after one of my selects.

    On a different note, do you know how a digital timer would be implemented. Is there some simple cool class that I haven’t seen, or do you use the Date or NSTimer classes?

  • http://www.iPhonik.pl www.iPhonik.pl

    This is the best tutorial in the web! I saw many , becouse I try to understand how to create soft for iPhone, and I want to thank You for this on!

    Great job! I wait for next one !

    Paweł

  • rupert

    I love your blog! I’ve been following your tutorials and they are simply great!

    You’re a great teacher and it really helps me to understand.

    Keep up the good work!

  • Christian

    Does anyone know how I would add a tick, just before the priority, so it is easier to distinguish between complete and incomplete to-do’s?

    Any help would be appreciated.

    Thanks,
    ~ Christian

  • http://www.kayzeesolutions.com KayZee Solutions

    Great work Brandon. These have been excellent tutorials to help with some necessary functionality.

    In one of your earlier posts (from Tutorial 3) you mentioned that you might be adding video tutorials in the future. I just wanted to mention that I find the written tutorials MUCH more useful and easier to follow. The written version allows us to read at our own pace and scroll up and down as we please rather than pausing/rewinding video playback. Just my opinion.

    Keep up the great work!

  • Tom

    Hi Brandon,

    Just completed the 4 tutorials and they were fantastic. One quick question, how can I upload the application to my iphone?

    Thanks

    Tomas

  • Mike

    When I add an entry, the segmented controller is set to the value of low when the view is loaded. Lets say, I change the value to Med and save it. When I try to add another entry… the segmented controller is set to the last value… in this case… Med. My question is… how do I reset the segmented controller to Low everytime I add a new value? I’ve checked Apple’s docs and can’t find the answer.

  • http://www.designsapling.com Jeremy White

    Awesome tutorial!

    I found one problem besides the one Will posted about on Nov 3rd.

    If you don’t look at or edit any To Do item before you add a new To Do item (in other words, you’re not creating a TodoViewController instance), then the status label says “Label” and the status button says, “Update status”. This is our default text from IB.

    However, the status setting default for a new item is “In Progress”.

    So to reflect that default status in the TodoViewController view, I added the following to RootViewController’s addTodo method:

    [self.todoView.todoStatus setText:@"In Progress"];
    [self.todoView.todoButton setTitle:@"Mark as Complete" forState:UIControlStateNormal];
    [self.todoView.todoButton setTitle:@"Mark as Complete" forState:UIControlStateHighlighted];

  • Max

    Thanks for this awesome tutorial. I did find one thing that tripped me up -

    The first time I ran it from my code, it worked fine. I tested all the functions, then exited. From then on it would crash on startup. I compared my code to yours and found this line in todoAppDelegate.m under initializeDatabase:

    NSLog([[NSString alloc] initWithFormat:@”size:%@”,[[todos objectAtIndex:3] text]]);

    This line was apparently included in Part 2 and must have found its way into mine when I was comparing code, however I noticed it is now missing from the code for Part 4, and deleting this line seems to have fixed my problem. What does this line do, and did it cause the same problem for you? Is that why its gone? Thanks!

  • http://www.wesg.ca Wes

    Wow, what a great resource for budding iPhone programmers. I’ve searched the web and your site has come above the rest. Great work!

    On somewhat of a side note, I’ve noticed you respond to comments with @commenter. If you’re looking for a cool way to spice the comments up, check out my wordpress plugin Comment Connection.

    http://www.wesg.ca/2008/04/wordpress-plugin-comment-connection/

  • Hank

    Brandon,

    is there anyway to change the text of the edit button on the bar?

  • http://www.squidoo.com/sqlitehammer Jay Godse

    This is a great tutorial on iPhone/SQLite programming. I think that I’ll put a pointer on my site at http://www.squidoo.com/sqlitehammer.

    If you’re interested, my site has a lot of information on SQLite in general.

  • reetu.raj

    Hi there !
    first of all thanks for this wonderful tutorial !

    I have a question , I am trying to integrate sqlite with in my application where I have some hierarchical windows , cant use rootviewcontroller .

    like

    mainviewcontroller > childviewcontroller > I want to make sqlite table views in childviewcontroller.

    But it doesnt seem to be working to me :(

    has anyone done something like that ?

    Thank you so much !

  • reetu.raj

    ok ! i just happened to get it done !
    if anyone face any problem in this , let me know, I’ll send you my sample code :D

  • Jonathan

    i keep getting an error and i even tried downloading your source.

    *** Terminating app due to uncaught exception ‘NSInvalidArgumentException’, reason: ‘*** +[NSString stringWithUTF8String:]: NULL cString’

    i tracked it dow to what i think is the problem. i stepped though the code and pk is incremented 1 3 4 and when it tries 5 it doesn’t exist so it errors out. I am not sure why it skips 2. I also deleted all but one entry in the database and it still tries to read entries that are not there.

  • wiegeabo

    I got the code to run, but something weird was going on with my database. When I created a new item, the text wasn’t saved. Then the program crashed when I exited.

    Now when I try to load the app, it just crashes. I checked the database, and it looked fine. The new item hadn’t been saved into it. Not sure what’s caused the issue.

  • Mark

    @wiegeabo I get the same thing. BTW I believe the app copies the database file to the phone, so your terminal commands will not reflect what has been saved on the phone, delete the app off of the simulator (or your phone) to get the DB back to normal.

    That being said, does anyone know what is causing this? My app runs fine until I try to update the text??

  • reetu.raj

    Hi there ,

    First of all thank you so much for your code.
    I have a query about todo.sqlite file.

    You know I am adding new things in and they show me those new things to do in table on iphone simulator but when I open todo.sqlite file in sqlite manager and do a simple query like
    select * from todo;

    it shows me only 4 enteries which were already there when I downloaded your code. whatever I enter new it just doesn’t show up in todo.sqlite file when I open it in sqlite manager or console :(

    Am I missing something here ? I am just confused that if new entries are not getting stored in the todo.sqlite where are they getting stored that all the enteries old and new appear in the table on iphone simulator but not on todo.sqlite when I open it on sqlite manager.

  • Mark

    @wiegeabo I figured it out… (at least in my code) I very foolishly was binding the text to my insert_statment INSTEAD of my hydrate statement, so it was being set to NULL, therefor the next time I tried to load that object, it fails. Double check what you are binding the text to.

    @reetu.raj The application creates a copy of the database to the phone. remember when you build, it compiles all of the code and transfers it to the iPhone (or simulator) once that happens, it never again reads the file in your project directory, which is why you cant see changes.

  • Reetu Raj

    Hi,

    thank you so much replying, but if I want to use that my updated database in other iphones too , I need to have todo.sqlite file itself updated isnt it ?

    How would we do that ? we will have to do manually ? :(

  • Mark

    @Reetu Raj So I just figured it out, you CAN open the database that the iPhone sym is using… edit rows, create rows, view rows that the App has created.

    The application is stored in:

    ~/Library/Application\ Support/iPhone\ Simulator/User/Applications/Some-Crazy-Hex-String/

    You will have to look in the different folders there to find out which is your app. Then the sqlite file is stored in Documents. I just wouldn’t suggest editing it while the simulator is running your application.

    Good luck!

  • Reetu Raj

    thank you sooooo much Mark !!!!!

  • Dan

    Brandon -

    Thanks for the fine tutorial.

    I have a question. How can one add an intro view to the
    todo application ? The intro would be a simple view (not a table view) which is the starting screen. It might say “welcome to the toto app”. Where would one “push the controller” as we do in RootViewController.addTodo ?

    thanks again.

  • Really Good Tutorial…

    Brandon, Thank you so Much for all this information this tutorial is really great, I’m just starting developing for the iPhone and this is just I need to start doing the application I have in mind, of course it will take time for me to figure out other things, but thanks to this one I have a foundation to start working on my app…

    Thanks again. I will be checking other material in general so I can continue learning how this works.

    Ralph Martin…

  • http://kbunnell@yahoo.com Karl

    Excellent tutorial! Really enjoyed learning iPhone development as I moved through all 4 tutorials. I’m new to objective c so I’ve been caught off guard by the permissiveness of the language at times. For example, it was throwing and uncaught exception when I’d try to build/run. Thanks to TextWrangler and its diff function I found that in my version (I’ve typed everything in to better learn as I went along) in the method where the priority text is set I’d missed the “text’ property on the end. Compiled fine, no errors, no warnings but it failed at run time.

  • Fred

    Hi. Thanks for a great tutorial.

    Could you please help me with something?

    I got ‘syntax error before ‘Todo’ in the AppDelegate.h file. 2x

  • nazbot

    In the insertNewTodoIntoDatabase: method, I believe the line “static char *sql …” be “const char *sql …”. Correct me if I’m wrong. :)

  • Pop

    i have a question my tableView show 3 colums ,if i want to
    show 3 colum in each label in the next UI ‘how to do’
    [self.todoView.todoText setText:todo.text]
    [self.todoView.todoPriority setText:todo.text];
    it appear that 2 label show the same lable i do not want. ^^

  • Oliver

    Dear Brandon,

    Thanks so much for this tutorial! I would like to use such a program to have a dictionary on my iPhone, but I don’t know how to import the database (Excel or Acess) into xCode. I haven’t found a way to do it using SQLite or PListEdit Pro… Do you have a hint on how to do this?
    Thanks!
    Oliver

  • strangeways

    Thank you so much for these tutorials! A couple questions:

    1. In the viewDidLoad method (in RootViewController.m), doesn’t “btn” need to be released? If not, why not?

    2. Is it possible to draw a strike-through on completed items? I’ve looked through Apple’s documentation and can’t figure out how to alter the display of the text to have a strike-through.

  • wiegeabo

    I’ve got it running.

    But when I edit or add a new todo, the text doesn’t appear in the screen that lists them. And I don’t think it’s getting saved in my database because when I reopen the app, it crashes. (Deleting the app, and database, fixes this.)

    I saw the comments that mention adding an update and setting dirty for the text. But making those changes didn’t seem to fix anything.

  • baiwu

    Hi Brandon,

    First, quite appreciated all your tutorials. I have learned a lot from them.
    But something was weird. In addtion to the bug on updateText without “dirty = YES”, I found that, without that fix, the update still happened sometimes. That’s because the the “updatePriority” method was called when a todo item was tapped. I did set a breakpoint to trace it though. It did not happen everytime. I tested the downloaded code without modification. Can’t figure it out why.

  • rahulvyas

    hello i like your tutorial very much. i have a little problem
    please solve my problem.
    as you added custom cell i added a button on cell.now the problem is how do i delete the cell and the data from the database with that button’s click event.i am unable to figure it out how the method should i wrote

  • robhgregory

    Great information, I’ve been playing around with this and it’s been very helpful. I have one question though. I’m working on an app that has a tab bar controller and the third tab is the one that makes the calls to sqlite. If I set up the third tab to be a table view controller, and essentially set up this same configuration on that tab, my tableview is not being updated until I terminate the application. I can delete a todo fine and that works, but if I add a todo or change anything in the todo, it doesn’t get updated. I’m stuck, and I feel like it’s probably something very simple.

  • http://www.lillyfilms.com/futures Chris Allen

    Hey Brandon,

    I have been following your tutorials on this todo list and I am having a problem. I followed through and the program builds, but it unexpectedly terminates when I try and tap any of the items. How can I find out what’s doing this is De-bugger isn’t giving em warnings?

  • k.i.m

    Great tutorial. Especially the UITableViewCell part.
    Thanks a lot for sharing your knowledge with us.

  • Merimim

    Hi!

    great tutorial !

    I found a little bug.
    When i delete a todo thing and create a new one just after (not closing the app) that last todo is not save.

    I remove the “return -1″ in the todo.m class in “insertNewTodoIntoDatabase”.
    Then i got a warning because th function didn’t have a return, but it works.

    If someone has a better way to solve the bug… :)

  • Merimim

    finally, it didn’t solve the bug.
    So leave the return -1.

  • David

    @Chris Allen

    I was having the same problem. The code was throwing an exception as soon as the RootViewController tried to push the todoViewController on to the stack. After scanning a lot of code, I finally just deleted the todoViewController.xib file and regenerated it by hand.

    After that the problem went away. My guess (since it worked in part 3) is that something went awry when I changed the UITextView to a UITextField and fouled up the XML underlying the view.

  • Bruce

    Thanks for the tutorial Brandon. At first I was really alienated by this language. Your tutorial helped me understand some aspects of objective-c. Btw, I’m coming from actionscript 3.0 background.

    However, I noticed that when I run the completed “To do app” and check the leak by doing (Run>Start with Performance Tool>Leaks). I encounter some heaps on the leak graph.

    I just want to know if it’s fine or bad for the application.
    Hope for your prompt response.

    and keep the tutorials coming.
    more power

  • fabiano

    Hello Brandon,
    First of all thank you very much for your wonderfull tutrial, because of that i was able to do the application i wanted.

    But unfortunatly I having a big big issue,
    Basically when i try to deploy your application(downloaded from this site) or my application in the device itself(my iphone is 2G, jailbreak and running on 2.2 firmware) i simple does not open the application on the device, while in the simulator it works fine.
    I think that this problem might be related to the database…
    So my question is, were you able to make your application work on a real device?

    thanks a lot and hope to hear back since my whole application is based on a database.

  • Fabiano

    Hello Brandon,

    I just made further tests about the error i`m getting running the app on my real iphone device and received the error message found below.

    It`s saying that it was not able to find my application document directory, and because of that it cannot create the database.

    To install the application on my iphone(jailbreaked and i do not have iphone developer sign code yet) I generated the .app file(compiled it) send it to my //Applications/ folder in iphone via ssh and then i executed the $ ldid -S /Applications/YourApp.app/YourApp and the$ killall SpringBoard from my mac terminal.(more details can be found here http://adeem.me/blog/2009/03/29/bypass-code-signature-published-your-application-on-cydia/

    After that my application just started showing on the iphone but when i run it i get the error message below.

    Do yo have any ideias of what could i do to make it work?
    thanks!

    Jun 19 18:02:15 iphone sshd[91]: USER_PROCESS: 91 ttys000
    Jun 19 18:04:21 iphone /Applications/DrillDownApp.app/DrillDownApp[95]: open on /var/mobile/Documents/todo.sqlite: No such file or directory
    Jun 19 18:04:21 iphone DrillDownApp[95]: *** Assertion failure in -[eMenuAppDelegate createEditableCopyOfDatabaseIfNeeded], /Users/fnunes/Documents/eMenu/Classes/eMenuAppDelegate.m:108
    Jun 19 18:04:21 iphone DrillDownApp[95]: *** Terminating app due to uncaught exception ‘NSInternalInconsistencyException’, reason: ‘Failed to create writable database file with message ‘Operation could not be completed. No such file or directory’.’
    Jun 19 18:04:21 iphone DrillDownApp[95]: Stack: (\n 808221155,\n 806100816,\n 808035743,\n 812495815,\n 8899,\n 8391,\n 816116592,\n 816153144,\n 812205481,\n 807837071,\n 807834407,\n 827735648,\n 816119480,\n 816158236,\n 8343,\n 8244\n)
    Jun 19 18:04:21 iphone UIKitApplication:com.yourcompany.DrillDownApp[0xe85e][95]: terminate called after throwing an instance of ‘NSException’
    Jun 19 18:04:22 iphone ReportCrash[96]: Formulating crash report for process DrillDownApp[95]
    Jun 19 18:04:23 iphone com.apple.launchd[1] (UIKitApplication:com.yourcompany.DrillDownApp[0xe85e][95]): Exited abnormally: Abort trap
    Jun 19 18:04:23 iphone SpringBoard[39]: Application com.yourcompany.DrillDownApp activate: animated deactivate: exited abnormally with signal 6: Abort trap
    Jun 19 18:04:23 iphone ReportCrash[96]: Saved crashreport to /var/mobile/Library/Logs/CrashReporter/DrillDownApp_2009-06-19-180422_iphone.plist using uid: 0 gid: 0, synthetic_euid: 501 egid: 0
    Jun 19 18:04:23 iphone com.apple.SpringBoard[39]: CoreAnimation: timed out fence 2

  • Sunny

    Hello,

    after I follow the tutorial, it done
    but i have some question on delete and insert
    for example
    at now the list have four “todo” item.
    now, i delete any one of them.
    and restart the application (only have three item now)

    but if I remove the application from the simulator
    and reinstall it
    I will get four “todo” item.

    how can i solve this problem?
    i guess it because of “commit sql” but how can i commit it?

  • Perim

    Hi,

    Nice tutorial(s)! Thanks for the same.

    I would like to know if the information created in SQlite will stick around for multiple versions of the same app and across firmware/OS upgrades. Any pointers would be of immense help!

    Appreciate your time!

  • Jason

    I was wondering if there was a way to reorder list in the todo’s and have the SQL database save it?

  • Marc

    Hey Brandon,

    I found a bug in your source code that you have available for download. I can change the names of the todo items, and they will save, except for the very first one. In the case for your app, if I try to change the “Take out trash” item, and then exit the app, and then re-open it, the name doesn’t change!

  • Anurag

    Thanks for the awesome tutorial! Really helped me get started with iPhone development.

  • Melvin

    Hi Brandon,

    I have been through all your tutorials on SQLite3 and others. Its all great with good explanations for those whom are new to xcode.

    Im a slow learner, I can understand your other tutorials. But this one is a little harder to understand. Can you email me and tell me what the individual class suppose to do? I will try to take it from there on my own.

    Thanks
    Melvin
    lxlionhartxl@yahoo.com.sg

  • Satyam

    Along with todo, I would like to set the target time to complete. In case, if I didn’t change the status (or not meeting the date), I want it to show alert at that particular time and date even if some other app is running at that time.
    Can some one tell me how to implement such functionality like alarm….?
    –satyam

  • sandeep

    good yarrrrrrrr

  • Blade Olson

    I am trying to add an additional UITextField. I want to use the first one as the Todo Title. And the second one to be notes about the todo. I am having trouble linking it back to data. Some clues would be appreciated.

  • mora
  • ComputerJ

    Hi Brandon,
    First of all, I want to thank and congratulate you on this great series of tutorials!! Awesome work man!!
    I have to do a tiny app for work and bought 2 books (keep titles out for now) and although 1 of them is not so bad, it’s so deep and complicated to follow that almost made me quit on the project. I found your tutorials and followed them all up to the ToDo Part 1 (I have 2 through 4 to continue tomorrow ;-) but I’m back on my feet thanks to your tutorials!! Thank you!!

    Now, a conceptual question. What’d be the best option to sync a SQLite DB with another DB in a webserver or FTP site? WOuld you have SQLite handle the sync having a MySQL on the other side? Or you’d wrap all changes since last sync in an xml or other format file and send it to “the other side” to be read and processed by a script?

    I can’t find any lead on Google and my app will need exactly that. The skeleton will be similar to your “ToDo app” with some added Tabs in one of the views, but then once all is working on the iPhone, I need to send it to a “main DB” where multiple iPhones will sync with. That DB will likely to be SQLite or MySQL, and I can’t figure out what best practices for that are….any clue will be greatly appreciated.

    And once again, THANK YOU!! Great tutorials!!

  • Shay

    Thanks, Brandon.

    I like following your tutorials.

    They are like a magic revealed.

    Regards
    Shay

  • Jeff

    Nice work on this one. Problem…

    If you click add, then go back without entering anything, it adds a BLANK Todo item. How can we stop this from happening?

    I’ve tried changing some of the code adding if (todoText = @”") Dont do anything… But it only works half way.

    Any help? Thanks in advance, and GREAT tutorials!

  • Pingback: MonkyMotion » Bookmarks del 3 de Octubre

  • AJ

    Hey Brandon,

    Excellent tutorials! I love the way they are guiding the development and making you type in the code!

    Unfortunately I have a bug in my code where an unhanded excception occurs on the line:

    [self.navigationController pushViewController:self.todoView animated:YES];

    in RootViewController.m

    I have tried debugging it but cannot seem to find what the problem is. I have even gone as far as downloading your code (which runs) and comparing every line of the code with mine…. I can see no differences! I have also resorted to copying across your sqlite3 database and still no luck. All I can think of is that there is an error in my XIB when I deleted the textview and added the textField. I have gone over the step many times but maybe I am missing something. I have searched for any textView references that I have missed but cannot seem to find any!

    I appreciate that you are probably extremely busy but is there a chance I could send you my project to see if you can work out where I am going wrong?

    Cheers

    AJ

  • Nagi

    Great tutorials. Learned a lot from them.

  • ODIS

    Hi people !
    Thanks for this great tutorial,

    I have problem ,when i try to implement delete something in my datebase (my own app), i found this error:

    ‘NSInternalInconsistencyException’, reason: ‘Error while creating update statement. ‘no such column: idJunta”
    what can i do?

    thanks! :)

  • http://zdavatz.wordpress.com Zeno Davatz

    Great tutorial! All steps are fun and worthwile to do!

    Also added the change of Wil. Now the todo-Text is also saved.

    Merry X-Mas!

  • Árpi

    Hey Brandon,
    First of all, I’d like to thank you for these awesome tutorials! I’ve started working with the iPhone about two months ago, and i can tell it is much easier with your tutorials!
    But i’m still a rookie (no wonders:) and i’d need a little advice.
    I made a function for posting the todos to an online database. It’s called when a button is pressed on the toolbar i added. It looks like this:

    - (void) send:(id)sender {

    //NSString * udid = [[UIDevice currentDevice] uniqueIdentifier];

    todoAppDelegate *appDelegate = (todoAppDelegate *)[[UIApplication sharedApplication] delegate];
    unsigned count = [appDelegate.todos count];
    Todo *todo;

    while (count–) {
    todo = (Todo *)[appDelegate.todos objectAtIndex:count];
    NSData *returnData;
    NSURLResponse *response;
    NSError *error;
    NSString *url = [NSString stringWithFormat:@"http://some.php?text=%@&priority=%i&status=%i",
    todo.text,todo.priority,todo.status];
    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:url]];

    [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];
    returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
    [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];
    }

    }

    But it only sends the first todo in the array of todos, and i don’t have a clue what did i do wrong. Could you help me out with this one?
    Thanks very much in advance!
    Árpi

  • neil

    File todo.m, property “text” is “retained”. Doesn’t that leak? I can’t see a release.

  • Jeff

    I have an application I created after working through this tutorial. It is similar to this app, but has a few more text fields.

    The interesting thing is that when I go to edit one of the items in my list of items, I click it, it takes me to the item view and shows all the values for that item, but when I change the value of one of the fields, say the date, it never updates on the original tableview on the main screen. I set up some NSLogs in the debugger console and saw something interesting:

    My Code:

    - (IBAction)updateText:(id) sender {
    NSLog(@”%@”,self.milemarker.logdate);
    NSLog(@”%@”,self.milemarkerLogDate.text);
    self.milemarker.logdate = self.milemarkerLogDate.text;
    NSLog(@”%@”,self.milemarker.logdate);
    NSLog(@”%@”,self.milemarkerLogDate.text);
    [self.milemarker updateText];
    }

    THe debugger output:

    2010-02-04 17:51:41.602 MileMarker[2754:207] (null)
    2010-02-04 17:51:41.603 MileMarker[2754:207] 11-11-1111
    2010-02-04 17:51:41.604 MileMarker[2754:207] (null)
    2010-02-04 17:51:41.605 MileMarker[2754:207] 11-11-1111

    I would expect to see the first line that is null to have the CURRENT value from the date textfield in my app, I would expect the second null to have 11-11-1111 in it due to the assignment I am making (self.milemarker.logdate = self.milemarkerLogDate.text;).

    Any ideas why I am not picking up my current values? When I put a breakpoint in it says out of scope for self.milemarker.logdate

    I know I am not showing all of the details here, but if anyone needs to see any of the source code files, I will be glad to provide them. This one has me scratching my head since I followed the examples in Brandon’s demo very closely.

    I probably missed something simple though…
    Thanks
    Jeff

  • Jeff

    When I put the same breakpoint in this tutorial’s code, here is what I get, the expected behavior:

    - (IBAction) updateText:(id) sender {
    NSLog(@”%@”,self.todo.text);
    NSLog(@”%@”,self.todoText.text);
    self.todo.text = self.todoText.text;
    NSLog(@”%@”,self.todo.text);
    NSLog(@”%@”,self.todoText.text);
    [self.todo updateText];
    }

    Debugger Console output:

    2010-02-04 21:35:02.545 todo[3326:207] DIGG this tutorial
    2010-02-04 21:35:02.547 todo[3326:207] REDDIT this tutorial
    2010-02-04 21:35:02.548 todo[3326:207] REDDIT this tutorial
    2010-02-04 21:35:02.548 todo[3326:207] REDDIT this tutorial

    Interesting?

  • pithhelmet

    Hi Brandon,

    How do you hide the keyboard when you are ready to save the new note??

  • mohsin

    HEY BRNDON,THE SOURCE CODE DOWNLOAD LINK IS NOT WORKING!!
    PLZ HAVE A LOOK….

  • Ali

    for updating the todo list after editing a TODO item we can override viewWillAppear to be like this:


    - (void)viewWillAppear:(BOOL)animated {
    [self.tableView reloadData];
    [super viewWillAppear:animated];
    }

  • Jon

    I had the issue mentioned in other posts in which the updateText method was not being called. I fixed my code by copying the code within updateText and pasting into viewWillDisapper (of TodoViewController.m). This guarantees the text field to be updated when you navigate back to RootViewController.

    Great set of tutorials!

  • Jon

    Also, for iOS4, you might need to add:

    [todos makeObjectsPerformSelector:@selector(dehydrate)];

    to applicationDidEnterBackground in TodoAppDelegate.m.

  • Alessign

    Great tutorial! Thanks! I used the idea in my app I am working on now. I have problems with icon badge number though. In appDelegate.m in section applicationDidFinishLaunching: I inserted code
    int rows = [coffeeArray count];
    [UIApplication sharedApplication].applicationIconBadgeNumber = rows;

    - it works fine until the point the UITableview is empty. The badge number still shows 1. How do I manage the code to display on the icon how many ToDo’s (rows in UITableView) I have correctly? Thank you for advices!

  • AD

    Hi, how do you lazy load SQLite tables? Say for example you have 3,000 records; its silly to put that into objects or an array, especially as the viewport is only X high.

    Therefore, is it possible to lazy load SQLite database tables, and if so what is the correct way to do this?

  • icky

    Hey.

    When you restart the App, the data isn’t saved properly – i.e. the items dont keep their names and so on…. Did anyone else see this too?

  • http://www.koldcastle.com anthony

    i love the tutural but i have a question can this sample be used as a beginning to build an app
    or is it just a sample can not be used to launch their app

  • Pingback: App development per iOS, i tutorial - TheAppleLounge

  • http://www.worldoftrade.com/ jack

    wow that great !
    iPhone Programming Tutorial post is very nice
    Your post have good information photo are also inspire to me on this website…….
    thanks for sharing great information…

  • http://www.worldoftrade.com/ Rolex Sweep

    Hello !
    Pretty good post, this is one of the best articles that I have ever seen! This is a great site and I have to congratulate you on the content.
    I appreciate it!

  • http://www.cygnismedia.com/ cygnis media

    Thanks for the sharing of such information we will pass it on to our readers.

  • Lost

    fails to update database on reruning in the the simulator,

  • http://www.rapidwriters.net/ Term Paper Writing

    Nice post. This post is different from what I read on most blog. And it have so many valuable things to learn. Thank you for your sharing!

  • Aguseka

    Fails to update/insert/delete….

  • Kevin

    how can I make it not show a To Do – item when that item is completed? I don’t know if this was already implemented but that option doesn’t work! Other than that a great tutorial serie ;)

  • Alan

     Excellent post. I’ve already done all those steps and the app is working perfectly.

  • Chargedneuron

    Could you please update this tutorial to reflect XCode 4 and iOS4 please? I am still very green to the programming and the errors I am getting are making it difficult to get a clear picture. Thank you for the awesome tutorials!

  • Fvelazco

    Hey man, I added a new text field OBS  but some problems.
    http://i52.tinypic.com/2vdgtaa.png
    http://i53.tinypic.com/1z7lld.png.

  • http://www.facebook.com/people/Wiegeabo-Kilijabob/100000074745693 Wiegeabo Kilijabob

    Every time I try and add the line -(Todo*)addTodo; I get an error.

    Expected ‘)’ before ‘Todo’

    • Lucy Bain

      I got that error too, here’s the problem:
      The “Todo” class hasn’t been declared yet, so when we type in “(Todo *)” the compiler is really confused – “What’s a ‘Todo’?  I’ve never heard of such a thing!  Error message!”.
      And here’s the solution:
      Tell the compiler about the “Todo” class.  There are (at least) two ways of doing this:
      1 – #include “Todo.h” – not recommended.  I’m honestly not sure why this isn’t a good idea, but all of the other tutorials and StackOverflow say not to do it.
      2 – add the line “@class Todo” before the ”  @interface:twitter  ” line in todoAppDelegate.h.  As I understand it, this is a forward declaration of the Todo class.  Basically it says to the compiler “just an FYI, there’s going to be a class called ‘Todo’, so if you see it, don’t flip out.”

      Hope that helps!

  • NeedHelp

    I found a bug and it’s similar to what people are posting.  When you re-run the simulator… anything that you added to the database is lost.

    So when you run it on a Device itself… everything works… database gets saved.  But if you TURN OFF (hold power off for 5 seconds)… anything that you added to the database is gone.  Basically the database gets deleted.

    Anyone found a solution????

  • http://twitter.com/kSeudo Brian Cunningham

    This was truly excellent… thanks for taking to time to do this tutorial

  • Ben Smith

    Yes I saw this. The new SDK has some additional functions that allow applications to enter the background. When you quit your application it is not actually running the applicationWillTerminate function, it is running the applicationDidEnterBackground function, so you need to add the [todos makeObjectsPerformSelector:@selector(deyhdrate)]; into this function as well.

canakkale canakkale canakkale balik tutma search canakkale vergi mevzuati bagimsiz denetim vergi mevzuati ozurlu engelliler