views:

1016

answers:

3

I want to open my SQLite database in my appDelegate class and reference that database in all my other classes that need the database. I have tried using : static sqlite3 *database = nil;

But when I try to reference it in my other classes with appDelegate.database, I get a compile error of "error: request for member 'database' in something not a structure or union." How do you reference these types of properies?

+4  A: 

You should access any variables stored in the app Delegate through the follow general formula:

YourAppDelegateName *delegate = (YourAppDelegateName *)[[UIApplication sharedApplication]delegate];
//access specific variables in delegate as follows:
sqlite3 *temp = delegate.database;
zPesk
A: 

I suggest you to use the FMDB Objective C wrapper for sqlite. It will really simplify the access to your sqlite database. You can download it from

http://code.google.com/p/flycode/source/browse/trunk/fmdb#fmdb/src

Then,

you can use the following sample code, and use a NSString *db_path variable to access your db from other classes (you use your app delegate to access db_path, then use

FMDatabase *db = [FMDatabase databaseWithPath:db_path];

to acces your db. See the sample code below.

  • (NSString *) initialize_db { NSString *DATABASE_RESOURCE_NAME = @"yourDbName"; NSString *DATABASE_RESOURCE_TYPE = @"db"; NSString *DATABASE_FILE_NAME = @"yourDbName.db";

    // copy the database from the bundle if necessary // look to see if DB is in known location (~/Documents/$DATABASE_FILE_NAME) NSArray *searchPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); NSString *documentFolderPath = [searchPaths objectAtIndex: 0]; NSString *dbFilePath = [documentFolderPath stringByAppendingPathComponent: DATABASE_FILE_NAME]; [dbFilePath retain];

    if (! [[NSFileManager defaultManager] fileExistsAtPath: dbFilePath]) { // didn't find db, need to copy NSString *backupDbPath = [[NSBundle mainBundle] pathForResource:DATABASE_RESOURCE_NAME ofType:DATABASE_RESOURCE_TYPE]; if (backupDbPath == nil) { // couldn't find backup db to copy, bail NSLog (@"couldn't init db"); return NULL; } else { BOOL copiedBackupDb = [[NSFileManager defaultManager] copyItemAtPath:backupDbPath toPath:dbFilePath error:nil]; if (! copiedBackupDb) { // copying backup db failed, bail NSLog (@"couldn't init db"); return NULL; } } }

    return dbFilePath;

}

  • (void)applicationDidFinishLaunching:(UIApplication *)application {

    FMResultSet *item_rs;

    // copy the database from the bundle if necessary db_path = [self initialize_db]; if (! db_path) { // TODO: alert the user! NSLog (@"couldn't init db"); return; }

    FMDatabase *db = [FMDatabase databaseWithPath:db_path]; if (![db open]) { NSLog(@"Could not open the db"); }

    FMResultSet *rs = [db executeQuery:@"select * from yourTable"]; if ([db hadError]) { NSLog(@"Err %d: %@", [db lastErrorCode], [db lastErrorMessage]); }

    while ([rs next]) { [yourArray addObject:[rs stringForColumn:@"yourColumnName"]];

    }

    [rs close];

    [db close];

    // Configure and show the window [window addSubview:[navigationController view]]; [window makeKeyAndVisible]; }

unforgiven
A: 

I needed to create an instance property for the database. My assumption that the static declaration was sufficient was incorrect. BTW, the FMDB/ORM advice is great. I am a huge fan of ORMs. However, this project is my first iphone and it is a small amount of database work and I want to learn. So, I am going to do it old school. Thanks for the advice.

Here are the code changes I made to make my global reference work.. Hope it helps someone:

/* myAppDelegate.h file */

import

@interface myAppDelegate : NSObject { ... // you may have windows etc here sqlite3 *database;

}

@property (readwrite) sqlite3 *database;

/* myAppDelegate.m file */ @implementation myAppDelegate ... @synthesize database;

/* some method in some class that uses the database */ - (void) getSomeData { myAppDelegate *appDelegate = (myAppDelegate *) [[ UIApplication sharedApplication ] delegate ];

const char *sql = "SELECT * FROM myTable";
 sqlite3_stmt *selectstmt;
 if(sqlite3_prepare_v2(appDelegate.database, sql, -1, &selectstmt, NULL) == SQLITE_OK)

{ // get the data here. }

}