Существует ли способ быстрого добавления новых данных из второго пакета областей без перезаписи существующих данных в текущей области по умолчанию? - PullRequest
0 голосов
/ 16 октября 2019

При первоначальной загрузке приложения Bundled Realm (Realm1) копируется в папку документов. Теперь, когда связанная область установлена ​​как область по умолчанию, я могу обновить свойство bool, чтобы в табличном представлении могли отображаться отмеченные и немаркированные ячейки. Однако я ищу способ связать вторую область (Realm2) с последующим обновлением, которое добавит новые данные в существующую область по умолчанию, но без перезаписи текущей области по умолчанию. В настоящее время я работаю в Swift 5 и Xcode 11.1, если это полезно.

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

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

Ниже приведен текущий код, который я реализовал для загрузки области по умолчанию из пакета.



    let bundlePath = Bundle.main.path(forResource: "preloadedData", ofType: "realm")!
            let defaultPath = Realm.Configuration.defaultConfiguration.fileURL!.path
            let fileManager = FileManager.default

    //        Copy Realm on initial launch
            if !fileManager.fileExists(atPath: defaultPath){
                do {
                    try fileManager.copyItem(atPath: bundlePath, toPath: defaultPath)
                    print("Realm was copied")
                } catch {
                    print("Realm was not coppied \(error)")
                }
            }
            return true

Ответы [ 2 ]

0 голосов
/ 04 ноября 2019

Я добавляю дополнительный ответ, который в некоторой степени связан с первым, но также стоит сам по себе.

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

Способ заключается в том, чтобы инкапсулировать вызовы Realm в пул автоматического выпуска, чтобы эти объекты могли быть освобождены при удалении Realm.

Вот пример:

Эта функция добавляет объект GameData в файл default.realm.

func addAnObject() {
   autoreleasepool {
      let realm = try! Realm()
      let testData = GameData()
      testData.Scenario = "This is my scenario"
      testData.Id = 1
      try! realm.write {
         realm.add(testData)
      }
   }
}

В этот момент, если вы запустите код addAnObject, ваш файл будетесть объект GameData.

GameData {
    Id = 1;
    GameDate = (null);
    Scenario = This is my scenario;
    GameStarted = 0;
}

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

func createDefaultRealm() {
   let defaultURL = Realm.Configuration.defaultConfiguration.fileURL!
   let defaultParentURL = defaultURL.deletingLastPathComponent()

   if let bundledRealmURL = self.bundleURL("default") {
      do {
         try FileManager.default.removeItem(at: defaultURL)
         try FileManager.default.copyItem(at: bundledRealmURL, to: defaultURL)
      } catch let error as NSError {
          print(error.localizedDescription)
          return
      }
   }

   let migrationBlock : MigrationBlock = { migration, oldSchemaVersion in
      //handle migration
   }

   Realm.Configuration.defaultConfiguration = Realm.Configuration(schemaVersion: 18, migrationBlock: migrationBlock)

   print("Your default realm objects: \(try! Realm().objects(GameData.self))")
}

func bundleURL(_ name: String) -> URL? {
    return Bundle.main.url(forResource: name, withExtension: "realm")
}

и обратите внимание, что если вы обращаетесь к Realm внутри класса, но снаружи пул авто-релизов, Realm откажется «отпускать» свои объекты.

НЕ делайте этого !!

class ViewController: UIViewController {
    var realm = try! Realm()
0 голосов
/ 18 октября 2019

После того, как вы создали свое Королевство по умолчанию на диске, если вы хотите прочитать данные из комплектного, вот код

    let config = Realm.Configuration(
        // Get the URL to the bundled file
        fileURL: Bundle.main.url(forResource: "MyBundledData", withExtension: "realm"),
        // Open the file in read-only mode as application bundles are not writeable
        readOnly: true)
    let realm = try! Realm(configuration: config)

и после того, как вы прочитали данные, вы можете переключиться обратно

var config = Realm.Configuration()
config.fileURL = config.fileURL!.deletingLastPathComponent().appendingPathComponent("\(some_realm_name).realm")
Realm.Configuration.defaultConfiguration = config

, если не перезаписать, убедитесь, что ваши объекты используют уникальный первичный ключ, и при их записи ничто не будет перезаписано, так как объекты добавят уникальный первичный ключ вместо перезаписи.

class MyClass: Object {
    @objc dynamic var my_primary_id = NSUUID().uuidString
...