2009-04-26 7 views
2

Je veux ouvrir ma base de données SQLite dans ma classe appDelegate et référencer cette base de données dans toutes mes autres classes qui ont besoin de la base de données. J'ai essayé d'utiliser: static sqlite3 * database = nil; Mais quand j'essaie de le référencer dans mes autres classes avec appDelegate.database, j'obtiens une erreur de compilation de "error: request for member 'database' dans quelque chose qui n'est ni une structure ni une union." Comment faites-vous référence à ces types de propriétés?iphone variable globale

Répondre

6

Vous devriez accéder à toutes les variables stockées dans le délégué de l'application par la suite formule générale:

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

Je vous suggère d'utiliser l'emballage Objectif C FMDB pour SQLite. Cela va vraiment simplifier l'accès à votre base de données sqlite. Vous pouvez le télécharger à partir

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

Ensuite,

vous pouvez utiliser le code exemple suivant, et utiliser un NSString * variable db_path pour accéder à votre db à partir d'autres classes (vous utilisez votre délégué app pour accéder db_path, puis utilisez

FMDatabase *db = [FMDatabase databaseWithPath:db_path]; 

pour votre acces db. Voir l'exemple de code ci-dessous.

- (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]; 
} 
1

J'avais besoin de créer une propriété d'instance pour la base de données. Ma supposition que la déclaration statique était suffisante était incorrecte. BTW, le conseil FMDB/ORM est génial. Je suis un grand fan des ORM. Cependant, ce projet est mon premier iphone et c'est une petite quantité de travail de base de données et je veux apprendre. Donc, je vais le faire vieille école. Merci pour le conseil.

Voici les modifications de code que j'ai fait pour faire mon travail global de référence .. il aide quelqu'un l'espoir:

/* myAppDelegate.h file */ 
#import <sqlite3.h> 

@interface myAppDelegate : NSObject <UIApplicationDelegate> { 
... // 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. 
} 

} 
Questions connexes