Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Backup Realm to iCloud Drive

I would like to backup a realm database file to an iCloud drive, like WhatsApp, I have some questions:

  1. What is the best practice to do this?

  2. I have a database located in a shared group folder to access it from extensions, how can I back it up? How can I show the progress bar of upload? Like WhatsApp for example?

  3. If I put a realm file in a document folder it will be synced for each modify.

  4. Are there some samples code that we can see?

Thanks for the help, have any ideas? links?

like image 537
Luca Becchetti Avatar asked Jan 27 '17 14:01

Luca Becchetti


2 Answers

Just to clarify, this is a question about backing up a discrete Realm file itself to iCloud Drive, so that it would be visible in the iCloud Drive app. Not synchronizing the contents of the file to a CloudKit store.

If you leave the Realm file in the Documents directory, then if the user performs an iCloud or iTunes backup, the file will be backed up. All this means though is that if the user decides to upgrade to a new device and perform a restore using the old device's backup image, the Realm file will be restored then. If the user deletes the app from your old device before then, the iCloud backup will also be deleted.

If you want to export your Realm file so it can be permanently saved and accessed in iCloud Drive, you can export a copy of the Realm file to your app's iCloud ubiquity container. This is basically just another folder like the shared group's folder, but it's managed by iCloud. This folder sort of behaves like Dropbox in that anything you put in there is automatically synchronized.

The code would look something like this:

let containerURL = FileManager.default.url(forUbiquityContainerIdentifier: nil)
let realmArchiveURL = containerURL.appendPathComponent("MyArchivedRealm.realm")

let realm = try! Realm()
try! realm.writeCopy(toFile: realmArchiveURL)

This is a really basic example. The Apple documentation recommends you do this on a background thread since setting up the iCloud folder for the first time can create some time.

Updating this wouldn't happen automatically. You'll need to export a new copy of the Realm each time the user wants to perform a backup.

like image 154
TiM Avatar answered Oct 31 '22 14:10

TiM


@yonlau as per your request sharing answer for backup realm file , This is tested once and the realm data only have when they backup on iCloud.

func DownloadDatabaseFromICloud()
{
    let fileManager = FileManager.default
    // Browse your icloud container to find the file you want
    if let icloudFolderURL = DocumentsDirectory.iCloudDocumentsURL,
        let urls = try? fileManager.contentsOfDirectory(at: icloudFolderURL, includingPropertiesForKeys: nil, options: []) {

        // Here select the file url you are interested in (for the exemple we take the first)
        if let myURL = urls.first {
            // We have our url
            var lastPathComponent = myURL.lastPathComponent
            if lastPathComponent.contains(".icloud") {
                // Delete the "." which is at the beginning of the file name
                lastPathComponent.removeFirst()
                let folderPath = myURL.deletingLastPathComponent().path
                let downloadedFilePath = folderPath + "/" + lastPathComponent.replacingOccurrences(of: ".icloud", with: "")
                var isDownloaded = false
                while !isDownloaded {
                    if fileManager.fileExists(atPath: downloadedFilePath) {
                        isDownloaded = true
                        print("REALM FILE SUCCESSFULLY DOWNLOADED")
                        self.copyFileToLocal()

                    }
                    else
                    {
                        // This simple code launch the download
                        do {
                            try fileManager.startDownloadingUbiquitousItem(at: myURL )
                        } catch {
                            print("Unexpected error: \(error).")
                        }
                    }
                }


                // Do what you want with your downloaded file at path contains in variable "downloadedFilePath"
            }
        }
    }
}

2.Copy realm file from iCloud to Document directory

func copyFileToLocal() {
    if isCloudEnabled() {
        deleteFilesInDirectory(url: DocumentsDirectory.localDocumentsURL)
        let fileManager = FileManager.default
        let enumerator = fileManager.enumerator(atPath: DocumentsDirectory.iCloudDocumentsURL!.path)
        while let file = enumerator?.nextObject() as? String {

            do {
                try fileManager.copyItem(at: DocumentsDirectory.iCloudDocumentsURL!.appendingPathComponent(file), to: DocumentsDirectory.localDocumentsURL.appendingPathComponent(file))

                print("Moved to local dir")

                //HERE ACCESSING DATA AVAILABLE IN REALM GET FROM ICLOUD
                let realm =  RealmManager()
                let array = realm.FetchObjects(type: Mood.self)
                print(array?.count)

            } catch let error as NSError {
                print("Failed to move file to local dir : \(error)")
            }
        }
    }
}
like image 5
Anita Avatar answered Oct 31 '22 15:10

Anita