Help us understand the problem. What is going on with this article?

Realm Databaseのバックアップとリストア

Realm Databaseのバックアップとリストア

あまりRealmのバックアップとリストアについての記事が見つからないので投稿します。

環境

環境 バージョン
Xcode 12.0
Swift 5
MacOS Big Sur(11.0.1)

Libraryディレクトリ直下にバックアップ

defaults.realm_bk_yyyy-MM-dd-hh-mm-ssというファイル名で
現在のdefaults.realm(Realm Database本体)をバックアップします。

Hoge.swift
    private func hoge() {
        do {
            let url = try FileManager.default.url(for: .libraryDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
            let dateformater = DateFormatter()
            dateformater.dateFormat = "yyyy-MM-dd-hh-mm-ss"
            dateformater.locale = Locale(identifier: "ja_JP")
            let fileName = "default.realm_bk_" + dateformater.string(from: Date())
            try backupLocalStore(storeBackupDirectoryURL: url, backupStoreFilename: fileName)
        } catch {
            print(error.localizedDescription)
        }
    }


    /// Realmを指定の場所にバックアップします。
    /// - Parameters:
    ///   - storeBackupDirectoryURL: バックアップするディレクトリを指定
    ///   - backupStoreFilename: バックアップするファイル名を指定
    /// - Throws: エラー
    private func backupLocalStore(storeBackupDirectoryURL: URL, backupStoreFilename: String) throws {
        let backupURL = storeBackupDirectoryURL.appendingPathComponent(backupStoreFilename)
        do {
            let realm = try Realm()
            realm.beginWrite()
            try realm.writeCopy(toFile: backupURL)
            realm.cancelWrite()
        } catch {
            throw error
        }
    }

Library直下にバックアップが作成されています。
スクリーンショット 2020-11-16 22.49.50.png

バックアップしたファイルをリストアする

Hoge.swift
    private func hoge() {
        do {
            var url = try FileManager.default.url(for: .libraryDirectory, in: .userDomainMask, appropriateFor: nil, create: false)
            url.appendPathComponent("default.realm_bk_2020-11-16-10-46-35")
            try realmRestore(backupFileURL: url)
        } catch {
            print(error.localizedDescription)
        }
    }

    /// Realmをリストアする
    /// - Parameter backupFileURL: バックアップファイル
    /// - Throws: エラー
    private func realmRestore(backupFileURL: URL) throws {
        guard let realmFileUrl = Realm.Configuration.defaultConfiguration.fileURL else {
            throw NSError.init(domain: "Realmのファイルパスが取得できませんでした。", code: -1, userInfo: nil)
        }
        try FileManager.default.removeItem(at: realmFileUrl)
        try FileManager.default.copyItem(at: backupFileURL, to: realmFileUrl)
    }

指定したバックアップファイルでデータベースが復元されているのが確認できるはずです。

懸念事項

今回書いたサンプルコードはRealmが他でアクセスされている事を考慮できていない可能性があります。(特にリストアする時)
ただ、個人アプリ等で絶対にここではアクセスしていないと分かる場面等では利用できるかと思いますので自己責任でご利用ください😇
なにかあればご質問、ご指摘お待ちしております!

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away