Realm swift: пустое пространство после повторного запуска приложения

#ios #swift #realm

#iOS #swift #область

Вопрос:

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

 class RealmManager {
     

static let shared = RealmManager()

let realm: Realm

init() {
    realm = try! Realm()
}

func write(_ completion: ()->Void) {
    do {
        try realm.write() {
            completion()
        }
    } catch {
        print(error)
    }
}

func add(_ object: Object) {
    realm.add(object)
}

func delete(_ object: Object) {
    realm.delete(object)
}

func objects<Element>(_ type: Element.Type) -> Results<Element> where Element : Object {
    return realm.objects(type)
}
}
  

Я создал этот синглтон, поэтому мне не нужно повторять это realm = try! Realm() везде в моем коде. У меня есть точно такой же класс в другом проекте, который работает нормально.

Моя модель выглядит так :

 class PrepFile: Object {


@objc dynamic var creationDate: Date = Date()
@objc dynamic var lastModificationDate: Date = Date()
@objc dynamic var title: String = "Pas de titre"

@objc dynamic var activityKind: String = ""
@objc dynamic var seanceNumber: Int = 0
@objc dynamic var level: String = ""
@objc dynamic var duration: Int = 0
@objc dynamic var date: Date = Date()
@objc dynamic var cycle: Int = 0

@objc dynamic var mainGoal: String = ""
@objc dynamic var specificGoal: String = ""
@objc dynamic var material: String = ""

@objc dynamic var isDraft: Bool = true

convenience init(title: String? = nil, activityKind: String? = nil, seanceNumber: Int? = nil, level: String? = nil, duration: Int? = nil, date: Date? = nil, cycle: Int? = nil, mainGoal: String? = nil, specificGoal: String? = nil, material: String? = nil, phases: [Phase] = [], isDraft: Bool = true) {
    self.init()
    if let tt = title {
        self.title = tt
    }
    if let ak = activityKind {
        self.activityKind = ak
    }
    if let sn = seanceNumber {
        self.seanceNumber = sn
    }
    if let lv = level {
        self.level = lv
    }
    if let dt = duration {
        self.duration = dt
    }
    if let dt = date {
        self.date = dt
    }
    if let cl = cycle {
        self.cycle = cl
    }
    if let mg = mainGoal {
        self.mainGoal = mg
    }
    if let sg = specificGoal {
        self.specificGoal = sg
    }
    if let mt = material {
        self.material = mt
    }
    self.isDraft = isDraft
}

required init() {
}
}
  

Затем в моем ВК вот что я делаю :

 class PrepFileListViewController: UIViewController {


@IBOutlet weak var tableView: UITableView!

lazy var prepFiles: Results<PrepFile> = { RealmManager.shared.objects(PrepFile.self) }()
var completePrepFiles: [PrepFile] = []
var draftPrepFiles: [PrepFile] = []

override func viewDidLoad() {
    super.viewDidLoad()
    tableView.delegate = self
    tableView.dataSource = self
    
    RealmManager.shared.write {
        for file in prepFiles {
            RealmManager.shared.delete(file)
        }
    }
    RealmManager.shared.write() {
        RealmManager.shared.add(PrepFile(title: "Fiche de prep 1"))
        RealmManager.shared.add(PrepFile(title: "Fiche de prep 2"))
        RealmManager.shared.add(PrepFile(title: "Fiche de prep 3"))
        RealmManager.shared.add(PrepFile(title: "Fiche de prep 4"))
        RealmManager.shared.add(PrepFile(title: "Fiche de prep 5"))
    }
}

override func viewWillAppear(_ animated: Bool) {
    prepFiles = RealmManager.shared.objects(PrepFile.self)
    completePrepFiles = prepFiles.filter({ !$0.isDraft })
    draftPrepFiles = prepFiles.filter({ $0.isDraft })
    tableView.reloadData()
}
}
  

Теперь, когда я запускаю это, оно работает нормально. Мои предварительные файлы добавляются в Realm, и я получаю их в порядке с помощью моего RealmManager.shared.objects (PrepFile.self). Теперь я комментирую ту часть, где я удаляю / добавляю свои файлы в viewDidLoad, и я ничего не получаю. Я не получаю пустые объекты из RealmManager.shared.objects (PrepFile.self), я получаю пустой результат, как будто там ничего не было сохранено.

Что я делаю не так?

Я использую Xcode 12 и запускаю свое приложение на симуляторе iPhone 11 / 13.3. Версия Realm — 5.5.0.

Комментарии:

1. Я скопировал и вставил ваш класс RealmManager и сохранил кучу «домашних» объектов, подобных этому RealmManager.shared.add(pet) , и все работало нормально. Вопрос: почему это lazy var prepFiles: Results<PrepFile> = , но затем viewWillAppear это делается снова prepFiles = RealmManager.shared.objects(PrepFile.self) .

2. Потому что я хотел бы, чтобы этот список обновлялся каждый раз, когда отображается контроллер, и мне нужно было его инициализировать. Ленивый, вероятно, бесполезен. Вы можете ознакомиться с полным проектом здесь: github.com/cmouline/FichesDePrep/tree/feature/Eureka . Как я уже сказал, я не думаю, что проблема в RealmManager, поскольку я использую точно такой же класс в другом проекте, и он работает нормально. Может быть, мой класс объектов, но я не вижу, что было бы неправильно: пожать плечами:

3. Ваш объект Realm также в порядке. Я скопировал и вставил это в проект, и он работал правильно. Вы открывали файл Realm с помощью Realm Studio, чтобы посмотреть, существуют ли объекты в файле?

4. После исследования с помощью Realm Studio я заметил, что default.realm создается просто отлично, и объекты хранятся нормально. Когда я перестаю запускать свое приложение, мой файл по умолчанию все еще существует, но когда я снова запускаю свое приложение, файл удаляется и не создается заново, пока я не попытаюсь восстановить свои объекты. Итак, теперь я пытаюсь выяснить, почему мой файл удаляется при повторном запуске моего приложения. Вероятно, мне следовало упомянуть, что я использую Xcode 12.0 и использую симулятор iPhone 11 / 13.3.

5. У вас есть блок миграции? У вас установлена конфигурация на config.deleteRealmIfMigrationNeeded ?

Ответ №1:

Хм, насколько я могу догадаться, у вас либо есть где-то еще конфигурация для realm, которая будет «inMemoryIdentifier», либо вы не задаете правильную конфигурацию с помощью fileURL при запуске приложения. Локальная область конфигурации: https://realm.io/docs/swift/latest/#realms

Комментарии:

1. У меня нет никакой другой конфигурации, и я использую конфигурацию по умолчанию из того, что я могу прочитать в документе. Я не использую inMemoryIdentifier или какую-либо функцию, связанную с миграцией. Код в моем вопросе — единственная часть, которая использует Realm в моем приложении.