2015-10-23 5 views
1

В моем приложении я делаю чтение, запись и удаление в базе данных sqlite (в форме db), и он отлично работает в симуляторе, но не работает на самом устройстве (давая ошибку: No such table found). Я очень стараюсь искать решение, но не могу найти его, или, может быть, я что-то неправильно понял.Моя база данных sqlite в db не работает на самом устройстве, но отлично работает в симуляторе

Мой дб в

/users/My Name/library/developer/Core simulator/devices/devicen-id/data/application/app-id/documents/My database.

- (NSString *) getWritableDBPath { 

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory , NSUserDomainMask, YES); 
NSString *documentsDir = [paths objectAtIndex:0]; 
return [documentsDir stringByAppendingPathComponent:mydaatabase]; 

} 

Меня смутить куда мне нужно скопировать мою базу данных во время работы в реальном устройстве IOS и что является основной problem.Any помощь относительно этого будет очень полезно

-(void)createEditableCopyOfDatabaseIfNeeded 
{ 

BOOL success; 
NSFileManager *fileManager1 = [NSFileManager defaultManager]; 
NSError *error; 
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, 
                NSUserDomainMask, YES); 
NSString *documentsDirectory = [paths objectAtIndex:0]; 
NSString *writableDBPath = [documentsDirectory stringByAppendingPathComponent:mydaatabase]; 
NSLog(@"=======%@", writableDBPath); 

success = [fileManager1 fileExistsAtPath:writableDBPath]; 
if (success) 
    return; 

NSString *defaultDBPath = [[[NSBundle mainBundle] resourcePath] 
          stringByAppendingPathComponent:mydaatabase]; 
NSLog(@"=======%@", [NSBundle mainBundle]); 

success = [fileManager1 copyItemAtPath:defaultDBPath 
           toPath:writableDBPath 
           error:&error]; 


if(!success) 
{ 
    NSAssert1(0,@"Failed to create writable database file with Message : '%@'.", 
    [error localizedDescription]); 
} 
} 
+0

Можете ли вы проверить, есть ли fileExists в «defaultDBPath»? – almas

+0

@ almas- я проверил в документе его там, но я не понимаю, что вы подразумеваете по умолчанию и как его проверить, спасибо за ответы –

+1

«defaultDBPath» - это исходное место, откуда вы копируете свою базу данных, это находится в вашем коде, который вы предоставили. Просто убедитесь, что файл существует до того, как вы попытаетесь скопировать его в папку документов. – almas

ответ

0

Проверьте, что ваш .sqlite файл добавлен в ваш Copy Bundle Resources в Build Phases вашего проекта. Если его там нет, добавьте его в свой проект.

Кроме того, я не могу найти код для открытия базы данных. Таким образом, в файле ViewController.h объявить Sqlite *database;

В файле ViewController.m,

-(void)databaseOpen 

{ 
    NSArray *paths=NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
    NSString *documentsDirectory=[paths objectAtIndex:0]; 
    NSString *myDBnew=[documentsDirectory stringByAppendingPathComponent:@"yourSqliteFile.sqlite"]; 

    database =[[Sqlite alloc]init]; 
    [database open:myDBnew]; 
    NSLog(@"path: %@", myDBnew); 

    NSLog(@"Database opened"); 

} 

и назвать его везде, где вы хотите, как [self databaseOpen];, а затем написать свой запрос.

Кроме того, ваш -(void)createEditableCopyOfDatabaseIfNeeded должен выглядеть примерно так в вашем AppDelegate.m:

- (void)createEditableCopyOfDatabaseIfNeeded 
{ 
    // First, test for existence. 
    BOOL success; 
    NSFileManager *fileManager = [NSFileManager defaultManager]; 
    NSError *error; 
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
    NSString *documentsDirectory = [paths objectAtIndex:0]; 
    NSString *writableDBPath = [documentsDirectory stringByAppendingPathComponent:@"yourSqliteFile.sqlite"]; 
    success = [fileManager fileExistsAtPath:writableDBPath]; 
    if (success) return; 

    // The writable database does not exist, so copy the default to the appropriate location. 

    NSString *defaultDBPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"yourSqliteFile.sqlite"]; 
    success = [fileManager copyItemAtPath:defaultDBPath toPath:writableDBPath error:&error]; 
    if (!success) { 
     NSAssert1(0, @"Failed to create writable database file with message '%@'.", [error localizedDescription]); 
    } 


} 

