ios – How to make a wrapper for Realm that won’t crash when used on different thread?


I am creating a wrapper for Realm so I can test my app easily with mocks. This is the code:

import Foundation
import RealmSwift
import Realm

class RealmStorage: LocalStoring {
    private static let configuration: Realm.Configuration = {
        let schemaString = Bundle.main.object(forInfoDictionaryKey: "Realm Schema") as? String ?? ""
        let schema = UInt64(schemaString) ?? 1
        return Realm.Configuration(schemaVersion: schema)
    }()
    private let category: String
    init(category: String) {
        self.category = category
    }
    
    func store<T: Object>(_ object: T) {
        do {
            let realm = try Realm(configuration: RealmStorage.configuration)
            try realm.write {
                realm.add(object, update: .all)
            }
        } catch {
            print("Realm error: \(error.localizedDescription)")
        }
    }
    
    func update<T: Object>(_ object: T, value: Any?, for key: String) {
        do {
            let realm = try Realm(configuration: RealmStorage.configuration)
            try realm.write {
                object.setValue(value, forKey: key)
            }
        } catch {
            print("Realm error: \(error.localizedDescription)")
        }
    }
    
    func retrieve<T: Object>(_ objectType: T.Type) -> [T] {
        
        guard let realm = try? Realm(configuration: RealmStorage.configuration) else {
            return []
        }
        
        let objects = realm.objects(objectType.self)
        return Array(objects)
    }
    
    func remove<T: Object>(_ objectType: T.Type,
                           where condition: @escaping (T) -> Bool) {
        do {
            let realm = try Realm(configuration: RealmStorage.configuration)
            try realm.write {
                let objects = realm.objects(objectType.self).filter(condition)
                realm.delete(objects)
            }
        } catch {
            print("Realm error: \(error.localizedDescription)")
        }
    }
    
    func removeAll<T: Object>(_ objectType: T.Type) {
        do {
            let realm = try Realm(configuration: RealmStorage.configuration)
            try realm.write {
                let objects = realm.objects(objectType.self)
                realm.delete(objects)
            }
        } catch {
            print("Realm error: \(error.localizedDescription)")
        }
    }
}

I tried storing the Realm instance once but it crashed when it is used in a background thread. With opening Realm object every time, it doesn’t crash but now it runs slower. There is 1-2 seconds waiting time to do anything.

How do I make it not crash without opening Realm all the time? I was thinking to store all the Objects into an array and just use it instead of the Realm database. And write to database only when needed to sync the data from the array and database. But I was hesitant since that means I have two source of truth. And this may create bugs when the data between the array and database is not the same. Do you have any other idea?

Thanks.

Latest articles

spot_imgspot_img

Related articles

Leave a reply

Please enter your comment!
Please enter your name here

spot_imgspot_img