Управление файлами Realm - PullRequest
       6

Управление файлами Realm

0 голосов
/ 11 января 2019

Мы уже некоторое время используем Realm, и некоторые наши пользователи испытывают некоторую потерю данных, связанных с Realm. Мы думаем, что сузили его до нашего метода сжатия, когда файл становится слишком большим. Мы хотели бы попросить небольшой совет, если это правильный способ для воссоздания нашего файла Realm. Этот метод вызывается для applicationDidEnterBackground.

Ниже мы написали пример того, что мы делаем:

public static func compact() {
    // Get the original file path
    let configuration = RealmSampleClient.shared.config
    guard let originalFileURL = configuration.fileURL else {
        return
    }
    // check if the file size is bigger than 10mb, if not return
    guard let attr = try? FileManager.default.attributesOfItem(atPath: originalFileURL.absoluteString),
        let fileSize = attr[FileAttributeKey.size] as? UInt64,
        fileSize > 500_000_000 else {
            return
    }

     // create a filepath for a copy
    let date = Date()
    let dateFormatter = DateFormatter()
    dateFormatter.dateFormat = "yyyyMMddHHmmss"
    let dateString = "\(dateFormatter.string(from: date)).realm"
    let copyFileURL = originalFileURL.deletingLastPathComponent().appendingPathComponent(dateString)

     // copy the Realm file
    do {
        let realm = try Realm(configuration: configuration)
        try realm.writeCopy(toFile: copyFileURL, encryptionKey: configuration.encryptionKey)
    } catch {
        return
    }

     // remove the old file and copy the new one
    do {
        removeRealmFile(at: originalFileURL)
        try FileManager.default.copyItem(at: copyFileURL, to: originalFileURL)
    } catch {
    }
    // remove a copy if it exists
    guard FileManager.default.fileExists(atPath: copyFileURL.path) else { return }
    do {
        try FileManager.default.removeItem(at: copyFileURL)
    } catch {
    }
}

private static func removeRealmFile(at url: URL = databaseUrl) {
        let realmURLs = [
            url,
            url.appendingPathExtension("lock"),
            url.appendingPathExtension("note"),
            url.appendingPathExtension("management"),
        ]
        realmURLs.forEach { URL in
            guard FileManager.default.fileExists(atPath: URL.path) else { return }
            do {
                try FileManager.default.removeItem(at: URL)
            } catch {
            }
        }
}

Спасибо за вашу помощь

Ответы [ 2 ]

0 голосов
/ 11 января 2019

Согласно документу Realm, рекомендуется обернуть ваш код с помощью autoreleasepool, например,

do {
    let realm = try Realm(configuration: configuration)
    try realm.writeCopy(toFile: copyFileURL, encryptionKey: configuration.encryptionKey)
} catch {
    return
}

и выполнение этой задачи в фоновом режиме определенно поможет, дружеский совет - всегда обрабатывать ошибки, вы просто возвращаетесь в блок catch, может помочь журнал.

Более подробно изучив документацию, я вижу, что RealmSwift теперь имеет функцию сжатия, подробнее здесь: https://realm.io/docs/swift/latest/#compacting-realms

0 голосов
/ 11 января 2019

Я не вижу здесь никакого вида кода сжатия, только копия файла базы данных. Поэтому я предполагаю, что вы оставили это, чтобы сохранить здесь компактный код.

В любом случае, вы делаете эту операцию, когда приложение переходит в фоновый режим. Вы регистрируете фоновое задание для этого? Если операция сжатия занимает слишком много времени, IOS убивает задачу, я думаю, что это проблема.

Вы можете явно запросить у ОС дополнительное время выполнения в фоновом режиме с помощью UIApplication.shared.beginBackgroundTask, но это также очень ограниченное по времени количество, обычно 3 минуты.

Но это все копается в темноте, вы должны опубликовать больше кода, чтобы увидеть, как настроена ваша фоновая задача.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...