最后我们弄清楚了如何处理客户端重置错误。我们已采取以下步骤来避免数据丢失,以防用户离线并上线并出现重置错误。
将本地领域保存到另一个目录
使领域无效并为零
启动领域手动重置 - 调用传递SyncSession.immediatelyHandleError
,clientResetToken
它将从目录中删除现有领域
显示客户端重置警报 - 这将提示用户重新启动应用程序。
在下一次启动时,领域会从 ROS 中创建一个新领域。
新领域连接后,从上面备份目录中保存的旧领域恢复领域记录(如果有)。
从目录中删除备份领域(旧领域)。
switch syncError.code {
case .clientResetError:
if let (path, clientResetToken) = syncError.clientResetInfo() {
// taking backup
backUpRealm(realm: yourLocalRealm)
// making realm nil and invalidating
yourLocalRealm?.invalidate()
yourLocalRealm = nil
//Initiate realm manual reset - Call `SyncSession.immediatelyHandleError` with `clientResetToken` passed and it will delete the existing realm from directory
SyncSession.immediatelyHandleError(clientResetToken)
// can show alert to user to relaunch the app
showAlertforAppRelaunch()
}
default:
// Handle other errors...
()
}
}```
备份领域代码如下所示:
func backUpRealm(realm: Realm?) {
do {
try realm?.writeCopy(toFile: backupUrl)
} catch {
print("Error backing up data")
}
}
完成此备份后,备份路径将可用。在下一次启动时,设备将连接并从 ROS 下载新领域,因此在设备连接后,从备份路径中保存的备份领域恢复领域记录。
还原合并备份代码将如下所示。在重新启动后连接领域时放置以下方法。 ```restoredRealm` 是启动时新下载的领域
func restoreAndMergeFromBackup(restoredRealm: Realm?) {
let realmBackUpFilePath = isRealmBackupExits()
// check if backup exists or not
if realmBackUpFilePath.exists {
let config = Realm.Configuration(
fileURL: URL(fileURLWithPath: realmBackUpFilePath.path),
readOnly: true)
let realm = try? Realm(configuration: config)
guard let backupRealm = realm else { return }
//Get your realm Objects
let objects = backupRealm.objects(YourRealmObject.self)
try? restoredRealm?.safeWrite {
for object in objects {
// taking local changes to the downloaded realm if it has
restoredRealm?.create(YourRealmObject.self, value: object, update: .modified)
}
self.removeRealmFiles(path: realmBackUpFilePath.path)
}
} else {
debug("backup realm does not exists")
}
}
private func isRealmBackupExits() -> (exists: Bool, path: String) {
let documentsPath = URL(fileURLWithPath: NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0])
let realmPathComponent = documentsPath.appendingPathComponent("your_backup.realm")
let filePath = realmPathComponent.path
let fileManager = FileManager.default
if fileManager.fileExists(atPath: filePath) {
return (true, filePath)
}
return (false, "")
}
private func removeRealmFiles(path: String) {
let realmURL = URL(fileURLWithPath: path)
let realmURLs = [
realmURL,
realmURL.appendingPathExtension("lock"),
realmURL.appendingPathExtension("realm"),
realmURL.appendingPathExtension("management")
]
for URL in realmURLs {
do {
try FileManager.default.removeItem(at: URL)
} catch {
debug("error while deleting realm urls")
}
}
}```
在我们的测试中,我们发现领域会自动进行备份,因此出于安全目的我们将其删除。您将获得的路径参数if let (path, clientResetToken) = syncError.clientResetInfo()
func removeAutoGeneratedRealmBackUp(path: String) {
do {
try FileManager.default.removeItem(at: URL(fileURLWithPath: path))
} catch {
debug("error while deleting realm backUp path \(path)")
}
}