Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SQLite data showing

I'm totally new with SQLite. I have a UITableview with contains different days in it. (Monday till sunday). When i click on for example Monday an other viewcontroller contains with also a UITableview inside it. In the same viewcontroller i have a UIButton when i click on it i can add data to my SQLite database [A], i insert the name and the day of the week (The day of the week is in this example 'monday' that's because i clicked on the monday view controller).

When i insert a name it appears in my tableview. But when i go back to my first viewcontroller with the days and i click for example on Wednesday the data i added also appear there.

So my question is; How can i show the name which i inserted in monday, only in the monday tableview and not the other days(tableviews)

More information:

So when a user adds a name in 'monday' i send the dayoftheweek with the added name to the SQLite database, when a user adds a name in wednesday i send 'dayoftheweek' Wednesday etc..

Database Coffee looks like =

CoffeeName    | dayoftheweek
-------------------------
Hello world   | Monday
Hello Planet  | Wednesday
Hello Animal  | Monday
Hello STOVW   | Friday

[A] const char *sql = "insert into Coffee(CoffeeName, dayoftheweek) Values(?, ?)";

I need to check if the day (for example) monday is the same as dayoftheweek (monday) and then display al the items which contains 'dayoftheweek monday'

My sqlite looks like:

+ (void) getInitialDataToDisplay:(NSString *)dbPath {


    if (sqlite3_open([dbPath UTF8String], &database) == SQLITE_OK) {


        const char *sql = "select coffeeID, coffeeName from coffee";
        sqlite3_stmt *selectstmt;
        if(sqlite3_prepare_v2(database, sql, -1, &selectstmt, NULL) == SQLITE_OK) {

            while(sqlite3_step(selectstmt) == SQLITE_ROW) {

                NSInteger primaryKey = sqlite3_column_int(selectstmt, 0);
                Coffee *coffeeObj = [[Coffee alloc] initWithPrimaryKey:primaryKey];
                coffeeObj.LessonName = [NSString stringWithUTF8String:(char *)sqlite3_column_text(selectstmt, 1)];

               coffeeObj.dayoftheweek = [NSString stringWithUTF8String:(char *)sqlite3_column_text(selectstmt, 1)];

                coffeeObj.isDirty = NO;

                [appDelegate.coffeeArray addObject:coffeeObj];
            }
        }
    }
    else
        sqlite3_close(database); //Even though the open call failed, close the database connection to release all the memory.
}


- (void) addCoffee1 {


    if(addStmt == nil) {
        const char *sql = "insert into Coffee(CoffeeName, dayoftheweek) Values(?, ?)";
        if(sqlite3_prepare_v2(database, sql, -1, &addStmt, NULL) != SQLITE_OK)
            NSAssert1(0, @"Error while creating add statement. '%s'", sqlite3_errmsg(database));
    }



    sqlite3_bind_text(addStmt, 1, [dayoftheweek UTF8String], -1, SQLITE_TRANSIENT);

    if(SQLITE_DONE != sqlite3_step(addStmt))
        NSAssert1(0, @"Error while inserting data. '%s'", sqlite3_errmsg(database));
    else
        //SQLite provides a method to get the last primary key inserted by using sqlite3_last_insert_rowid
        LesID = sqlite3_last_insert_rowid(database);

    //Reset the add statement.
    sqlite3_reset(addStmt);
}

Insert:

coffeeObj.dayoftheweek = [NSString stringWithFormat:@"%@", dayoftheweek];

this insert: monday tuesday wednesday thursday friday saturday or sunday

But how can i display the data which is inserted in monday in the monday tableview and the data which is inserted in tuesday in the tuesday controller etc.

i tried ;

if([coffeeObj.dayoftheweek isEqualToString:@"Monday"]) {

cell.day.text = coffeeObj.LessonName;


} else {

}

