从支持文件中的Sqlite更改为URL中的Sqlite

时间:2012-08-05 18:36:03

标签: iphone xcode

为了测试目的,我一直在我的应用程序的支持文件中删除我的sqlite数据库。我目前正在尝试将其移至URL,因此我将能够在不更新应用程序的情况下更新数据库。我正在使用以下代码,它似乎正在工作,因为它将文件下载到文档目录。问题是我从支持文件中删除了旧数据库,它的数据仍在被提取。我对我的数据库进行了更改,因此我知道其中的差异。

我需要清理一些记忆吗?如果不是我在这里错过了什么。

- (void)viewDidLoad
{
    [super viewDidLoad];

    NSString *file = [NSString stringWithFormat:@"http://www.myurl/TulsaListBars.sqlite"];
    NSURL *fileURL = [NSURL URLWithString:file];

    NSURLRequest *req = [NSURLRequest requestWithURL:fileURL];
    NSURLConnection *conn = [NSURLConnection connectionWithRequest:req delegate:self];

    fileData = [NSMutableData data];
}

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
    [fileData setLength:0];
    totalFileSize = [NSNumber numberWithLongLong:[response expectedContentLength]];
}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
    [fileData appendData:data];
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
    NSArray *dirArray = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,    NSUserDomainMask, YES);
    NSLog(@"%@", [dirArray objectAtIndex:0]);

    NSString *path = [NSString stringWithFormat:@"%@/TulsaListBar.sqlite", [dirArray objectAtIndex:0]];

    if ([fileData writeToFile:path options:NSAtomicWrite error:nil] == NO) {
        NSLog(@"writeToFile error");
    }
    else {
        NSLog(@"Written!");
    }
}

以下代码是我阅读数据库的方式。

-(NSMutableArray *) barList{
    thebars = [[NSMutableArray alloc] init];
    @try {
        NSFileManager *fileMgr = [NSFileManager defaultManager];
        NSString *dbPath = [[[NSBundle mainBundle] resourcePath ]stringByAppendingPathComponent:@"TulsaListBars.sqlite"];
        BOOL success = [fileMgr fileExistsAtPath:dbPath];
        if(!success)
        {
            NSLog(@"Cannot locate database file '%@'.", dbPath);
        }else{
            NSLog(@"File Exists: %@", dbPath);
        }
        if(!(sqlite3_open([dbPath UTF8String], &db) == SQLITE_OK))
        {
            NSLog(@"An error has occured: %s", sqlite3_errmsg(db));

        }       

        const char *sql = "SELECT * FROM Locations WHERE bar = 'yes'";
        sqlite3_stmt *sqlStatement;
        if(sqlite3_prepare(db, sql, -1, &sqlStatement, NULL) != SQLITE_OK)
        {
            NSLog(@"Problem with prepare statement:  %s", sqlite3_errmsg(db));
        }else{

            while (sqlite3_step(sqlStatement)==SQLITE_ROW) {
                Bar * bar = [[Bar alloc] init];
                bar.barName = [NSString stringWithUTF8String:(char *) sqlite3_column_text(sqlStatement,1)];
                bar.barAddress = [NSString stringWithUTF8String:(char *) sqlite3_column_text(sqlStatement,2)];

                etc.....

2 个答案:

答案 0 :(得分:0)

数据库的旧副本仍在文档目录中。如果您写入文件并且该文件已存在,writeToFile:应覆盖它,但当然它必须具有相同的名称/路径。

解决方案:只需从模拟器/设备中删除该应用,然后再次运行您的应用。此外,请确保在打开数据库时寻址正确的路径。

答案 1 :(得分:0)

请记住,您无法写入应用程序的捆绑包,并且文档文件夹与此文件夹是分开的。您的代码示例未显示数据库的打开方式,因此无论下载的文件是什么,都可能从捆绑包中打开它。更好的方法是将数据库打开代码放入didFinishLoading委托方法中,并在那里使用下载文件的路径。