如何用从 iCloud 下载的另一个 Realm 替换默认 Realm [英] How to replace default Realm with another Realm downloaded from iCloud

查看:71
本文介绍了如何用从 iCloud 下载的另一个 Realm 替换默认 Realm的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的应用程序使用 CloudKit 来备份领域数据并在用户按下某个按钮时获取数据.我编码以使用以下代码将default.realm"文件从文档文件夹上传到 iCloud.而且数据好像上传的不错.

My app uses CloudKit to backup the realm data and fetch the data whenever user press a certain button. I coded to upload "default.realm" file from documents folder to iCloud with below code. And the data seems to be uploaded well.

// create file path from app's documents folder
NSString* filePath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString* fileName = @"default.realm";
NSString* fileAtPath = [filePath stringByAppendingPathComponent:fileName];
CKRecordID *recordID = [[CKRecordID alloc] initWithRecordName:kRecordName];
CKRecord *record = [[CKRecord alloc] initWithRecordType:kRecordType recordID:recordID];

if ([[NSFileManager defaultManager] fileExistsAtPath:fileAtPath]) {
    CKAsset *asset = [[CKAsset alloc] initWithFileURL:[NSURL fileURLWithPath:fileAtPath]];
    [record setObject:asset forKey:@"Realm"];
}

// upload
CKDatabase *privateDatabase = [[CKContainer defaultContainer] privateCloudDatabase];
[privateDatabase saveRecord:record completionHandler:^(CKRecord *record, NSError *error) {
    // completion handling
}

下面是下载部分.我也可以下载,但似乎领域文件没有被替换.

And below is the download part. I can download as well but seems like the realm file is not replaced.

CKDatabase *privateDatabase = [[CKContainer defaultContainer] privateCloudDatabase];
CKRecordID *recordID = [[CKRecordID alloc] initWithRecordName:kRecordName];

// fetch realm from cloud
[privateDatabase fetchRecordWithID:recordID completionHandler:^(CKRecord *record, NSError *error) {
  if (!error) {
        CKAsset *realmAsset = record[@"Realm"];
        NSData *realmData = [NSData dataWithContentsOfURL:realmAsset.fileURL];
        NSString* filePath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
        NSString* fileName = @"default.realm";
        NSString* fileAtPath = [filePath stringByAppendingPathComponent:fileName];

        // delete existing default.realm file in documents
        if ([[NSFileManager defaultManager] fileExistsAtPath:fileAtPath]) {
            [[NSFileManager defaultManager] removeItemAtPath:fileAtPath error:&error];
        }
        // create a new default.realm file with downloaded data
        if([[NSFileManager defaultManager] createFileAtPath:fileAtPath contents:realmData attributes:nil]) {
              // code goes thru here but nothing changes
        }
    }
}];

我想替换整个领域文件.我究竟做错了什么?我应该从哪里开始?任何建议将不胜感激.

I want to replace the entire realm file. What am I doing wrong? Where should I start from? Any advice will be appreciated.

推荐答案

要更改 Realm 文件路径,请设置为 Realm.Configuration.fileURL 的路径.

To change Realm file path, set to the path to Realm.Configuration.fileURL.

let fileURL = ...
let config = Realm.Configuration(fileURL: fileURL)

let realm = try! Realm(configuration: config)

如果不想每次都指定文件路径,可以将配置对象设置为默认配置.

If you'd not like to specify file path every time, you can set the configuration object as a default configuration.

let fileURL = ...
let config = Realm.Configuration(fileURL: fileURL)

Realm.Configuration.defaultConfiguration = config

let realm = try! Realm()

另见 https://realm.io/docs/swift/latest/#领域配置

基于这些,在运行时交换 Realm 文件是非常危险的.要实现这一点,您必须保证根本没有 Realm 的强引用.取而代之的是,您可以创建另一个文件并切换到使用它.

Based on these, to swap Realm files at run-time is very dangerous. To achieve this, you have to guarantee there are no Realm's strong references at all. Instead of this, you can create another file and switch to using it.

// fetch realm from cloud
[privateDatabase fetchRecordWithID:recordID completionHandler:^(CKRecord *record, NSError *error) {
  if (!error) {
        CKAsset *realmAsset = record[@"Realm"];
        ...

        // Do not delete existing default.realm file in documents

        // create a new default.realm file with downloaded data
        // as deferent file name

        NSString* newFileName = @"default1.realm"; // default2.realm, default3.realm, ...
        NSString* newfileAtPath = [filePath stringByAppendingPathComponent:newfileAtPath];
        if([[NSFileManager defaultManager] createFileAtPath:newfileAtPath contents:realmData attributes:nil]) {
              // Switch to using new file to create Realm instance
              // e.g. set new file path to de default configuration file URL
              let config = Realm.Configuration(fileURL: NSURL(fileURLWithPath: newfileAtPath)!)
              Realm.Configuration.defaultConfiguration = config
              ...
        }

这篇关于如何用从 iCloud 下载的另一个 Realm 替换默认 Realm的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