Вызов -(void)createEditableCopyOfDatabaseIfNeeded в didFinishLaunchingWithOptions:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 
{ 
    // Override point for customization after application launch. 

    [self createEditableCopyOfDatabaseIfNeeded]; 
    return YES; 
} 

Это должно вас происходит.

+0

@ Rumin-- спасибо за ответ, в моих ресурсах Bundle у меня была копия моего database.db, но не файл mydatabase.sqlite, поэтому мне нужно скопировать файл .sqlite также –

+0

Да ... вам нужно '. sqlite', а не '.db'. '.db' - ваша база данных, и она будет автоматически загружена после добавления файла' .sqlite'. – Rumin

+0

Я тоже пробовал этот, но не работал ... Я не понимаю, почему он работает на симуляторе отлично не в самом устройстве - @ Rumin –

0

Ниже приведены шаги по работе с SQLite Database.

  1. Создайте свою базу данных в SQLite, добавьте требуемую таблицу со структурой скважины. и добавьте его в свое приложение.

  2. Теперь перейдите в приложение, выберите проект из левой панели, в средней панели -> Общие -> Linked Каркасы и библиотеки (последний один) добавить libsqlite3.0.tbd (. Это зависит от вашей Xcode версии)

  3. Теперь определим ниже методов в your-object.h

    #import <sqlite3.h> 
    
    + (NSString *)getDBPath; 
    + (void)copyDatabaseIfNeeded; 
    + (void)openDatase; 
    
  4. Реализовать их в your-object.m

    static sqlite3 *database; 
    
    #pragma mark - Copy and open databse 
    
    + (NSString *)getDBPath 
    { 
        NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory , NSUserDomainMask, YES); 
        NSString *documentsDir = [paths objectAtIndex:0]; 
        return [documentsDir stirngByAppendingPathComponent:@"dbName.sqlite"]; 
    } 
    
    + (void)copyDatabaseIfNeeded 
    { 
        NSFileManager *fileManager = [NSFileManager defaultManager]; 
        NSError *error; 
    
        NSString *dbPath = [self getDBPath]; 
        BOOL success = [fileManager fileExistsAtPath:dbPath]; 
    
        if(!success) 
        { 
         NSString *defaultDBPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"dbName.sqlite"]; 
         success = [fileManager copyItemAtPath:defaultDBPath toPath:dbPath error:&error]; 
    
         if (!success) 
          NSAssert1(0, @"Failed to create writable database file with message '%@'.", [error localizedDescription]); 
        } 
    } 
    
    + (void)openDatase 
    { 
        NSString *dbPath = [self getDBPath]; 
    
        if (sqlite3_open([dbPath UTF8String], &database) == SQLITE_OK) 
        { 
         NSLog(@"Database Successfully Opened."); 
        } 
        else 
        { 
         NSLog(@"Error in opening database."); 
        } 
    } 
    
  5. Затем вызывается метод в AppDelegate.m в application: didFinishLaunchingWithOptions:

    [DataManager copyDatabaseIfNeeded]; 
    
  6. Всякий раз, когда вы хотите, чтобы выполнить задачу с базой данных, откройте его и проверьте.

Для вставки в базе данных

 + (void)insertData 
    { 
     const char *dbpath = [[self getDBPath] UTF8String]; 

     if (sqlite3_open(dbpath, &database) == SQLITE_OK) 
     { 
      NSString *strSQL = [NSString stringWithFormat:@"INSERT INTO table name………………."]; 
      const char *insertQuery = [strSQL UTF8String]; 
      sqlite3_stmt *insert_stmt; 

      if (sqlite3_prepare_v2(database, insertQuery, -1, &insert_stmt, NULL) == SQLITE_OK) 
      { 
       if (sqlite3_step(insert_stmt) == SQLITE_DONE) 
       { 
        // Code 
       } 
       else 
       { 
        NSLog(@"error"); 
       } 
      } 
      sqlite3_finalize(insert_stmt); 
      sqlite3_close(database); 
     } 
    } 

7. Завершена .... наслаждаться с базой данных.

Смежные вопросы