Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/iphone/35.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在iphone上本地存储数据_Iphone_Ios_Database_Xcode_Uitableview - Fatal编程技术网

在iphone上本地存储数据

在iphone上本地存储数据,iphone,ios,database,xcode,uitableview,Iphone,Ios,Database,Xcode,Uitableview,我正在构建一个应用程序,我想在设备上本地存储用户信息,而不使用任何服务器数据库——但一切都在设备端。我希望存储特定的用户位置并将其显示在表视图中,因此即使用户稍后启动应用程序,我也可以提取历史记录并向历史记录表提供过去的位置。基本上是本地数据库的读/写功能 现在,我知道以前有很多这样的问题,但我找不到一个能够解决在没有外部数据库的情况下在本地保存数据的问题。例如,我不确定在这里使用核心数据是否是正确和最简单的做法 如果您有任何建议,我将不胜感激 存储数据基本上有两种选择: CoreData(如果

我正在构建一个应用程序,我想在设备上本地存储用户信息,而不使用任何服务器数据库——但一切都在设备端。我希望存储特定的用户位置并将其显示在表视图中,因此即使用户稍后启动应用程序,我也可以提取历史记录并向历史记录表提供过去的位置。基本上是本地数据库的读/写功能

现在,我知道以前有很多这样的问题,但我找不到一个能够解决在没有外部数据库的情况下在本地保存数据的问题。例如,我不确定在这里使用核心数据是否是正确和最简单的做法


如果您有任何建议,我将不胜感激

存储数据基本上有两种选择:

  • CoreData(如果您计划使用较新版本的iOS)
  • SQLite(支持SDK的任何版本)
  • CoreData使用SQLite,它的API更易于使用(您不需要了解SQL或编写大量函数来读取和写入数据)

    SQLiteAPI仍然是一个很好的选择,因为它使用SQLite的C API,这是一个很好的文档,使用起来很简单。这样做的好处是,您可以使用它针对较旧的iOS平台


    使用这两种选项,数据将存储在客户端,并且在用户每次将其手机与iTunes同步时都会进行备份。

    如果您只存储一些值,而不需要任何搜索逻辑,您可以查看

    它只是一个字典,您可以在其中存储数组、字符串、int、对象和通过NSString键进行访问


    在内部,它是一个just plist,因此您可以使用xcode打开它以快速查看当前状态

    对于简单的数据,您应该使用NSUserDefaults。CoreData非常酷,但主要用于存储DB结构,并且引入了复杂性(但我喜欢它:)。如果只需要存储字符串、数组等(基本上是prefs),可以使用NSUserDefaults:

    例如:

    NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];  //load NSUserDefaults
    NSArray *fakeFavs = [[ NSArray alloc] initWithObjects:@"2",@"4", @"100", nil];  //declare array to be stored in NSUserDefaults
    [prefs setObject:fakeFavs forKey:@"favourites"];  //set the prev Array for key value "favourites"
    
    selectquery:
    NSArray*数组\u hiback=[app.sk lookupAllForSQL:@“从循环中选择*数据收集\u begoodyourselef按随机顺序()限制1];
    NSLog(@“%@”,数组回退);
    插入查询:
    NSMutableDictionary*dict=[[NSMutableDictionary alloc]init];
    [dict setObject:@“0”forKey:@“已上载”];
    [app.sk insertDictionary:dict forTable:@“mindeditor”];
    [听写释放];
    更新查询:::
    NSMutableDictionary*updatedata=[[NSMutableDictionary alloc]init];
    [updatedata setObject:[[NSUserDefaults standardUserDefaults]objectForKey:@“savecycleid”]forKey:@“cycleid”];
    删除查询:
    [app.sk deletehere:[NSString stringWithFormat:@“rowid=%@”,str]forTable:@“mindeditor”];
    [app.sk updateDictionary:updatedata forTable:@“mindeditor”其中:[NSString stringWithFormat:@“rowid=%@”,[[checkarray objectAtIndex:checkarray.count-1]objectForKey:@“cycleid”]];
    [更新数据发布];
    -(BOOL)应用程序:(UIApplication*)应用程序使用选项完成启动:(NSDictionary*)启动选项
    {
    sk=[[SKDatabase alloc]init];
    NSString*db=@“MindEditor.db”;
    [sk initWithDynamicFile:db];
    userid=@“0”;
    }
    SKDatabase.h
    //
    //SKDatabase.h
    //版本1.1
    //
    //由Shannon Appelcline于2008年9月11日创建。
    //版权所有2008年uu MyCompanyName uuu。版权所有。
    //
    #进口
    #进口
    @协议数据库委托
    @可选的
    -(void)DatabaseTablewasUpdate:(NSString*)表;
    @结束
    @接口数据库:NSObject{
    id代表;
    sqlite3*胸径;
    布尔动力学;
    }
    @属性(分配)id委托;
    @不动产sqlite3*dbh;
    @属性布尔动态;
    -(id)initWithFile:(NSString*)dbFile;
    -(id)initWithDynamicFile:(NSString*)dbFile;
    -(无效)关闭;
    -(sqlite3_stmt*)准备:(NSString*)sql;
    -(id)lookupColForSQL:(NSString*)sql;
    -(NSDictionary*)lookupRowForSQL:(NSString*)sql;
    -(NSArray*)lookupAllForSQL:(NSString*)sql;
    -(int)lookupCountWhere:(NSString*),其中forTable:(NSString*)表;
    -(int)lookupMax:(NSString*)键,其中:(NSString*),其中forTable:(NSString*)表;
    -(int)lookupSum:(NSString*)键,其中:(NSString*),其中forTable:(NSString*)表;
    -(void)insertArray:(NSArray*)dbData forTable:(NSString*)表;
    -(void)insertDictionary:(NSDictionary*)dbData forTable:(NSString*)表;
    -(void)updateArray:(NSArray*)dbData forTable:(NSString*)表;
    -(void)updateArray:(NSArray*)dbData forTable:(NSString*)表中:(NSString*)其中;
    -(void)updateDictionary:(NSDictionary*)dbData forTable:(NSString*)表;
    -(void)updateDictionary:(NSDictionary*)dbData forTable:(NSString*)表格,其中:(NSString*),其中;
    -(void)updateSQL:(NSString*)sql forTable:(NSString*)表;
    -(void)deletehere:(NSString*),其中forTable:(NSString*)表;
    -(BOOL)runDynamicSQL:(NSString*)sqlfortable:(NSString*)表;
    @结束
    SKDatabase.m
    //
    //SKDatabase.m
    //版本1.1
    //
    //由Shannon Appelcline于2008年9月11日创建。
    //版权所有2008年uu MyCompanyName uuu。版权所有。
    //
    #导入“SKDatabase.h”
    @数据库的实现
    @综合代表;
    @综合胸径;
    @综合动力学;
    //初始化的两种方法:一种是从数据库中选择,另一种是更新
    //和或插入
    -(id)initWithFile:(NSString*)dbFile{
    if(self=[super init]){
    NSString*path=[[NSBundle mainBundle]resourcePath];
    NSString*path=[路径stringByAppendingPathComponent:dbFile];
    int result=sqlite3_open([path UTF8String],&dbh);
    NSAssert1(SQLITE_OK==结果,NSLocalizedStringFromTable(@“无法打开SQLITE数据库(%@)”,@“数据库”,@“),[NSString stringWithUTF8String:sqlite3_errmsg(dbh)];
    self.dynamic=NO;
    }
    
    NSUserDefaults *prefs = [NSUserDefaults standardUserDefaults];  //load NSUserDefaults
    NSArray *fakeFavs = [[ NSArray alloc] initWithObjects:@"2",@"4", @"100", nil];  //declare array to be stored in NSUserDefaults
    [prefs setObject:fakeFavs forKey:@"favourites"];  //set the prev Array for key value "favourites"
    
    Select Query::::::
    
    NSArray  *array_hiback =[app.sk lookupAllForSQL:@"SELECT * FROM cycle_datagathering_begoodyourselef ORDER BY RANDOM() LIMIT 1"];
        NSLog(@"%@",array_hiback);      
    
    insert Query:::::
    
     NSMutableDictionary *dict=[[NSMutableDictionary alloc]init];
    [dict setObject:@"0" forKey:@"isuploaded"];
            [app.sk insertDictionary:dict forTable:@"mindeditor"];
            [dict release];
    
    
    update Query::::
    
    
      NSMutableDictionary *updatedata=[[NSMutableDictionary alloc]init];
    [updatedata setObject:  [[NSUserDefaults standardUserDefaults] objectForKey:@"savecycleid"] forKey:@"cycleid"];
    
    
    delete Query:::::
    
            [app.sk deleteWhere:[NSString stringWithFormat:@"rowid=%@",str] forTable:@"mindeditor"];
    
                [app.sk updateDictionary:updatedata forTable:@"mindeditor" where:[NSString stringWithFormat:@"rowid=%@", [[checkarray objectAtIndex:checkarray.count-1] objectForKey:@"cycleid"]]];
                [updatedata release];
    
      - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
            {
    
    
                sk = [[SKDatabase alloc] init];
                NSString *db = @"MindEditor.db";
                [sk initWithDynamicFile:db];
                userid=@"0";
            }
    
    
           SKDatabase.h
    
    
        //
        //  SKDatabase.h
        //  Version 1.1
        //
        //  Created by Shannon Appelcline on 9/11/08.
        //  Copyright 2008 __MyCompanyName__. All rights reserved.
        //
    
        #import <UIKit/UIKit.h>
        #import <sqlite3.h>
    
        @protocol SKDatabaseDelegate <NSObject>
        @optional
        - (void)databaseTableWasUpdated:(NSString *)table;
        @end
    
        @interface SKDatabase : NSObject {
    
            id<SKDatabaseDelegate> delegate;
            sqlite3 *dbh;
            BOOL dynamic;
        }
    
        @property (assign) id<SKDatabaseDelegate> delegate;
        @property sqlite3 *dbh;
        @property BOOL dynamic;
    
        - (id)initWithFile:(NSString *)dbFile;
        - (id)initWithDynamicFile:(NSString *)dbFile;
        - (void)close;
    
        - (sqlite3_stmt *)prepare:(NSString *)sql;
    
        - (id)lookupColForSQL:(NSString *)sql;
        - (NSDictionary *)lookupRowForSQL:(NSString *)sql;
        - (NSArray *)lookupAllForSQL:(NSString *)sql;
    
        - (int)lookupCountWhere:(NSString *)where forTable:(NSString *)table;
        - (int)lookupMax:(NSString *)key Where:(NSString *)where forTable:(NSString *)table;
        - (int)lookupSum:(NSString *)key Where:(NSString *)where forTable:(NSString *)table;
    
        - (void)insertArray:(NSArray *)dbData forTable:(NSString *)table;
        - (void)insertDictionary:(NSDictionary *)dbData forTable:(NSString *)table;
    
        - (void)updateArray:(NSArray *)dbData forTable:(NSString *)table;
        - (void)updateArray:(NSArray *)dbData forTable:(NSString *)table where:(NSString *)where;
        - (void)updateDictionary:(NSDictionary *)dbData forTable:(NSString *)table;
        - (void)updateDictionary:(NSDictionary *)dbData forTable:(NSString *)table where:(NSString *)where;
        - (void)updateSQL:(NSString *)sql forTable:(NSString *)table;
    
        - (void)deleteWhere:(NSString *)where forTable:(NSString *)table;
    
        - (BOOL)runDynamicSQL:(NSString *)sql forTable:(NSString *)table;
    
        @end
    
           SKDatabase.m
    
    
    
    
        //
        //  SKDatabase.m
        //  Version 1.1
        //
        //  Created by Shannon Appelcline on 9/11/08.
        //  Copyright 2008 __MyCompanyName__. All rights reserved.
        //
    
        #import "SKDatabase.h"
    
        @implementation SKDatabase
    
        @synthesize delegate;
        @synthesize dbh;
        @synthesize dynamic;
    
        // Two ways to init: one if you're just SELECTing from a database, one if you're UPDATing
        // and or INSERTing
    
        - (id)initWithFile:(NSString *)dbFile {
            if (self = [super init]) {
    
                NSString *paths = [[NSBundle mainBundle] resourcePath];
                NSString *path = [paths stringByAppendingPathComponent:dbFile];
    
                int result = sqlite3_open([path UTF8String], &dbh);
                NSAssert1(SQLITE_OK == result, NSLocalizedStringFromTable(@"Unable to open the sqlite database (%@).", @"Database", @""), [NSString stringWithUTF8String:sqlite3_errmsg(dbh)]); 
                self.dynamic = NO;
            }
    
            return self;    
        }
    
        - (id)initWithDynamicFile:(NSString *)dbFile {
            if (self = [super init]) {
    
                NSArray *docPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
                NSString *docDir = [docPaths objectAtIndex:0];
                NSString *docPath = [docDir stringByAppendingPathComponent:dbFile];
    
                NSFileManager *fileManager = [NSFileManager defaultManager];
    
                if (![fileManager fileExistsAtPath:docPath]) {
    
                    NSString *origPaths = [[NSBundle mainBundle] resourcePath];
                    NSString *origPath = [origPaths stringByAppendingPathComponent:dbFile];
    
                    NSError *error;
                    int success = [fileManager copyItemAtPath:origPath toPath:docPath error:&error];            
                    NSAssert1(success,[NSString stringWithString:@"Failed to copy database into dynamic location"],error);
                }
                int result = sqlite3_open([docPath UTF8String], &dbh);
                NSAssert1(SQLITE_OK == result, NSLocalizedStringFromTable(@"Unable to open the sqlite database (%@).", @"Database", @""), [NSString stringWithUTF8String:sqlite3_errmsg(dbh)]); 
                self.dynamic = YES;
            }
    
            return self;    
        }
    
        // Users should never need to call prepare
    
        - (sqlite3_stmt *)prepare:(NSString *)sql {
    
            const char *utfsql = [sql UTF8String];
    
            sqlite3_stmt *statement;
    
            if (sqlite3_prepare([self dbh],utfsql,-1,&statement,NULL) == SQLITE_OK) {
                return statement;
            } else {
                return 0;
            }
        }
    
        // Three ways to lookup results: for a variable number of responses, for a full row
        // of responses, or for a singular bit of data
    
        - (NSArray *)lookupAllForSQL:(NSString *)sql {
            sqlite3_stmt *statement;
            id result;
            NSMutableArray *thisArray = [NSMutableArray arrayWithCapacity:4];
            if (statement = [self prepare:sql]) {
                while (sqlite3_step(statement) == SQLITE_ROW) { 
                    NSMutableDictionary *thisDict = [NSMutableDictionary dictionaryWithCapacity:4];
                    for (int i = 0 ; i < sqlite3_column_count(statement) ; i++) 
                    {
                        if (sqlite3_column_decltype(statement,i) != NULL &&
                            strcasecmp(sqlite3_column_decltype(statement,i),"Boolean") == 0)
                        {
                            result = [NSNumber numberWithBool:(BOOL)sqlite3_column_int(statement,i)];
                        } 
                        else if (sqlite3_column_type(statement, i) == SQLITE_TEXT)
                        {
                            result = [NSString stringWithUTF8String:(char *)sqlite3_column_text(statement,i)];
                        } 
                        else if 
                            (sqlite3_column_type(statement,i) == SQLITE_INTEGER)
                        {
                            result = [NSNumber numberWithInt:(int)sqlite3_column_int(statement,i)];
                        } 
                        else if (sqlite3_column_type(statement,i) == SQLITE_FLOAT)
                        {
                            result = [NSNumber numberWithFloat:(float)sqlite3_column_double(statement,i)];                  
                        }
                        else 
                        {
                            result = [NSString stringWithUTF8String:(char *)sqlite3_column_text(statement,i)];
                        }
                        if (result) 
                        {
                            [thisDict setObject:result
                                         forKey:[NSString stringWithUTF8String:sqlite3_column_name(statement,i)]];
                        }
                    }
                    [thisArray addObject:[NSDictionary dictionaryWithDictionary:thisDict]];
                    [thisArray retain];
                }
            }
            sqlite3_finalize(statement);
            return thisArray;
        }
    
        - (NSDictionary *)lookupRowForSQL:(NSString *)sql {
            sqlite3_stmt *statement;
            id result;
            NSMutableDictionary *thisDict = [NSMutableDictionary dictionaryWithCapacity:4];
            if (statement = [self prepare:sql]) 
            {
                if (sqlite3_step(statement) == SQLITE_ROW) 
                {   
                    for (int i = 0 ; i < sqlite3_column_count(statement) ; i++) 
                    {
                        if (strcasecmp(sqlite3_column_decltype(statement,i),"Boolean") == 0)
                        {
                            result = [NSNumber numberWithBool:(BOOL)sqlite3_column_int(statement,i)];
                        } 
                        else if (sqlite3_column_type(statement, i) == SQLITE_TEXT) 
                        {
                            result = [NSString stringWithUTF8String:(char *)sqlite3_column_text(statement,i)];
                        } 
                        else if (sqlite3_column_type(statement,i) == SQLITE_INTEGER)
                        {
                            result = [NSNumber numberWithInt:(int)sqlite3_column_int(statement,i)];
                        } 
                        else if (sqlite3_column_type(statement,i) == SQLITE_FLOAT)
                        {
                            result = [NSNumber numberWithFloat:(float)sqlite3_column_double(statement,i)];                  
                        } 
                        else 
                        {
                            result = [NSString stringWithUTF8String:(char *)sqlite3_column_text(statement,i)];
                        }
                        if (result) 
                        {
                            [thisDict setObject:result
                                         forKey:[NSString stringWithUTF8String:sqlite3_column_name(statement,i)]];
                        }
                    }
                }
            }
            sqlite3_finalize(statement);
            return thisDict;
        }
    
        - (id)lookupColForSQL:(NSString *)sql {
    
            sqlite3_stmt *statement;
            id result;
            if (statement = [self prepare:sql]) {
                if (sqlite3_step(statement) == SQLITE_ROW) {        
                    if (strcasecmp(sqlite3_column_decltype(statement,0),"Boolean") == 0) {
                        result = [NSNumber numberWithBool:(BOOL)sqlite3_column_int(statement,0)];
                    } else if (sqlite3_column_type(statement, 0) == SQLITE_TEXT) {
                        result = [NSString stringWithUTF8String:(char *)sqlite3_column_text(statement,0)];
                    } else if (sqlite3_column_type(statement,0) == SQLITE_INTEGER) {
                        result = [NSNumber numberWithInt:(int)sqlite3_column_int(statement,0)];
                    } else if (sqlite3_column_type(statement,0) == SQLITE_FLOAT) {
                        result = [NSNumber numberWithDouble:(double)sqlite3_column_double(statement,0)];                    
                    } else {
                        result = [NSString stringWithUTF8String:(char *)sqlite3_column_text(statement,0)];
                    }
                }
            }
            sqlite3_finalize(statement);
            return result;
    
        }
    
        // Simple use of COUNTS, MAX, etc.
    
        - (int)lookupCountWhere:(NSString *)where forTable:(NSString *)table {
    
            int tableCount = 0;
            NSString *sql = [NSString stringWithFormat:@"SELECT COUNT(*) FROM %@ WHERE %@",
                             table,where];      
            sqlite3_stmt *statement;
    
            if (statement = [self prepare:sql]) {
                if (sqlite3_step(statement) == SQLITE_ROW) {        
                    tableCount = sqlite3_column_int(statement,0);
                }
            }
            sqlite3_finalize(statement);
            return tableCount;
    
        }
    
        - (int)lookupMax:(NSString *)key Where:(NSString *)where forTable:(NSString *)table {
    
            int tableMax = 0;
            NSString *sql = [NSString stringWithFormat:@"SELECT MAX(%@) FROM %@ WHERE %@",
                             key,table,where];      
            sqlite3_stmt *statement;
            if (statement = [self prepare:sql]) {
                if (sqlite3_step(statement) == SQLITE_ROW) {        
                    tableMax = sqlite3_column_int(statement,0);
                }
            }
            sqlite3_finalize(statement);
            return tableMax;
    
        }
    
        - (int)lookupSum:(NSString *)key Where:(NSString *)where forTable:(NSString *)table {
    
            int tableSum = 0;
            NSString *sql = [NSString stringWithFormat:@"SELECT SUM(%@) FROM %@ WHERE %@",
                             key,table,where];      
            sqlite3_stmt *statement;
            if (statement = [self prepare:sql]) {
                if (sqlite3_step(statement) == SQLITE_ROW) {        
                    tableSum = sqlite3_column_int(statement,0);
                }
            }
            sqlite3_finalize(statement);
            return tableSum;
    
        }
    
        // INSERTing and UPDATing
    
        - (void)insertArray:(NSArray *)dbData forTable:(NSString *)table {
    
        //  NSMutableString *sql = [NSMutableString stringWithCapacity:16];
        //  [sql appendFormat:@"INSERT INTO %@ (",table];
        //  
        //  
        //  for (int i = 0 ; i < [dbData count] ; i++) {
        //      NSLog(@"%@",[[dbData objectAtIndex:i] objectForKey:@"mid"]);
        //      [sql appendFormat:@"%@",[[dbData objectAtIndex:i] objectForKey:@"key"]];
        //      if (i + 1 < [dbData count]) {
        //          [sql appendFormat:@", "];
        //      }
        //  }
        //  [sql appendFormat:@") VALUES("];
        //  for (int i = 0 ; i < [dbData count] ; i++) {
        //      if ([[[dbData objectAtIndex:i] objectForKey:@"value"] intValue]) {
        //          [sql appendFormat:@"%@",[[[dbData objectAtIndex:i] objectForKey:@"value"] intValue]];
        //      } else {
        //          [sql appendFormat:@"'%@'",[[dbData objectAtIndex:i] objectForKey:@"value"]];
        //      }
        //      if (i + 1 < [dbData count]) {
        //          [sql appendFormat:@", "];
        //      }
        //  }
        //  [sql appendFormat:@")"];
        //  [self runDynamicSQL:sql forTable:table];
            for(int i=0;i<[dbData count];i++)
            {
                NSDictionary *dict=[dbData objectAtIndex:i];
                NSMutableString *sql = [NSMutableString stringWithCapacity:16];
                [sql appendFormat:@"INSERT INTO %@ (",table];
    
                NSArray *dataKeys = [dict allKeys];
                for (int i = 0 ; i < [dataKeys count] ; i++) {
                    [sql appendFormat:@"%@",[dataKeys objectAtIndex:i]];
                    if (i + 1 < [dataKeys count]) {
                        [sql appendFormat:@", "];
                    }
                }
    
                [sql appendFormat:@") VALUES("];
                for (int i = 0 ; i < [dataKeys count] ; i++) {
                    if ([[dict objectForKey:[dataKeys objectAtIndex:i]] intValue]) {
                        [sql appendFormat:@"%@",[dict objectForKey:[dataKeys objectAtIndex:i]]];
                    } else {
                        [sql appendFormat:@"'%@'",[dict objectForKey:[dataKeys objectAtIndex:i]]];
                    }
                    if (i + 1 < [dict count]) {
                        [sql appendFormat:@", "];
                    }
                }
    
                [sql appendFormat:@")"];
                [self runDynamicSQL:sql forTable:table];
            }
        }
    
        - (void)insertDictionary:(NSDictionary *)dbData forTable:(NSString *)table {
    
            NSMutableString *sql = [NSMutableString stringWithCapacity:16];
            [sql appendFormat:@"INSERT INTO %@ (",table];
    
            NSArray *dataKeys = [dbData allKeys];
            for (int i = 0 ; i < [dataKeys count] ; i++) {
                [sql appendFormat:@"%@",[dataKeys objectAtIndex:i]];
                if (i + 1 < [dbData count]) {
                    [sql appendFormat:@", "];
                }
            }
    
            [sql appendFormat:@") VALUES("];
            for (int i = 0 ; i < [dataKeys count] ; i++) {
                //if ([[dbData objectForKey:[dataKeys objectAtIndex:i]] intValue]) {
        //          [sql appendFormat:@"%@",[dbData objectForKey:[dataKeys objectAtIndex:i]]];
        //      } else {
    
                [sql appendFormat:@"'%@'",[dbData objectForKey:[dataKeys objectAtIndex:i]]];
                //}
                if (i + 1 < [dbData count]) {
                    [sql appendFormat:@", "];
                }
            }
    
            [sql appendFormat:@")"];
            [self runDynamicSQL:sql forTable:table];
        }
    
        - (void)updateArray:(NSArray *)dbData forTable:(NSString *)table { 
            [self updateArray:dbData forTable:table where:NULL];
        }
    
        - (void)updateArray:(NSArray *)dbData forTable:(NSString *)table where:(NSString *)where {
    
            NSMutableString *sql = [NSMutableString stringWithCapacity:16];
            [sql appendFormat:@"UPDATE %@ SET ",table];
    
            for (int i = 0 ; i < [dbData count] ; i++) {
                if ([[[dbData objectAtIndex:i] objectForKey:@"value"] intValue]) {
                    [sql appendFormat:@"%@=%@",
                     [[dbData objectAtIndex:i] objectForKey:@"key"],
                     [[dbData objectAtIndex:i] objectForKey:@"value"]];
                } else {
                    [sql appendFormat:@"%@='%@'",
                     [[dbData objectAtIndex:i] objectForKey:@"key"],
                     [[dbData objectAtIndex:i] objectForKey:@"value"]];
                }       
                if (i + 1 < [dbData count]) {
                    [sql appendFormat:@", "];
                }
            }
            if (where != NULL) {
                [sql appendFormat:@" WHERE %@",where];
            } else {
                [sql appendFormat:@" WHERE 1",where];
            }       
            [self runDynamicSQL:sql forTable:table];
        }
    
        - (void)updateDictionary:(NSDictionary *)dbData forTable:(NSString *)table { 
            [self updateDictionary:dbData forTable:table where:NULL];
        }
    
        - (void)updateDictionary:(NSDictionary *)dbData forTable:(NSString *)table where:(NSString *)where {
    
            NSMutableString *sql = [NSMutableString stringWithCapacity:16];
            [sql appendFormat:@"UPDATE %@ SET ",table];
    
            NSArray *dataKeys = [dbData allKeys];
            for (int i = 0 ; i < [dataKeys count] ; i++) {
                if ([[dbData objectForKey:[dataKeys objectAtIndex:i]] intValue]) {
                    [sql appendFormat:@"%@=%@",
                     [dataKeys objectAtIndex:i],
                     [dbData objectForKey:[dataKeys objectAtIndex:i]]];
                } else {
                    [sql appendFormat:@"%@='%@'",
                     [dataKeys objectAtIndex:i],
                     [dbData objectForKey:[dataKeys objectAtIndex:i]]];
                }       
                if (i + 1 < [dbData count]) {
                    [sql appendFormat:@", "];
                }
            }
            if (where != NULL) {
                [sql appendFormat:@" WHERE %@",where];
            }
            [self runDynamicSQL:sql forTable:table];
        }
    
        - (void)updateSQL:(NSString *)sql forTable:(NSString *)table {
            [self runDynamicSQL:sql forTable:table];
        }
    
        - (void)deleteWhere:(NSString *)where forTable:(NSString *)table {
    
            NSString *sql = [NSString stringWithFormat:@"DELETE FROM %@ WHERE %@",
                             table,where];
            [self runDynamicSQL:sql forTable:table];
        }
    
        // INSERT/UPDATE/DELETE Subroutines
    
        - (BOOL)runDynamicSQL:(NSString *)sql forTable:(NSString *)table {
    
            int result;
            //NSAssert1(self.dynamic == 1,[NSString stringWithString:@"Tried to use a dynamic function on a static database"],NULL);
            sqlite3_stmt *statement;
            if (statement = [self prepare:sql]) {
                result = sqlite3_step(statement);
            }       
            sqlite3_finalize(statement);
            if (result) {
                if (self.delegate != NULL && [self.delegate respondsToSelector:@selector(databaseTableWasUpdated:)]) {
                    [delegate databaseTableWasUpdated:table];
                }   
                return YES;
            } else {
                return NO;
            }
    
        }
    
        // requirements for closing things down
    
        - (void)dealloc {
            [self close];
            [delegate release];
            [super dealloc];
        }
    
        - (void)close {
    
            if (dbh) {
                sqlite3_close(dbh);
            }
        }
    
        @end
    
    // Create Database file
    
    - (void)createEditableCopyOfDatabaseIfNeeded
    {
        // First, test for existence.
        BOOL success;
        NSFileManager *fileManager = [NSFileManager defaultManager];
        NSError *error;
        NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
        NSString *documentsDirectory = [paths objectAtIndex:0];
        NSLog(@"%@",documentsDirectory);
        NSString *writableDBPath = [documentsDirectory stringByAppendingPathComponent:@"TestDB.sqlite"];
        success = [fileManager fileExistsAtPath:writableDBPath];
        if (success) return;
    
        // The writable database does not exist, so copy the default to the appropriate location.
    
        NSString *defaultDBPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"TestDB.sqlite"];
        success = [fileManager copyItemAtPath:defaultDBPath toPath:writableDBPath error:&error];
        if (!success) {
            NSAssert1(0, @"Failed to create writable database file with message '%@'.", [error localizedDescription]);
        }
    }