1. 程式人生 > >iOS 把資料庫檔案打包到mainbundle中,查詢不到路徑的解決辦法;以及在刪除bundle中檔案的可行性

iOS 把資料庫檔案打包到mainbundle中,查詢不到路徑的解決辦法;以及在刪除bundle中檔案的可行性

在開發中有時我們需要把資料庫檔案打包到我們的專案中,一般我們都是在外部用工具生成資料庫檔案,然後拉入專案中,但是我們在程式中查詢改檔案時,返回的路徑總是nil

解決辦法:

原因我們拉入其他資原始檔(比如:圖片、程式碼檔案等)Xcode都會自動新增到target 的 "Build Phases" 下 "Copy Bundle Resources目錄下,但是我們拉過來的資料庫檔案這裡是找不到的,可能是Xcode無法識別這類檔案(當我們拉去過來時),所以我們要做的就是把剛才新增的db檔案加入該目錄下,如圖


這樣就OK了,執行程式碼就可以找到了該資料庫檔案的路徑了。接下來上程式碼:

- (void)_testDataBaseHandle
{
    static NSString *const DATABASE_FILE_NAME = @"exiu.db";
    NSString *dbFilePath ;
    //獲取應用程式的路徑
    NSArray *searchPaths = NSSearchPathForDirectoriesInDomains(
                                                               NSDocumentDirectory,
                                                               NSUserDomainMask,
                                                               YES);
    NSString *documentFolderPath = [searchPaths objectAtIndex:0];
    NSLog(@"docoumentFolderPath=%@",documentFolderPath);
    
    //往應用程式路徑中新增資料庫檔名稱,把它們拼接起來, 這裡用到了巨集定義(目的是不易出錯)
    dbFilePath = [documentFolderPath stringByAppendingPathComponent:DATABASE_FILE_NAME];
    NSLog(@"dbFilePath = %@",dbFilePath);
    
    //
    
    
    /*
     為什麼要往應用程式裡新增資料庫檔案這個過程:
     因為下面要進行判斷,會根據這個路徑去查詢應用程式的路徑中到底有沒有這個檔案,
     如果有,則不用在此拷貝了,
     如果沒有,則重新拷貝一次,
     資料庫檔案必須新增進取,否則無法進行資料庫的操作,而且必須新增一次,
     
     那麼為什麼必須要新增一次呢?
     因為我們在程式中實現對資料庫的修改,然而卻又把資料庫添加了一次,
     那麼新新增的資料庫就會把舊的資料庫覆蓋掉,那麼程式中對資料庫的修改也不能實現,
     所以資料庫只能新增一次且是在程式執行初新增
     */
    
    //根據上面拼接好的路徑 dbFilePath ,利用NSFileManager 類的物件的fileExistsAtPath方法來檢測是否存在,返回一個BOOL值
    //1. 建立NSFileManager物件  NSFileManager包含了檔案屬性的方法
    NSFileManager *fm = [NSFileManager defaultManager];
    
    //2. 通過 NSFileManager 物件 fm 來判斷檔案是否存在,存在 返回YES  不存在返回NO
    BOOL isExist = [fm fileExistsAtPath:dbFilePath];
    //- (BOOL)fileExistsAtPath:(NSString *)path;
    
    //如果不存在 isExist = NO,拷貝工程裡的資料庫到Documents下
    if (!isExist)
    {
        //拷貝資料庫
        
        //獲取工程裡,資料庫的路徑,因為我們已在工程中添加了資料庫檔案,所以我們要從工程裡獲取路徑
        NSString *backupDbPath = [[NSBundle mainBundle]
                                  pathForResource:@"exiu"
                                  ofType:@"db"];
        //這一步實現資料庫的新增,
        // 通過NSFileManager 物件的複製屬性,把工程中資料庫的路徑拼接到應用程式的路徑上
        BOOL cp = [fm copyItemAtPath:backupDbPath toPath:dbFilePath error:nil];
        NSLog(@"cp = %d",cp);
        //- (BOOL)copyItemAtPath:(NSString *)srcPath toPath:(NSString *)dstPath error:(NSError **)error
        NSLog(@"backupDbPath =%@",backupDbPath);
        if (cp) {
            NSError *error;
            //這裡驗證程式執行時,copy成功後,刪除mainbundle裡的檔案
            BOOL bl = [fm removeItemAtPath:backupDbPath error:&error];

        }
        
       }
    NSLog(@"isExist =%d",isExist);
}

下面說說copy檔案成功後,刪除main bundle下的原始檔的可行性

如果是在模擬器下,你執行發現是可以的!這樣並不意味著在真機上是可行的。經過真機測試,發現會報錯!!因為程式在真機真機上執行時,bundle 是隻讀的!所以千萬不要執行時修改程式bundle下的任何檔案!!!

上面說到,程式執行時,程式bundle是隻讀的,這也是我們為什麼要把資料檔案copy到Document檔案加下的原因!我們這個資料檔案肯定是要進行增刪改查操作的。