【问题标题】:iOS NSArray of NSDictionaries from SQLite in UITableView来自 UITableView 中 SQLite 的 NSDictionaries 的 iOS NSArray
【发布时间】:2012-03-09 04:29:25
【问题描述】:

过去两天我一直在努力解决这个问题,但我似乎无法弄清楚。我有一个具有以下结构的 SQlite 数据库。

List 和 List_Items 之间是一对多的关系

我访问数据库并创建一个对象,然后将其添加到 NSDictionary 中,该 NSDictionary 又添加到 NSArray 中。我这样做了两次,一次用于 List 表,一次用于 List_Items。 然后我使用列表数组来计算我的表格视图行的列表数量,然后将它们添加到表格视图中。

当我到达方法时问题就来了

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 

我似乎无法弄清楚如何匹配 Lists 和 List_Items 中的记录以在向下钻取表视图中显示与该列表相关的列表项。

具体的代码示例会很有帮助,因为此时我的想法很混乱:(

这是我目前 Writersblock 的相关代码。

 //#******************************************************#

//               *******Start Database*******

//#******************************************************#

-(void)checkAndCreateDatabase
{
    // Check if the SQL database has already been saved to the users phone, if not then copy it over
    BOOL success;

    // Create a FileManager object, we will use this to check the status
    // of the database and to copy it over if required
    NSFileManager *fileManager = [NSFileManager defaultManager];

    // Check if the database has already been created in the users filesystem
    success = [fileManager fileExistsAtPath:databasePath];

    // If the database already exists then return without doing anything
    if(success) return;

    // If not then proceed to copy the database from the application to the users filesystem

    // Get the path to the database in the application package
    NSString *databasePathFromApp = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:databaseName];

    // Copy the database from the package to the users filesystem
    [fileManager copyItemAtPath:databasePathFromApp toPath:databasePath error:nil];
}

-(void)readItemsFromDatabase 
{
    // Setup the database object
    sqlite3 *database;

    // Init the Items Array
    items = [[NSMutableArray alloc] init];
    lists = [[NSMutableArray alloc] init];

    //---------------### SELECT THE LISTS #####---------------//

    // Open the database from the users filessytem
    if(sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK) 
    {
        NSLog(@"SQL Opened");
        // Setup the SQL Statement and compile it for faster access
        const char *sqlStatement = "SELECT * from List";
        sqlite3_stmt *compiledStatement;
        if(sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK) {
            // Loop through the results and add them to the array
            while(sqlite3_step(compiledStatement) == SQLITE_ROW) {
                // Read the data from the result row
                NSString *aListName = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 1)];
                NSString *aUserID = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 2)];
                NSString *aListID = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 3)];

                NSLog(@"SQL Compiled");

                // Create a new list object with the data from the database
                List *list = [[List alloc] initWithlistName:(NSString *)aListName userID:(NSString *)aUserID listID:(NSString *)aListID];

                listNames = [NSDictionary dictionaryWithObjectsAndKeys:list.listName,@"listName",list.listID,@"listID",list.listID,@"listID",nil];

                // Add the Shopping object to the list Array
                [lists addObject:listNames];

            }
        }

        else { NSLog(@"Database Not Found");}

        // Release the compiled statement from memory
        sqlite3_finalize(compiledStatement);
    }
    sqlite3_close(database);

        //---------------### SELECT THE LIST_ITEMS #####---------------//

        if(sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK) 
        {
            NSLog(@"SQL Opened");
            // Setup the SQL Statement and compile it for faster access
            const char *sqlStatement = "SELECT * from List_Items";
            sqlite3_stmt *compiledStatement;
            if(sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK) {
                // Loop through the results and add them to the array
                while(sqlite3_step(compiledStatement) == SQLITE_ROW) {
                    // Read the data from the result row

                    NSString *aBrandName = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 1)];
                    NSString *aItemName = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 2)];
                    NSString *aItemQuantity = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 4)];
                    NSString *aImageUrl = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 5)];
                    NSString *aListID = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 6)];

                    NSLog(@"SQL Compiled");

                    // Create a new items object with the data from the database
                    Shopping *shopping = [[Shopping alloc] initWithlistID:(NSString *)aListID brandName:(NSString *)aBrandName itemName:(NSString *)aItemName itemQuantity:(NSString *)aItemQuantity imageURL:(NSString *)aImageUrl];                    

                    itemList = [NSDictionary dictionaryWithObjectsAndKeys:shopping.listID,@"listID",shopping.brandName,@"brandName",shopping.itemName,@"itemName",shopping.itemQuantity,@"itemQuantity",shopping.imageURL,@"imageURL",nil];

                    // Add the Shopping object to the items Array
                    [items addObject:itemList];
                }
            }

            else { NSLog(@"Database Not Found");}

            // Release the compiled statement from memory
            sqlite3_finalize(compiledStatement);

        NSLog(@"%@",items);
        NSLog(@"%@",lists);

    }
    sqlite3_close(database);

}

