2013-05-04 77 views
1

我的模擬器運行良好且快速。我的iPhone似乎凍結在我嘗試創建並填充數據庫的部分。不過,我更喜歡使用模擬器中的數據庫,並將它放在iphone上,這樣用戶不必重新創建數據庫。 我想知道的是如何從數據庫中加載到文件夾中。替換/加載iphone上的數據庫

我搜索了很多,但它是過時的或與我想要的不同。 我現在從查找器中將數據庫文件添加到xcode項目中。 所以如果我是正確的,我必須改變_databasePath指向文件的位置,我是否正確?

如果是的話它在哪裏,從代碼中一個是在這裏: /var/mobile/Applications/65B5541A-1E73-46F6-AB5A-C5988003103E/Documents/paths.db 但就是沒有一個我拖入xcode。 另外我看着組織者,我可以看到那裏的文件/ paths.db,但由於它錯過了其他文件,我也假設這是代碼創建分貝,而不是拖入英寸 我試圖刪除它,但我可以'選擇它。

有人可以幫忙嗎?

在頭

@property (strong, nonatomic) NSString *databasePath; 
@property (nonatomic) sqlite3 *pathDB; 

中的m:

- (void) createDataBaseIfNotExist { 

    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:@"paths.db"]]; 

    NSLog(@"databasePath: %@", _databasePath); 

    NSFileManager *filemgr = [NSFileManager defaultManager]; 

    if ([filemgr fileExistsAtPath: _databasePath] == NO) { 

     const char *dbpath = [_databasePath UTF8String]; 

     if(sqlite3_open(dbpath, &_pathDB) == SQLITE_OK) { 
      char *errMsg; 
      const char *sql_stmt = 
      "CREATE TABLE IF NOT EXISTS Paths (ID INTEGER PRIMARY KEY AUTOINCREMENT, START INTEGER, END INTEGER, DISTANCE REAL, NODES TEXT)"; 

      if (sqlite3_exec(_pathDB, sql_stmt, NULL, NULL, &errMsg) != SQLITE_OK) 
      { 
       //_status.text = @"Failed to create table"; 
       NSLog(@"Failed to create table"); 

      } 
      sqlite3_close(_pathDB); 
     } else { 
      // _status.text = @"Failed to open/create database"; 
      NSLog(@"Failed to open/create database"); 
     } 
    } 

} 

回答

1

所以,幾件事情:

  1. 首先,您需要修改createDatabaseIfNotExist從複製如果沒有在Documents中找到,則捆綁:

    - (void) createDataBaseIfNotExist { 
    
        // Get the documents database path 
        NSString *docsDir = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0]; 
        self.databasePath = [docsDir stringByAppendingPathComponent:@"paths.db"]; // always use setter when setting property's value 
    
        NSFileManager *fileManager = [NSFileManager defaultManager]; 
    
        if ([fileManager fileExistsAtPath:_databasePath] == NO) { 
    
         // if the database doesn't exist in documents, look for it in the bundle and copy it if found 
    
         // get the bundle database path 
         NSString *bundleDatabasePath = [[NSBundle mainBundle] pathForResource:@"paths" ofType:@"db"]; 
    
         if (bundleDatabasePath) { 
          // if we successfully copied from bundle, then quit 
    
          if ([fileManager copyItemAtPath:bundleDatabasePath toPath:self.databasePath error:nil]) 
           return; 
         } 
    
         // otherwise, let's proceed with creating the database 
    
         if(sqlite3_open([_databasePath UTF8String], &_pathDB) == SQLITE_OK) { 
          char *errMsg; 
          const char *sql_stmt = "CREATE TABLE IF NOT EXISTS Paths (ID INTEGER PRIMARY KEY AUTOINCREMENT, START INTEGER, END INTEGER, DISTANCE REAL, NODES TEXT)"; 
    
          if (sqlite3_exec(_pathDB, sql_stmt, NULL, NULL, &errMsg) != SQLITE_OK) { 
           //_status.text = @"Failed to create table"; 
           NSLog(@"Failed to create table, %s", errMsg); 
           sqlite3_free(errMsg); // if you're going to use that fifth parameter, you must free it when you're done 
          } 
          sqlite3_close(_pathDB); 
         } else { 
          // _status.text = @"Failed to open/create database"; 
          NSLog(@"Failed to open/create database"); 
         } 
        } 
    } 
    
  2. 其次,一旦您在模擬器上運行過一次,請在模擬器的Documents文件夾中找到您的Xcode項目中的數據庫。模擬器的文件可以在

    〜/庫/應用程序支持/ iPhone模擬器/ 6.1中找到/應用/ XXX /文檔

    其中XXX是隱蔽標識符(例如85206BA6-9D03-4F18-BB0A-3B8C25B552C4)。注意,默認情況下,Library文件夾是隱藏的,所以我去一個終端命令行鍵入以下命令來顯示它:

     
    chflags nohidden Library 
    
  3. 然後,您可以添加數據庫返回到項目由拖動查找到Xcode的文件導航窗口,此時你會看到一個窗口,如:

    enter image description here

    確保檢查兩個高亮複選標記,以確保數據庫將被包含在捆綁。

兩個結論性意見:

  • 現在你有一個「從包副本,如果必要的邏輯」,這是一個有趣的問題,你是否真的想要的代碼在所有在代碼中創建表了。就個人而言,我總是用一個漂亮的Mac圖形SQLite工具創建我的數據庫,然後將它們複製到我的項目中。我唯一一次編程創建表的時候是(a)我正在部署一個包含新/更改表的更新; (b)用戶的數據庫可能包含一些關鍵數據,我不想簡單地用數據庫中的數據庫替換。

  • 我個人總是在我的應用程序中包含一個configuration表,其中包含一行,其中一列是數據庫版本。因此,我的應用程序將從文檔打開數據庫,檢查版本號,如果過期(因爲用戶只是最近升級了他們的應用程序),則更新數據庫。這個「數據庫版本號」邏輯是你真正想要作爲你的應用程序的1.0版本的一部分。

+0

謝謝,非常完整的答案 – clankill3r 2013-05-05 10:14:49