我想将一个领域数据库文件备份到一个iCloud驱动器,比如WhatsApp,我有一些问题:
这样做的最佳做法是什么?
我有一个位于共享组文件夹中的数据库,可以从扩展程序访问它,我该如何备份它?如何显示上传的进度条?像WhatsApp一样?
如果我将一个领域文件放在一个文档文件夹中,它将同步进行每次修改。
我们可以看到一些示例代码吗?
感谢您的帮助,有什么想法吗?链接?
答案 0 :(得分:8)
为了澄清,这是一个关于将离散Realm文件本身备份到iCloud Drive的问题,以便它可以在iCloud Drive应用程序中看到。不将文件内容同步到CloudKit商店。
如果将Realm文件保留在Documents目录中,则如果用户执行iCloud或iTunes备份,则将备份该文件。所有这些意味着,如果用户决定升级到新设备并使用旧设备的备份映像执行还原,则将恢复Realm文件。如果用户在此之前从旧设备中删除了应用程序,则iCloud备份也将被删除。
如果您要导出您的Realm文件,以便可以在iCloud Drive中永久保存和访问它,您可以将Realm文件的副本导出到您应用的iCloud ubiquity container。这基本上只是另一个文件夹,如共享组的文件夹,但它由iCloud管理。此文件夹的行为类似于Dropbox,因为您放入的任何内容都会自动同步。
代码看起来像这样:
let containerURL = FileManager.default.url(forUbiquityContainerIdentifier: nil)
let realmArchiveURL = containerURL.appendPathComponent("MyArchivedRealm.realm")
let realm = try! Realm()
try! realm.writeCopy(toFile: realmArchiveURL)
这是一个非常基本的例子。 Apple文档建议您在后台线程上执行此操作,因为首次设置iCloud文件夹可能会创建一些时间。
更新此功能不会自动发生。每次用户想要执行备份时,您都需要导出Realm的新副本。
答案 1 :(得分:2)
您可以mikemac8888
查看this Github project。
基本上,您使模型对象符合RealmCloudObject
:
class Note: Object, RealmCloudObject {
...
}
您必须实现映射功能:
func toRecord() -> CKRecord {
...
record["text"] = self.text
record["dateModified"] = self.dateModified
}
...以及用于从CloudKit记录中创建Realm记录的反向函数:
public func changeLocalRecord(...) throws {
...
realm.create(objectClass as! Object.Type,
value: ["id": id,
"text": text,
"dateModified": NSDate(),
"ckSystemFields": recordToLocalData(record)],
update: true)
...
}
完整的文档可以在我提供的链接上阅读,显然。
答案 2 :(得分:2)
我最近有相同的要求,并且可以通过以下步骤实现
快速键:4 +
步骤:1
Private items As New BindingList(Of String)
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
ListBox1.DataSource = items
End Sub
Private Sub addButton_Click(sender As Object, e As EventArgs) Handles addButton.Click
items.Add(TextBox1.Text)
End Sub
Private Sub deleteSelectedButton_Click(sender As Object, e As EventArgs) Handles deleteSelectedButton.Click
items.RemoveAt(ListBox1.SelectedIndex)
End Sub
Private Sub deleteLastButton_Click(sender As Object, e As EventArgs) Handles deleteLastButton.Click
items.RemoveAt(items.Count - 1)
End Sub
第2步
1.Setup Your cloudKit for your app with a Developer account
2. You can take reference: https://www.raywenderlich.com/1000-cloudkit-tutorial-getting-started
第3步 -检查iPhone的“云启用”选项
- Add CloudKit Capabilities in your App
- Please check out the screenshot: https://prnt.sc/pdpda5
步骤4 -为本地或iCloud文档目录设置以下变量
// Return true if iCloud is enabled
func isCloudEnabled() -> Bool {
if DocumentsDirectory.iCloudDocumentsURL != nil { return true }
else { return false }
}
步骤:5 下面的函数用于copyRealmFileToIcloudContainer
struct DocumentsDirectory {
static let localDocumentsURL = FileManager.default.urls(for: FileManager.SearchPathDirectory.documentDirectory, in: .userDomainMask).last!
static let iCloudDocumentsURL = FileManager.default.url(forUbiquityContainerIdentifier: nil)?.appendingPathComponent("Documents")
}
Step:6
func uploadDatabaseToCloudDrive()
{
if(isCloudEnabled() == false)
{
self.iCloudSetupNotAvailable()
return
}
let fileManager = FileManager.default
self.checkForExistingDir()
let iCloudDocumentsURL = FileManager.default.url(forUbiquityContainerIdentifier: nil)?.appendingPathComponent("Documents", isDirectory: true)
let iCloudDocumentToCheckURL = iCloudDocumentsURL?.appendingPathComponent("\(memberId)_default.realm", isDirectory: false)
let realmArchiveURL = iCloudDocumentToCheckURL//containerURL?.appendingPathComponent("MyArchivedRealm.realm")
if(fileManager.fileExists(atPath: realmArchiveURL?.path ?? ""))
{
do
{
try fileManager.removeItem(at: realmArchiveURL!)
print("REPLACE")
let realm = try! Realm()
try! realm.writeCopy(toFile: realmArchiveURL!)
}catch
{
print("ERR")
}
}
else
{
print("Need to store ")
let realm = try! Realm()
try! realm.writeCopy(toFile: realmArchiveURL!)
}
}
步骤:7 -确保已在info.plist中添加了以下几行
- Once your realm file uploaded on the server , you can check this in your iPhone
- Steps
- 1.Go To Setting
- 2.Go To iCloud
- 3.Go To ManageStorage
- 4.You will see your application there
- 5.Tap on Application, you will able to see your realm file over there
答案 3 :(得分:2)
@yonlau根据您对备份领域文件的请求共享答案,此文件将进行一次测试,并且领域数据仅在备份到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。将领域文件从iCloud复制到文档目录
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)")
}
}
}
}