Display:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    static NSString *CustomCellIdentifier = @"DaycusViewController";
    DaycusViewController *cell = (DaycusViewController *)[tableView dequeueReusableCellWithIdentifier: CustomCellIdentifier];


    if (cell == nil) {
        NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"DaycusViewController"
                                                     owner:self options:nil];
        for (id oneObject in nib) if ([oneObject isKindOfClass:[DaycusViewController class]])
            cell = (DaycusViewController *)oneObject;
    }


    //Get the object from the array.
    Coffee *coffeeObj = [appDelegate.coffeeArray objectAtIndex:indexPath.row];



    cell.Name.text = CoffeeObj.CoffeeID;
    cell.Day.text =  CoffeeObj.dayoftheweek;


    //i tried this: (not working)

/* begin */ if([CoffeeObj.dayoftheweek isEqualToString:@"Monday"]) {

        //  cell.Name.text = CoffeeObj.CoffeeID;
    //cell.Day.text =  CoffeeObj.dayoftheweek;

    } else {

    }
    /* end */

//it need's to display in this example only things where dayoftheweek is monday but.
    return cell;
}

call to function getInitialDataToDisplay

//Copy database to the user's phone if needed.
[self copyDatabaseIfNeeded];

//Initialize the coffee array.
NSMutableArray *tempArray = [[NSMutableArray alloc] init];
self.coffeeArray = tempArray;
[tempArray release];

//Once the db is copied, get the initial data to display on the screen.
[Coffee getInitialDataToDisplay:[self getDBPath]];
like image 918
Frenck Avatar asked Feb 25 '12 15:02

Frenck


2 Answers

It's hard to understand your question but i think you can better open a new project and start with Core Data. It's easy to understand and it's faster than SQLite.

Core Data is a framework Apple provides to developers that is described as a “schema-driven object graph management and persistence framework.” What does that actually mean? The framework manages where data is stored, how it is stored, data caching, and memory management. It was ported to the iPhone from Mac OS X with the 3.0 iPhone SDK release.

The Core Data API allows developers to create and use a relational database, perform record validation, and perform queries using SQL-less conditions. It essentially allows you to interact with SQLite in Objective-C and not have to worry about connections or managing the database schema

More about Core Data:

  • https://developer.apple.com/technologies/ios/data-management.html
  • https://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/CoreData/cdProgrammingGuide.html
  • https://developer.apple.com/library/ios/#referencelibrary/GettingStarted/GettingStartedWithCoreData/_index.html

I wish you all the luck with your application, but i'm for sure that Core Data is the best for your application!

like image 105
Blazer Avatar answered Oct 26 '22 11:10

Blazer


If I understand correctly your problem is not so much about SQLite but much more about how to wire up your view controllers correctly.

When the user selects one of the days in your first UITableViewController you have to pass the information about the selection on to the next view controller. Assuming you are not using storyboards it would probably look something like this:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath*)indexPath
{
 [tableView deselectRowAtIndexPath:indexPath animated:NO];
 DaycusViewController *viewController = [[DaycusViewController alloc] initWithStyle:UITableViewStylePlain];
 viewController.selectedDay = [days objectAtIndex:indexPath.row];
 [[self navigationController] pushViewController:viewController animated:YES];
 [viewController release];
} 

As you now have the information available which coffees you want to display (e.g. the ones for "Monday") in your second view controller you can do for example what Diego suggested and filter your data accordingly.

Your current approach does probably not work because the UITableViewDataSource methods

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

and

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section

depend on each other. So you have to be consistent here. The first one (...cellForRowAtIndexPath...) will be called for each row you want to display as you indicated in the second one (... numberOfRowsInSection ...).

So if you said you had 4 rows to display it will be called four times. What you cannot do is then use an if statement in the ...cellForRowAtIndexPath ... method to just return less than the four rows. Instead you should have a collection of the coffees for that specific day (ideally coming out of your data model ...). You can use the size of the collection for the ...numberOfRowsInSection... method and then return the corresponding element for each row using the index path in the ...cellForRowAtIndexPath ... method like this:

Coffee c = [coffees objectAtIndex: indexPath.row]
cell.name.text = c.name;

There are some quite good examples in Apple's documentation and some sample code that covers exactly your problem as well.

like image 28
pbrc Avatar answered Oct 26 '22 12:10

pbrc