有時候我們會想要從電腦把檔案放進APP中,恰好這個APP可以讀取相片或影片,然後我們就可以重新開啟APP,直接享用我們剛匯入檔案的成果!
在這裡我想展示的是,如何將Core Data資料,由第一個設備複製到第二個設備,如此一來,我就能將資料庫複製多份到無限多個設備上。
首先就是要在專案Info.plist設定Application supports iTunes file sharing (UIFileSharingEnabled)為YES,馬上編譯執行,開啟iTunes軟體,就能看到HappyTest2出現在「檔案共享」清單上喲!表示透過iTunes檔案共享 (File Share through iTunes)功能已開啟~
想要複製Core Data,必須先知道它的位置所在,沒想到它有三個檔案:coredata.splite、coredata.splite-shm、coredata.splite-wal⋯⋯為了不遺漏任何一個相關檔案,我就把它們三個打包成zip檔。若要使用zip檔方式可參考我之前的文章-建立和解除壓縮檔。
我們可以從模擬器來得知此三檔的位置,是在APP母目錄的Library的Private Documents,接著將這三個檔複製到APP母目錄的Documents,即可在iTunes看到檔案出現!真是讓人興奮~
/** Theme: File Share through iTunes IDE: Xcode 5 Language: Objective C Date: 103/04/26 Author: HappyMan Blog: https://cg2010studio.wordpress.com/ */ -(BOOL)exportCoreData { NSError *err; NSString *coreDataFile1Name = @"coredata.sqlite"; NSString *coreDataFile2Name = @"coredata.sqlite-shm"; NSString *coreDataFile3Name = @"coredata.sqlite-wal"; // 原始檔案路徑 NSString *libraryDirectory = [NSHomeDirectory() stringByAppendingPathComponent:@"Library"]; NSString *privateDocumentsDirectory = [libraryDirectory stringByAppendingPathComponent:@"Private Documents"]; if (![[NSFileManager defaultManager] fileExistsAtPath:privateDocumentsDirectory]) { [[NSFileManager defaultManager] createDirectoryAtPath:privateDocumentsDirectory withIntermediateDirectories:YES attributes:nil error:&err]; } NSString *oCoreDataFile1Path = [privateDocumentsDirectory stringByAppendingPathComponent:coreDataFile1Name]; NSString *oCoreDataFile2Path = [privateDocumentsDirectory stringByAppendingPathComponent:coreDataFile2Name]; NSString *oCoreDataFile3Path = [privateDocumentsDirectory stringByAppendingPathComponent:coreDataFile3Name]; if (![[NSFileManager defaultManager] fileExistsAtPath:oCoreDataFile1Path]) { DxLog(@"oCoreDataFile1Path not exists"); } if (![[NSFileManager defaultManager] fileExistsAtPath:oCoreDataFile2Path]) { DxLog(@"oCoreDataFile2Path not exists"); } if (![[NSFileManager defaultManager] fileExistsAtPath:oCoreDataFile3Path]) { DxLog(@"oCoreDataFile3Path not exists"); } // 壓縮檔案 // 想要創造的ZIP檔的路徑 NSString *documentsDirectory = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"]; NSString *zipPath = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@"zipFile.zip"]]; // 先移除 [[NSFileManager defaultManager] removeItemAtPath:zipPath error:&err]; ZipArchive *zip = [[ZipArchive alloc] init]; [zip CreateZipFile2:zipPath Password:@""]; // 想要加入的檔案的路徑 // newname參數為在ZIP檔中的新名稱 if (![zip addFileToZip:oCoreDataFile1Path newname:coreDataFile1Name]) { // 加入檔案失敗的處理~ } if (![zip addFileToZip:oCoreDataFile2Path newname:coreDataFile2Name]) { // 加入檔案失敗的處理~ } if (![zip addFileToZip:oCoreDataFile3Path newname:coreDataFile3Name]) { // 加入檔案失敗的處理~ } BOOL success = [zip CloseZipFile2]; return success; } -(BOOL)importCoreData { NSError *err; NSString *coreDataFile1Name = @"coredata.sqlite"; NSString *coreDataFile2Name = @"coredata.sqlite-shm"; NSString *coreDataFile3Name = @"coredata.sqlite-wal"; NSString *documentsDirectory = [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"]; // 想要解除的ZIP檔的路徑 NSString *zipPath = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@"zipFile.zip"]]; ZipArchive *zip = [[ZipArchive alloc] init]; if ([zip UnzipOpenFile:zipPath Password:@""]) { if (![zip UnzipFileTo:documentsDirectory overWrite:YES]) { // 解壓縮失敗的處理~ } } BOOL success = [zip UnzipCloseFile]; // 目標檔案路徑 NSString *tCoreDataFile1Path = [documentsDirectory stringByAppendingPathComponent:coreDataFile1Name]; NSString *tCoreDataFile2Path = [documentsDirectory stringByAppendingPathComponent:coreDataFile2Name]; NSString *tCoreDataFile3Path = [documentsDirectory stringByAppendingPathComponent:coreDataFile3Name]; if (![[NSFileManager defaultManager] fileExistsAtPath:tCoreDataFile1Path]) { DxLog(@"tCoreDataFile1Path not exists"); } if (![[NSFileManager defaultManager] fileExistsAtPath:tCoreDataFile2Path]) { DxLog(@"tCoreDataFile2Path not exists"); } if (![[NSFileManager defaultManager] fileExistsAtPath:tCoreDataFile3Path]) { DxLog(@"tCoreDataFile3Path not exists"); } [self listFileAtPath:documentsDirectory]; // 原始檔案路徑 NSString *libraryDirectory = [NSHomeDirectory() stringByAppendingPathComponent:@"Library"]; NSString *privateDocumentsDirectory = [libraryDirectory stringByAppendingPathComponent:@"Private Documents"]; if (![[NSFileManager defaultManager] fileExistsAtPath:privateDocumentsDirectory]) { [[NSFileManager defaultManager] createDirectoryAtPath:privateDocumentsDirectory withIntermediateDirectories:YES attributes:nil error:&err]; } NSString *oCoreDataFile1Path = [privateDocumentsDirectory stringByAppendingPathComponent:coreDataFile1Name]; NSString *oCoreDataFile2Path = [privateDocumentsDirectory stringByAppendingPathComponent:coreDataFile2Name]; NSString *oCoreDataFile3Path = [privateDocumentsDirectory stringByAppendingPathComponent:coreDataFile3Name]; // 先移除 [[NSFileManager defaultManager] removeItemAtPath:oCoreDataFile1Path error:&err]; [[NSFileManager defaultManager] removeItemAtPath:oCoreDataFile2Path error:&err]; [[NSFileManager defaultManager] removeItemAtPath:oCoreDataFile3Path error:&err]; // 再複製 [[NSFileManager defaultManager] copyItemAtPath:tCoreDataFile1Path toPath:oCoreDataFile1Path error:&err]; [[NSFileManager defaultManager] copyItemAtPath:tCoreDataFile2Path toPath:oCoreDataFile2Path error:&err]; [[NSFileManager defaultManager] copyItemAtPath:tCoreDataFile3Path toPath:oCoreDataFile3Path error:&err]; return success; } -(NSArray *)listFileAtPath:(NSString *)path { //-----> LIST ALL FILES <-----// NSLog(@"LISTING ALL FILES FOUND"); int count; NSArray *directoryContent = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:path error:NULL]; for (count = 0; count < (int)[directoryContent count]; count++) { NSLog(@"File %d: %@", (count + 1), [directoryContent objectAtIndex:count]); } return directoryContent; }
連結設備到電腦,開啟iTunes該設備的App欄位,接著實際執行一遍就知道有多神奇!可以直接將電腦上的資料拖曳進該APP中,也能將該APP中的檔案拉出到電腦上喔!
我的程式碼首先要執行exportCoreData,會先將位於私密資料夾三個檔案打包,iTunes就出現zipFile.zip(只有這一個檔);接著執行importCoreData,會解壓縮zipFile.zip,iTunes就出現三個Core Data檔(共有四個檔),同時複製這三個檔到私密資料夾。
最後重新編譯執行,就能看到Core Data成功匯入另一台設備!若要用程式自殺,可以用exit(0)這個指令喔~
參考:iOS如何设置app支持文件共享、讓iOS App通過iTunes進行文件交換、通過iTunes共享文件到Document目錄。
Comments on: "[iOS] 透過iTunes檔案共享 (File Share through iTunes)" (1)
[…] 在此我要將student.sqlite抽出來,可以參考我先前的文章:透過iTunes檔案共享。抽出來之後我再使用SQLite Database Browser來查看! […]
讚讚