iOS在为SQLite记录添加书签时遇到问题

时间:2012-09-22 16:45:16

标签: iphone objective-c ios xcode ipad

我创建了一个包含多个数据库的字典应用程序,除了在书签中保存列外,一切正常!我知道,它不可能在NSBundle中更改文件,但我不知道如何解决它。如果您在这里帮助我,我将不胜感激:

- (NSString *) getDBPath {
    NSString *path;

    if ( [[[NSUserDefaults standardUserDefaults] stringForKey:@"Bv"] intValue] == 2)
    {
        path = [[NSBundle mainBundle]pathForResource:@"pr-eng" ofType:@"sqlite"];

    } else {

        path = [[NSBundle mainBundle]pathForResource:@"eg-pr" ofType:@"sqlite"];
    }

    if ( [[[NSUserDefaults standardUserDefaults] stringForKey:@"Bv"] intValue] == 3)
    {
        path = [[NSBundle mainBundle]pathForResource:@"german" ofType:@"sqlite"];
    }

    return path;    
}

这是书签功能:

-(void) setBookMark:(NSInteger)oid {

sqlite3_stmt    *statement;

const char *dbpath = [[self getDBPath] UTF8String];

if (sqlite3_open(dbpath, &database) == SQLITE_OK)
{
    NSString *SetFavSQL = [NSString stringWithFormat: @"UPDATE DIC SET bookmark=1 WHERE id=\"%d\"", oid];
    //      NSLog(@"%@",SetFavSQL);
    const char *SetFav_stmt = [SetFavSQL UTF8String];

    sqlite3_prepare_v2(database, SetFav_stmt, -1, &statement, NULL);
    if (sqlite3_step(statement) != SQLITE_DONE)
    {

    }
    sqlite3_finalize(statement);
    sqlite3_close(database);
}
}

阅读数据库:

-(void) read_Database{

NSMutableArray *DB_Array = [[NSMutableArray alloc] init];
NSMutableArray *word_Array = [[NSMutableArray alloc] init];

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

    NSString *sql =@"SELECT * FROM DIC";

    //        NSLog(@"%@",sql);

    sqlite3_stmt *compiledStatement;

    if(sqlite3_prepare_v2(database, [sql UTF8String] , -1, &compiledStatement, NULL) == SQLITE_OK) {
        while(sqlite3_step(compiledStatement) == SQLITE_ROW) {


            NSInteger oid = sqlite3_column_int(compiledStatement, 0);

            const char* f1 = (const char*)sqlite3_column_text(compiledStatement, 1);
            NSString *oName = f1 == NULL ? nil : [[NSString alloc] initWithUTF8String:f1];

            const char* f2 = (const char*)sqlite3_column_text(compiledStatement, 2);
            NSString *oMean = f2 == NULL ? nil : [[NSString alloc] initWithUTF8String:f2];


            const char* f3 = (const char*)sqlite3_column_text(compiledStatement, 3);
            NSString *oPron = f3 == NULL ? nil : [[NSString alloc] initWithUTF8String:f3];

            NSInteger bm = sqlite3_column_int(compiledStatement, 5);

            readerClass = [[Reader alloc]initWithReadDB:oid Name:oName Mean:oMean Pron:oPron bookMark:bm];

            [DB_Array addObject:readerClass];
        }
    }
    sqlite3_finalize(compiledStatement);

}
sqlite3_close(database);


AppDelegate *appDelegateClass = (AppDelegate *)[[UIApplication sharedApplication] delegate];

[appDelegateClass.wordList removeAllObjects];
appDelegateClass.wordList=[word_Array mutableCopy];


[appDelegateClass.dictionaryArray removeAllObjects];
appDelegateClass.dictionaryArray=[DB_Array mutableCopy];
}

3 个答案:

答案 0 :(得分:2)

  

我知道,在NSBundle中无法更改文件

很好,至少你努力谷歌这个问题。那么,为什么不直接复制这些文件,以便在第一次启动应用程序时更新到某些可写路径,如NSDocumentsDirectory?

NSArray *paths = NSSearchPathsForDirectoriesInDomains(NSDocumentsDirectory, NSUserDomainMask, YES);
NSString *docsDir = [paths objectAtIndex:0];
[[NSFileManager defaultManager] copyItemAtPath:path toPath:[docsDir stringByAppendingPathComponent:@"db.sql"] error:NULL];

答案 1 :(得分:0)

为了进一步改进@ H2CO3的答案并进一步澄清,我发表了我的答案:)

以下是我在iPhone或iPad(iOS)上将数据保存到数据库的操作。所有数据都保存在本地设备中。因此,如果卸载应用程序,则所有数据都将丢失,如果用户没有备份应用程序并从备份恢复,则会丢失。

NSFileManager *fileMgr;
NSString *homeDir;

这些是我在下面的函数中使用的ivar所有函数都在我的.m文件中,它包含我的所有数据库相关函数,如update,insert,select,delete。

-(void)CopyDbToDocumentsFolder
{
    NSError *err=nil;
    fileMgr = [NSFileManager defaultManager];
    NSString *dbpath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"res_in_mil.sqlite"];
    NSString *copydbpath = [self.GetDocumentDirectory stringByAppendingPathComponent:@"res_in_mil.sqlite"];
    [fileMgr removeItemAtPath:copydbpath error:&err];
    if(![fileMgr copyItemAtPath:dbpath toPath:copydbpath error:&err])
    {
        UIAlertView *tellErr = [[UIAlertView alloc] initWithTitle:title message:@"Unable to copy database." delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
        [tellErr show];

    }
}
-(NSString *) GetDocumentDirectory
{
    fileMgr = [NSFileManager defaultManager];
    homeDir = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"];
    return homeDir;
}

由于名称是自我解释的,因此无需解释这些功能的用途。

在appDelegate.m中我使用下面的代码将我的数据库复制到我可以编辑数据库的指定位置。此代码位于- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions方法中。

NSFileManager *fileMgr;
myDB *dbObj = [[myDB alloc]init];
fileMgr = [NSFileManager defaultManager];
NSString *dbPath = [[dbObj GetDocumentDirectory] stringByAppendingPathComponent:@"res_in_mil.sqlite"];
BOOL success = [fileMgr fileExistsAtPath:dbPath];
if(!success)
    [dbObj CopyDbToDocumentsFolder]; 

我将它用于一个DB,因为我只有一个DB。但我认为你可以扩展这些功能来复制多个数据库。

即使您可以使用上面给出的- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions方法代码,使用一个函数来识别所需的DB在DocumentDirectory中。

对于插入,更新,删除,选择操作,我使用以下代码打开数据库以进行任何访问。

fileMgr = [NSFileManager defaultManager];
NSString *dbPath = [[self GetDocumentDirectory] stringByAppendingPathComponent:@"res_in_mil.sqlite"];
BOOL success = [fileMgr fileExistsAtPath:dbPath];

if(!success)
    {
        NSLog(@"Cannot locate database file '%@'",dbPath);
        [self CopyDbToDocumentsFolder];
    }

快乐编码:)

答案 2 :(得分:0)

我认为你必须只创建一个主数据库,并且可以有多个表。这可以解决您的问题。