iOS 把資料庫檔案打包到mainbundle中,查詢不到路徑的解決辦法;以及在刪除bundle中檔案的可行性
阿新 • • 發佈:2018-12-25
在開發中有時我們需要把資料庫檔案打包到我們的專案中,一般我們都是在外部用工具生成資料庫檔案,然後拉入專案中,但是我們在程式中查詢改檔案時,返回的路徑總是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檔案加下的原因!我們這個資料檔案肯定是要進行增刪改查操作的。