//#******************************************************#

//                *******END Database*******

//#******************************************************#

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    int rowcount;
    rowcount = [lists count];
    return rowcount;
}

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

    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) 
    {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault 
                                      reuseIdentifier:CellIdentifier];    
    }

    // Set up the cell...

    NSString *cellValue = [[lists objectAtIndex:indexPath.row] objectForKey:@"listName"];

    cell.textLabel.text = cellValue;

    return cell;
}

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
{

    if ([[lists objectAtIndex:indexPath.row] objectForKey:@"listID"] != NULL) 
    {        
        NSString *listIndex = [[lists objectAtIndex:indexPath.row] objectForKey:@"listID"];
        int i = [listIndex intValue];
        NSLog(@"indexPath: %d",i);
    }

}

编辑**********

单个 Sql 语句返回多个 Listname。这是一个问题,因为我只需要每个列表名称中的一个。

【问题讨论】:

    标签: sql ios sqlite uitableview nsarray


    【解决方案1】:

    首先,您要创建一个 List 对象,然后创建一个与 List 对象几乎相同的 NSDictionary 对象。为什么?为什么不直接将 List 对象添加到 Array。如果您没有对 List 项中的属性执行任何功能,则根本不要使用 List 对象,只需将字段直接放在 NSDictionary 中即可。

    其次,不要执行两个不同的 SQL 调用来获取信息,只使用一个来同时获取该列表的 List 和 list_items。然后,如果您使用的是 List 对象,请添加一个 NSMutableArray 属性调用项目,并将您的 listItems 添加到该数组中。您可以在 NSDictionary 中执行相同的操作,只需为关键项添加 NSMutableArray 对象,然后将 list_items 添加到该数组。

    现在您可以设置 tableview 来做您想做的事情。

    针对以下 cmets 的修改答案

    Select * FROM List, List_Items WHERE List.list_id = List.list_id

    【讨论】:

    • 我之前在同一个查询中使用过它们,但是我得到了太多的对象,因为它是一对多的关系,所以例如我会得到 3 个对象,它们都具有相同的 listName 但不同的项目。因此,当我将 Listname 添加到 tableview 时,我将拥有三个相同的 listName,因为其中包含三个项目。
    • 是的,当我在字典上执行 NSLog 时,我会返回每个 listName 的 7 个,而我真的只需要一个。
    • 这是我对两个列表的 SQL 查询 "const char *sqlStatement = "SELECT * from List, List_Items";"
    • 您缺少 WHERE 语句。请参阅修改后的答案。
    • 我仍然会返回包含多个列表项的任何项目的重复项。 (见上图)
    【解决方案2】:

    任何对此感兴趣的人都是我想出来的。 我得到列表的listID,然后我创建一个数组并循环遍历列表项,并将它们与listID 进行比较。如果它们与 listID 相同,我将它们添加到数组中,一旦完成 for 循环,它会将结果添加到我的数据对象协议(使其可用于下一个视图),然后我呈现一个模式视图控制器并加载来自数据对象的数组。完成模态视图后,我将数据对象设置回 nil 和 Tada!有用。

    -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
    {
    
        if ([[lists objectAtIndex:indexPath.row] objectForKey:@"listID"] != NULL) 
        {        
            [listTableView deselectRowAtIndexPath:indexPath animated:YES];
            NSString *listIndex = [[lists objectAtIndex:indexPath.row] objectForKey:@"listID"];
    
            NSMutableArray *itemArray = [[NSMutableArray alloc]init];
    
            int i; int itemCount = [items count];
    
            for (i = 0; i < itemCount; i++) 
            {
                if ([[[items objectAtIndex:i] objectForKey:@"listID"] isEqual:listIndex]) 
                {
                    [itemArray addObject:[items objectAtIndex:i]];
                    NSLog(@"Item Array:%@",itemArray);
                }
            }
    
            if (i == itemCount) 
            {
                AppDataObject* theDataObject = [self theAppDataObject];
                theDataObject.itemArray = itemArray;
    
                ItemView *temp = [[ItemView alloc] initWithNibName:@"ItemView" bundle:nil];
                [self presentModalViewController: temp animated: YES];
            }
    
        }
    
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多