Just My Life & My Work

有時候我們會想要從電腦把檔案放進APP中,恰好這個APP可以讀取相片或影片,然後我們就可以重新開啟APP,直接享用我們剛匯入檔案的成果!

在這裡我想展示的是,如何將Core Data資料,由第一個設備複製到第二個設備,如此一來,我就能將資料庫複製多份到無限多個設備上。

File Share through iTunes2

首先就是要在專案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中的檔案拉出到電腦上喔!

File Share through iTunes

我的程式碼首先要執行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)

  1. […] 在此我要將student.sqlite抽出來,可以參考我先前的文章:透過iTunes檔案共享。抽出來之後我再使用SQLite Database Browser來查看! […]

隨意留個言吧:)~

在下方填入你的資料或按右方圖示以社群網站登入:

WordPress.com 標誌

您的留言將使用 WordPress.com 帳號。 登出 /  變更 )

Twitter picture

您的留言將使用 Twitter 帳號。 登出 /  變更 )

Facebook照片

您的留言將使用 Facebook 帳號。 登出 /  變更 )

連結到 %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

標籤雲

%d 位部落客按了讚: