pch
pch

Reputation: 13

Read data from existing sqlite.db is working on simulator but not actual device (Objective C)

I don't know how to fix this error, I go to "Build Phases" and add sqlit.db file to Bundle resources but it still error. Have anyone solve the problem this thing?.

Click Here to see code

-(void) initDatabase{
    dbName  = @"MBox_karaoke.db";
    BOOL success;
    NSFileManager *fileManager  = [NSFileManager defaultManager];
    NSError *error;
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSString *writeableDBPath = [documentsDirectory stringByAppendingPathComponent:dbName];
    success = [fileManager fileExistsAtPath:writeableDBPath];

    if(success){
        return;
    }

    NSString *defaultDBPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:dbName];

    success = [fileManager copyItemAtPath:defaultDBPath toPath:writeableDBPath error:&error];
    if (!success) {
        // NSAssert1(0, @"Failed to create writable database file with message '%@'.", [error localizedDescription]);
        NSLog(@"Database created failed, %@",[error localizedDescription]);
    }
    else {
        NSLog(@"Database created successfully");
    }
}

Upvotes: 0

Views: 378

Answers (3)

user3182143
user3182143

Reputation: 9609

My answer

 + (NSString *)databasePath
 {
    NSArray *paths=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *sql_Path=[paths objectAtIndex:0];

    NSString *dbPath=[sql_Path stringByAppendingPathComponent:@"MBox_karaoke.sqlite"];

    NSFileManager *fileMgr=[NSFileManager defaultManager];
    BOOL success;
    NSError *error;
    success=[fileMgr fileExistsAtPath:dbPath];
    if (!success) 
    {
       NSString *path=[[[NSBundle mainBundle]resourcePath]stringByAppendingPathComponent:@"MBox_karaoke.sqlite"];
      success=[fileMgr copyItemAtPath:path toPath:dbPath error:&error];
    }
    return dbPath;
}

Create Table and here My Table Name is Account

+ (void) createTableForAccount
{
   char *error;
   NSString *filePath =[self databasePath];
   if (sqlite3_open([filePath UTF8String], &database) == SQLITE_OK)
   {
      NSString *strQuery=[NSString stringWithFormat:@"CREATE TABLE IF NOT EXISTS Account(id TEXT,name TEXT);"];
      sqlite3_exec(database, [strQuery UTF8String], NULL, NULL, &error);
   }
   else
   {
      NSAssert(0, @"Table failed to create");
      NSLog(@"Account Table Not Created");
   }
   sqlite3_close(database);
 }

Insert Data

 + (void)insertAccountDetails:(NSString *)id:(NSString *)name
 {
     NSString *dbPath=[self databasePath];
     if(sqlite3_open([dbPath UTF8String],&database)==SQLITE_OK)
     {
       NSString *strQuery = [NSString stringWithFormat:@"INSERT into Account(id,name) values(?,?);"];
       if(sqlite3_prepare_v2(database,[strQuery UTF8String] , -1, &stment, NULL)==SQLITE_OK)
      {
            sqlite3_bind_text(stment, 1, [[self checkEmpty:id] UTF8String], -1, SQLITE_TRANSIENT);
            sqlite3_bind_text(stment, 2, [[self checkEmpty:name] UTF8String] , -1, SQLITE_TRANSIENT);
            sqlite3_step(stment);
            sqlite3_reset(stment);
      }
      sqlite3_finalize(stment);
   }
   sqlite3_close(database);
}

Fetch or Get Data from Table

+ (void)getAccountDetails
{
  NSString *dbPath = [self databasePath];
  if (sqlite3_open([dbPath UTF8String], &database) == SQLITE_OK)
  {
     NSString *query = [NSString stringWithFormat:@"SELECT id,name from Account"];
     if (sqlite3_prepare_v2(database, [query UTF8String], -1, &stment, nil) == SQLITE_OK)
     {
        while (sqlite3_step(stment) == SQLITE_ROW)
        {
            NSString *idString = [[self charToString: (char *)sqlite3_column_text(stment, 0)]base64DecodedString];
            NSString *nameString = [[self charToString: (char *)sqlite3_column_text(stment, 1)]base64DecodedString];
            NSMutableArray *arrayId = [[NSMutableArray alloc]init];
            NSMutableArray *arrayName = [[NSMutableArray alloc]init];
            [arrayId addObject:idString];
            [arrayName addObject:nameString];
          }
          sqlite3_reset(stment);
        }
        sqlite3_finalize(stment);
     }
     sqlite3_close(database);
}

Other Methods which called inside the db insert and fetch

insert

+ (NSString *)checkEmpty:(NSString *)check
{
  if([check isEqual:[NSNull null]])
    check = @" ";
  return check;
}

Fetch method

+ (NSString*)charToString:(const char*)chart
{
  NSString *string = @" ";
  if(string)
  {
    chart = [self checkEmptyChar:chart];
    string=[NSString stringWithUTF8String:chart];
  }
  return string;
}


 + (const char *)checkEmptyChar:(const char *)check
 {
   NSString *string = @" ";
   if (check == NULL)
     check = [string UTF8String];
   return check;
 }

Upvotes: 0

Bhadresh Kathiriya
Bhadresh Kathiriya

Reputation: 3244

Your code is correct but some time database file doesn't select target membership that your database doesn't copy your path that it's this type error occur.

First Remove/Uninstall your install app.

Please, Select your database file in xcode and see your target membership is check or uncheck. Uncheck that select check. (See below image)

Run the project simulator and check your database available in your path. Database available that see your database browse contain is correct.

NSLog("Path: %@",defaultDBPath);

enter image description here

Upvotes: 1

MD.
MD.

Reputation: 1167

As an error states resource file not found.

Make sure you copied the database file in bundle. When you drag database to project navigator, make sure that you have checked "Copy item if needed".

Following solution working for me.

-(void)initializeDatabase {

    NSError *error;
    NSFileManager *fm = [NSFileManager defaultManager];
    NSArray *docPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *docDir = [docPaths objectAtIndex:0];
    NSString *docPath = [docDir stringByAppendingPathComponent:@"Test.sqlite"];

    NSString *template_path = [[NSBundle mainBundle] pathForResource:@"Test" ofType:@"sqlite"];

    if (![fm fileExistsAtPath:docPath])
        [fm copyItemAtPath:template_path toPath:docPath error:&error];


    //-====
}

Upvotes: 1

Related Questions