Creating a singleton DB helper class - ios

I am trying to write a Master-Detail application that gets it's data from a sqlite database. As part of this I'm trying to create a helper class that creates a singleton instance of my database. All I want it to do is initialise the database so I can then reference this from the different views of the application.
I followed a tutorial that does this here: http://www.raywenderlich.com/913/sqlite-101-for-iphone-developers-making-our-app
I got the tutorial to work however now I am trying to modify it to fit my application and I can't seem to get it working. I have no errors or warnings but when I run the app on the emulator none of the debug text I have put in executes. So it looks to me like my init function is not executing. I just can't figure out why.
Can anyone spot my problem in the code below?
LoyaltyProgramDatabase.h
#import <Foundation/Foundation.h>
#import <sqlite3.h>
#interface LoyaltyProgramDatabase : NSObject {
sqlite3 *_loyaltyProgDB;
}
#property (strong, nonatomic) NSString *databasePath; //Path file of our database
#property (nonatomic) sqlite3 *loyaltyProgDB; //Reference to the database
+ (LoyaltyProgramDatabase*)loyaltyProgDB;
#end
LoyaltyProgramDatabase.m
#import "LoyaltyProgramDatabase.h"
#implementation LoyaltyProgramDatabase
static LoyaltyProgramDatabase *_loyaltyProgDB;
//Create a singleton instance of loyaltyProgDB
+ (LoyaltyProgramDatabase*)loyaltyProgDB {
if (_loyaltyProgDB == nil) {
_loyaltyProgDB = [[LoyaltyProgramDatabase alloc] init];
}
return _loyaltyProgDB;
}
- (id)init {
NSLog(#"Inside init function");
if ((self = [super init])) {
NSString *docsDir;
NSArray *dirPaths;
// Get the documents directory
dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
docsDir = dirPaths[0];
// Build the path to the database file
_databasePath = [[NSString alloc] initWithString: [docsDir stringByAppendingPathComponent:#"loyaltyProg.db"]];
NSFileManager *filemgr = [NSFileManager defaultManager];
if ([filemgr fileExistsAtPath: _databasePath ] == NO)
{
const char *dbpath = [_databasePath UTF8String];
if (sqlite3_open(dbpath, &_loyaltyProgDB) == SQLITE_OK)
{
char *errMsg;
const char *sql_stmt = "CREATE TABLE IF NOT EXISTS scoreCard (ID INTEGER PRIMARY KEY AUTOINCREMENT, campaignID INTEGER, merchantName TEXT)";
if (sqlite3_exec(_loyaltyProgDB, sql_stmt, NULL, NULL, &errMsg) != SQLITE_OK)
{
//_status.text = #"Failed to create table";
NSLog(#"Failed to create table");
}
sqlite3_close(_loyaltyProgDB);
} else {
//_status.text = #"Failed to open/create database";
NSLog(#"Failed to open/create database");
}
}
}
return self;
}
- (void)dealloc {
sqlite3_close(_loyaltyProgDB);
}
#end

Try this:
+ (id)allocWithZone:(NSZone *)zone
{
return [self loyaltyProgDB];
}
+ (LoyaltyProgramDatabase*)loyaltyProgDB
{
static BNRImageStore *loyaltyProgDB = nil;
if (!loyaltyProgDB) {
// Create the singleton
loyaltyProgDB = [[super allocWithZone:NULL] init];
}
return loyaltyProgDB;
}
- (id)init {
self = [super init];
if (self) {
NSString *docsDir;
NSArray *dirPaths;
// Get the documents directory
dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
docsDir = dirPaths[0];
// Build the path to the database file
_databasePath = [[NSString alloc] initWithString: [docsDir stringByAppendingPathComponent:#"loyaltyProg.db"]];
NSFileManager *filemgr = [NSFileManager defaultManager];
if ([filemgr fileExistsAtPath: _databasePath ] == NO)
{
const char *dbpath = [_databasePath UTF8String];
if (sqlite3_open(dbpath, &_loyaltyProgDB) == SQLITE_OK)
{
char *errMsg;
const char *sql_stmt = "CREATE TABLE IF NOT EXISTS scoreCard (ID INTEGER PRIMARY KEY AUTOINCREMENT, campaignID INTEGER, merchantName TEXT)";
if (sqlite3_exec(_loyaltyProgDB, sql_stmt, NULL, NULL, &errMsg) != SQLITE_OK)
{
//_status.text = #"Failed to create table";
NSLog(#"Failed to create table");
}
sqlite3_close(_loyaltyProgDB);
} else {
//_status.text = #"Failed to open/create database";
NSLog(#"Failed to open/create database");
}
}
}
return self;
}

If you have not written a line of code that says [[LoyaltyProgramDatabase alloc] init] or [LoyaltyProgramDatabase loyaltyProgDB], then your init function is never getting called.
The init is not automatically called when you start the app. The only time any init function is called automatically is if you have a UI element in a nib/xib/storyboard file, and the app creates the element utilizing various initialization functions, but never your own init function. But for something like what you have written, to initialize the database object, you need to call the init function yourself.
In your app delegate, under the didFinishLaunching function, put this line:
[LoyaltyProgramDatabase loyaltyProgDB];
This isn't a really up-to-date singleton pattern by the way. This is actually a lazy loader function. If you want a more secure singleton, use this code.
+(id)sharedInstance {
static dispatch_once_t pred = 0;
__strong static id _sharedObject = nil;
dispatch_once(&pred, ^{
_sharedObject = [[self alloc] init];
});
return _sharedObject;
}
This will make sure the database is only ever initialized once and it is thread safe. To create/use the singleton, the code would change from the above to
[LoyaltyProgramDatabase sharedInstance]

Related

no such table: tablename in sqlite even after initialization

i am new to ios dev and i am having the following problem:
i initialized the tables i needed, and when i try to execute a query to any of the tables i get the "no such table" error, here is the steps and code:
-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Function called to create a copy of the database if needed.
[[SQLiteUtilities sharedSQLiteManager] initializationDatabase];
return YES;
}
and here is the implementation:
-(void)initializationDatabase {
NSString *path = [self databaseFilePath];
BOOL isExists = [[NSFileManager defaultManager] fileExistsAtPath:path];
if (isExists) return;
FMDatabase *db = [FMDatabase databaseWithPath:path];
if ([db open] == NO) {
return;
}
NSString *sql =
#"CREATE TABLE albums("
"albumid INTEGER PRIMARY KEY AUTOINCREMENT,"
"directory CHAR(20) NOT NULL,"
"albumname CHAR(32) NOT NULL,"
"count INT NOT NULL,"
"orderid INT NOT NULL"
");"
"CREATE TABLE photos("
"photoid INTEGER PRIMARY KEY AUTOINCREMENT,"
"albumid INTEGER NOT NULL DEFAULT 0,"
"filename CHAR(50) NOT NULL DEFAULT \"\","
"originalname CHAR(50) DEFAULT \"\","
"addtime INTEGER NOT NULL DEFAULT 0,"
"createtime INTEGER NOT NULL DEFAULT 0,"
"filesize INTEGER NOT NULL DEFAULT 0"
");";
//[db executeQuery:sql1];
[db executeQuery:sql];
[db close];
}
and when i try to add anything as follows i get the "no such table:albums" error:
- (AlbumsUtilities *)createAlbumWithName:(NSString *)name {
FMDatabase *db = [FMDatabase databaseWithPath:[self databaseFilePath]];
if (![db open]) return nil;
NSString *directory = createRandomAlbumDirectory();
int maxid = 0;
BOOL success = [db executeUpdate:#"INSERT INTO albums(directory,albumname,count,orderid) VALUES(?,?,0,?)", directory,name,#(maxid)];
AlbumsUtilities *album = nil;
if (success) {
....(not getting here of course)
}
[db close];
return album;
}
any help would be appreciated, thanks.
Try this two function for initialize db .
ADD Blank File .sqlite extension
- (void)createCopyOfDatabaseIfNeeded {
// First, test for existence.
BOOL success;
NSFileManager *fileManager = [NSFileManager defaultManager];
NSError *error;
NSLog(#"%#",[self getDBPath]);
success = [fileManager fileExistsAtPath:[self getDBPath]];
if (success){
return;
}
// The writable database does not exist, so copy the default to the appropriate location.
NSString *defaultDBPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"db.sqlite"];
success = [fileManager copyItemAtPath:defaultDBPath toPath:[self getDBPath] error:&error];
if (!success) {
NSAssert1(0, #"Failed to create writable database file with message '%#'.", [error localizedDescription]);
}
}
-(NSString *)getDBPath{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docsPath = [paths objectAtIndex:0];
NSString *dbPath = [docsPath stringByAppendingPathComponent:#"db.sqlite"];
return dbPath;
}
After Initialize create table
-(void)createTable{
FMDatabase *database = [FMDatabase databaseWithPath:[self getDBPath]];
[database open];
[database executeUpdate:"your query"];
[database close];
}
Calling
-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Function called to create a copy of the database if needed.
[[SQLiteUtilities sharedSQLiteManager] createCopyOfDatabaseIfNeeded];
[[SQLiteUtilities sharedSQLiteManager] createTable];
}
#Try this:
Bool isSuccess = YES;
if (sqlite3_open(path, &db) == SQLITE_OK)
{
char *errMsg;
const char *sql_stmt =
"CREATE TABLE IF NOT EXISTS contactTable (albumid integer primary key autoincrement ,directory CHAR(20) NOT NULL, albumname CHAR(32) NOT NULL, albumname CHAR(32) NOT NULL, count INT NOT NULL, orderid INT NOT NULL);";
if (sqlite3_exec(db, sql_stmt, NULL, NULL, &errMsg)
!= SQLITE_OK)
{
sqlite3_close(db);
isSuccess = NO;
}
sqlite3_close(db);
return isSuccess;
}
else {
sqlite3_close(db);
isSuccess = NO;
}
}
sqlite3_close(db);
NSLog(#"Albums Table Created");
return isSuccess;

cannot create database table and insert in iOS sqlite3

I am new in iOS development. I am trying to do a simple todo list app. I am using xocde 8 and objective-C language . I tried several tutorial but could not create the database table. Here is my code.
-(void)createOrOpenDB{
printf("createOrOpenDB: into this function \n");
NSArray *docsDir = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *dirPaths = [docsDir objectAtIndex:0];
dbPathString = [[NSString alloc] initWithString: [dirPaths stringByAppendingPathComponent:#"person.db"]];
NSFileManager *fileManager = [NSFileManager defaultManager];
char *err;
printf("createOrOpenDB: into this function before if statement \n");
if(![fileManager fileExistsAtPath:dbPathString]){
const char *dbPath = [dbPathString UTF8String];
printf("createOrOpenDB: into this functions 1st if statement \n");
//create db here
if(sqlite3_open(dbPath, &personDB) ==SQLITE_OK){
const char *sql_stnt = "CREATE TABLE IF NOT EXISTS PERSONS (ID INTEGER PRIMARY KEY AUTOINCREMENT, NAME TEXT, AGE INTEGER)";
if(sqlite3_exec(personDB, sql_stnt, NULL, NULL, &err) !=SQLITE_OK){
printf("Failed to create table\n");
}
sqlite3_close(personDB);
printf("createOrOpenDB: database table created\n");
}
}
}
when i press the add button , its not giving me any error. but its not adding any data. NSLog in not working in xcode 8 . so i did printf instead . and my code breaks before the if statement . can anybody tell me what i am doing wrong?
do like this,
+(DBManager*)getSharedInstance{
if (!sharedInstance) {
sharedInstance = [[super allocWithZone:NULL]init];
[sharedInstance createDB];
}
return sharedInstance;
}
-(BOOL)createDB{
NSString *docsDir;
NSArray *dirPaths;
// Get the documents directory
dirPaths = NSSearchPathForDirectoriesInDomains
(NSDocumentDirectory, NSUserDomainMask, YES);
docsDir = dirPaths[0];
// Build the path to the database file
databasePath = [[NSString alloc] initWithString:
[docsDir stringByAppendingPathComponent: #"student.db"]];
BOOL isSuccess = YES;
NSFileManager *filemgr = [NSFileManager defaultManager];
if ([filemgr fileExistsAtPath: databasePath ] == YES)
{
const char *dbpath = [databasePath UTF8String];
if (sqlite3_open(dbpath, &database) == SQLITE_OK)
{
char *errMsg;
const char *sql_stmt = "create table if not exists studentsDetail (regno integer primary key, name text, department text, year text)";
if (sqlite3_exec(database, sql_stmt, NULL, NULL, &errMsg)
!= SQLITE_OK)
{
isSuccess = NO;
NSLog(#"Failed to create table");
}
else
{
NSLog(#"Table Created Successfully");
}
sqlite3_close(database);
return isSuccess;
}
else {
isSuccess = NO;
NSLog(#"Failed to open/create database");
}
sqlite3_finalize(statement);
}
return isSuccess;
// NSLog(#"database %#", isSuccess);
}
For saving the data in this table,
- (BOOL) saveData:(NSString*)registerNumber name:(NSString*)name
department:(NSString*)department year:(NSString*)year;
{
const char *dbpath = [databasePath UTF8String];
if (sqlite3_open(dbpath, &database) == SQLITE_OK)
{
NSString *insertSQL = [NSString stringWithFormat:#"insert into studentsDetail (regno,name, department, year) values (\"%ld\",\"%#\", \"%#\", \"%#\")",(long)[registerNumber integerValue], name, department, year];
const char *insert_stmt = [insertSQL UTF8String];
sqlite3_prepare_v2(database, insert_stmt,-1, &statement, NULL);
if (sqlite3_step(statement) == SQLITE_DONE)
{
return YES;
}
else {
return NO;
}
sqlite3_reset(statement);
}
return NO;
}
It will create table every time when table does not exist.
Hope t will help you.

Implicit conversion to an Objective-C pointer using SQLite3

I following old tutorial that use MRC, and when i pasted code i got an error: Implicit conversion to an Objective-C pointer using SQLite3 on a line:
if (sqlite3_open([sqLiteDb UTF8String], &_database) != SQLITE_OK) {
Full code snippet is :
static FailedBankDatabase *_database;
+ (FailedBankDatabase*)database {
if (_database == nil) {
_database = [[FailedBankDatabase alloc] init];
}
return _database;
}
- (id)init {
if ((self = [super init])) {
NSString *sqLiteDb = [[NSBundle mainBundle] pathForResource:#"banklist"
ofType:#"sqlite3"];
if (sqlite3_open([sqLiteDb UTF8String], &_database) != SQLITE_OK) {
NSLog(#"Failed to open database!");
}
}
return self;
}
Im not very keen in MRC, can you help me fix it?
The _database variable is your static reference to the FailedBankDatabase singleton. But you are also trying to use it to save the SQLite database reference. For that, you need an instance variable of type sqlite3 *.
Update your code to something like the following:
#implementation FailedBankDatabase {
sqlite3 *_db;
}
+ (FailedBankDatabase*)database {
static FailedBankDatabase *database = nil;
if (database == nil) {
database = [[FailedBankDatabase alloc] init];
}
return database;
}
- (id)init {
if ((self = [super init])) {
NSString *sqLiteDb = [[NSBundle mainBundle] pathForResource:#"banklist"
ofType:#"sqlite3"];
if (sqlite3_open([sqLiteDb UTF8String], &_db) != SQLITE_OK) {
NSLog(#"Failed to open database!");
}
}
return self;
}
Now use the _db variable for all database references in the various sqlite3_... function calls.
FYI - you should use a more modern approach to creating the singleton:
+ (FailedBankDatabase*)database {
static FailedBankDatabase *database = nil;
static dispatch_once_t predicate = 0;
dispatch_once(&predicate, ^{
database = [[FailedBankDatabase alloc] init];
});
return database;
}

sqlite3 prepare statement not working, possibly improper pointers iOS

I have setup a GlobalVars class to hold my sqlite3 database variable.
static sqlite3** database;
const char *dbPath;
#implementation GlobalVars : NSObject
+(GlobalVars*)sharedInstance {
static GlobalVars *myInstance = nil;
if(myInstance == nil) {
myInstance = [[[self class] alloc] init];
}
return myInstance;
}
+(sqlite3*)getGlobalDatabase {
return &database;
}
+(void)setGlobalDatabase:(sqlite3*)_database {
database = &_database;
}
Then in the header file I have
static sqlite3** database;
which is above the interface. This is how I setup my database variable.
I am then trying to access it when i open the database and prepare it. I can open it, because the open call returns true. I can not prepare it properly, because the statement returns false and it doesn't go into the if statement. I am wondering if I have messed up my pointers, because the prepare statement isn't working, and it doesn't prepare it properly.
-(void)setAllValues:(NSMutableArray*)array {
if(sqlite3_open([GlobalVars getGlobalDBPath], [GlobalVars getGlobalDatabase]) == SQLITE_OK) {
sqlite3_stmt *insertStatement;
NSString *sqlInsert = [NSString stringWithFormat:#"insert into my_table ('_id', 'name', 'age', 'weight', 'height', 'description') VALUES (%i, '%#', '%i', '%i', '%#', '%#')", ID, name, age, weight, height, description];
//*********** This is not opening, and SQLITE_OK is equal to false ***********
if(sqlite3_prepare_v2(([GlobalVars getGlobalDatabase]), [sqlInsert UTF8String], -1, &insertStatement, nil) == SQLITE_OK) {
if(sqlite3_step(insertStatement) == SQLITE_DONE) {
NSLog(#"insert stepping done");
}
sqlite3_reset(insertStatement);
}
sqlite3_finalize(insertStatement);
sqlite3_close([GlobalVars getGlobalDatabase]);
}
}
The variables for the database are all filled with their correct data, and it seems to open the database without issues. When it comes to preparing, it does not work properly and returns false. Any ideas why. Thank you for your assistance, any help is appreciated.
**
You must try this one ... Maybe its help you :
**
#import "DBManager.h"
#import "userRegistrationClass.h"
static DBManager *sharedInstance = nil;
static sqlite3 *database = nil;
static sqlite3_stmt *statement = nil;
#implementation DBManager
#pragma mark
#pragma mark Get shared Function
+(DBManager*)getSharedInstance{
if (!sharedInstance) {
sharedInstance = [[super allocWithZone:NULL]init];
[sharedInstance createDB];
}
return sharedInstance;
}
#pragma mark
#pragma mark Create DataBase
-(BOOL)createDB{
NSString *docsDir;
NSArray *dirPaths;
// Get the documents directory
// http://www.mycashkit.com/my-earnings.php
dirPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSLog(#"Dir Path Value is %#",dirPaths);
docsDir = [dirPaths objectAtIndex:0];
NSLog(#"DocsDir Path Value is %#",docsDir);
// Build the path to the database file
databasePath = [[NSString alloc] initWithString:[docsDir stringByAppendingPathComponent: #"UserRegInfo.sqlite"]];
NSLog(#"Data base Work's %#:",databasePath);
BOOL isSuccess = YES;
NSFileManager *filemgr = [NSFileManager defaultManager];
// NSString *currentPath = [filemgr currentDirectoryPath];
NSLog(#"My file managaer value is %#",filemgr);
//NSLog(#"My current drictory path is %#",currentPath);
//the file will not be there when we load the application for the first time
//so this will create the database table
if ([filemgr fileExistsAtPath: databasePath ] == NO)
{
const char *dbpath = [databasePath UTF8String];
NSLog(#"Constan charcter value is %s:-",dbpath);
if (sqlite3_open(dbpath, &database) == SQLITE_OK)
{
char *errMsg;
const char *sql_stmt = "create table if not exists UserInfo(UserID integer primary key, UserName,Gender,UserEmailID,Password,RePassword,DOB, MobileNo,IsUserType)";
const char *sql_stmt2 = "create table if not exists TestInfo(TestID integer primary key, TestName,TestType)";
// NSString *dbPathFromApp=[[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"UserRegInfo.sqlite"];[filemgr copyItemAtPath:dbPathFromApp toPath:databasePath error:nil];
NSLog(#"Constan charcter value is %s:-",dbpath);
if (sqlite3_exec(database, sql_stmt, NULL, NULL, &errMsg) && (sqlite3_exec(database, sql_stmt2, NULL, NULL, &errMsg)!= SQLITE_OK))
{
isSuccess = NO;
NSLog(#"Failed to create table");
}
NSLog(#"Print Sqlite%d",(sqlite3_exec(database, sql_stmt, NULL, NULL, &errMsg)));
sqlite3_close(database);
return isSuccess;
}
else {
isSuccess = NO;
NSLog(#"Failed to open/create database");
}
}
return isSuccess;
}
#pragma mark
#pragma mark Save Data Function
-(BOOL)saveData:(NSString*)insertSQL{
const char *dbpath = [databasePath UTF8String];
if (sqlite3_open(dbpath, &database) == SQLITE_OK)
{
NSLog(#" my Sqlite Query is :- %#",insertSQL);
const char *insert_stmt = [insertSQL UTF8String];
sqlite3_prepare_v2(database, insert_stmt,-1, &statement, NULL);
if (sqlite3_step(statement) == SQLITE_DONE)
{
return YES;
}
else
{
NSLog(#"Squlite Error Msg is %s",sqlite3_errmsg(database));
return NO;
}
}
return NO;
}

Load data SQlite into htmlString iOS

I have an app that reads from sqlite database,data is read and included in the objects using this method ....I checked with NSLog
#import "ViewController1.h"
#import "Ricetta.h"
#import "AppDelegate.h"
static sqlite3_stmt *leggiStatement = nil;
#interface ViewController1 ()
#end
#implementation ViewController1
#synthesize Webmain, oggetto2;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
//percorso file su cartella documents
NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDir = [documentPaths objectAtIndex:0];
NSString *path = [documentsDir stringByAppendingPathComponent:#"Rice.sqlite"];
//controllo se il file esiste
if(![[NSFileManager defaultManager] fileExistsAtPath:path])
{
//se non esiste lo copio nella cartella documenti
NSString *pathLocale=[[NSBundle mainBundle] pathForResource:#"Rice" ofType:#"sqlite"];
if ([[NSFileManager defaultManager] copyItemAtPath:pathLocale toPath:path error:nil] == YES)
{
NSLog(#"copia eseguita");
}
}
[self personalizzaAspetto];
[self carica_ID];
// NSString * query = #" SELECT Immagine, Titolo, Descrizione FROM LIBRO";
// NSArray * arrayQuery = [[NSArray alloc] initWithObjects:#"Immagine",#"Titolo",#"Descrizione",nil];
// NSArray * arrayElementi = [self caricaValoriMain:query :arrayQuery];
Webmain= [[UIWebView alloc]initWithFrame:CGRectMake(0, 0, 320, 365)];
NSString *htmlString =[NSString stringWithFormat:#"<html> \n"
"<head> \n"
"<style type=\"text/css\"> \n"
"body {font-family: \"%#\"; font-size: %#;}\n"
"</style> \n"
"</head> \n"
"<body><center><img src='%#'/></center></body><center><h1>%#</h1></center><body bgcolor=\"#FFFFFF\" text=\" #ffa500\">%#</body></html>" ,#"futura",[NSNumber numberWithInt:15],oggetto2.Immagine,oggetto2.Titolo,oggetto2.Descrizione];
[Webmain loadHTMLString:htmlString baseURL:nil];
[self.view addSubview:Webmain];
-(void)carica_ID{
sqlite3 *database = NULL;
NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDir = [documentPaths objectAtIndex:0];
NSString *dbPath = [documentsDir stringByAppendingPathComponent:#"Rice.sqlite"];
if(sqlite3_open([dbPath UTF8String], &database) == SQLITE_OK)
{
if(leggiStatement==nil){
const char *sql = "select Immagine,Titolo,Descrizione from LIBRO WHERE RicettaID=1";
if(sqlite3_prepare_v2(database, sql, -1, &leggiStatement, NULL) != SQLITE_OK)
NSAssert1(0, #"Errore creazione compiledState '%s'", sqlite3_errmsg(database));
}
//while(sqlite3_step(leggiStatement) == SQLITE_ROW)
if(SQLITE_DONE != sqlite3_step(leggiStatement))
{
NSString *titolo = [[NSString alloc] initWithUTF8String:(char *)sqlite3_column_text(leggiStatement, 1)];
NSLog(#"%#",titolo);
oggetto2.Titolo=titolo;
NSString *descrizione = [[NSString alloc] initWithUTF8String:(char *)sqlite3_column_text(leggiStatement, 2)];
NSLog(#"%#",descrizione);
oggetto2.Descrizione = descrizione;
NSString *image= [[NSString alloc]initWithUTF8String:(char *)sqlite3_column_text(leggiStatement, 0)];
NSLog(#"%#",image);
oggetto2.Immagine= image;
}
sqlite3_finalize(leggiStatement);
}
sqlite3_close(database);
}
#end
My problem is that I can not put them in webMain...objects in webMain remain empty.
I do not use Xib.
In the code snippet provided, you never perform the alloc and init of oggetto2. Thus, it is nil, and thus attempts to set its properties will achieve nothing.
In addition to your existing NSLog statements, I'd also suggest doing a NSLog of the htmlString right before you perform loadHTMLString, because it's easier to see what's going on with your HTML by looking at the source, rather than trying to make inferences from a blank web view.
Unrelated to your problem, but you probably should not have code that could potentially reusing your static sqlite3_stmt after you've finalized it. The first time you call carica_ID you would initialize the static leggiStatement. But you end up doing a sqlite_finalize but don't set leggiStatement to nil. If you ever called this method a second time, it won't sqlite3_prepare_v2 again, but you will have freed the resources associated with your prior leggiStatement.
A couple of easy fixes:
do not make leggiStatement a static global, but rather make it a local, non-static variable of the method;
if you do sqlite3_finalize, make sure you set leggiStatement to nil as well; or
don't call sqlite3_finalize, but rather just call sqlite3_reset, which will reset the prepared statement, but won't release its resources.

Resources