I have 2 almost identical methods, they differ only in the model that is stored in the realm. And for some reason, one of them manipulates its model without problems, while the other throws me the error “Realm accessed from incorrect thread”. I can’t figure out what the problem is.
func savePOIs(pois:[POI], implan: String) { <<<That work good>>>
autoreleasepool {
// check there are results to store or return
guard pois.count > 0 else { return }
// build the set of new pois
var newPois: Set<String> = []
for p in pois { newPois.insert(p.uid ?? "")}
// delete only the pois in the database which are not in the set
// write all new pois
DispatchQueue.global(qos: .background).async {
let realmBackground = try! Realm()
for oldPoi in realmBackground.objects(POI.self).filter("name_implan == %@", implan) {
if !newPois.contains(oldPoi.uid ?? "") {
try! realmBackground.write { realmBackground.delete(oldPoi) }
}
}
}
// keep the uis of the ephemeral sorting order
let oldSortingOrder = realm.objects(POI.self).filter("ephemeral_sorting_order > 0")
var dicSortingOrder: [Int: Int] = [:]
for poi in oldSortingOrder {
dicSortingOrder[poi.ephemeral_sorting_order] = poi.ephemeral_sorting_order
}
// write all new pois
DispatchQueue.global(qos: .background).async {
let realmBackground = try! Realm()
try! realmBackground.write {
for poi in pois { realmBackground.add(poi, update: .all) }
}
try! realmBackground.write {
for (uid, order) in dicSortingOrder {
if let poi = realmBackground.objects(POI.self).filter(NSPredicate(format: "ephemeral_sorting_order = %d", uid)).first {
poi.ephemeral_sorting_order = order
}
}
}
}
let finalSize = realm.objects(POI.self).count
print("\(LOG_TAG) - savePOIs - final size (all implans) = \(finalSize), new pois = \(pois.count), ")
// prefetch images for all pois
if Utils.hasInternetConnection() { ImageClient.sharedInstance.prefetchAllImages(prefetchType: .pois, implan: implan) }
}
}
func saveSmallPOIs(pois: [SmallPOI], implan: String) { <<<That throw error>>>
autoreleasepool {
// check there are results to store or return
guard pois.count > 0 else { return }
// build the set of new pois
var newPois: Set<String> = []
for p in pois { newPois.insert(p.smallPOIUID ?? "")}
// delete only the pois in the database which are not in the set
// write all new pois
DispatchQueue.global(qos: .background).async {
let realmBackground = try! Realm()
for oldPoi in realmBackground.objects(SmallPOI.self).filter("name_implan == %@", implan) {
if !newPois.contains(oldPoi.smallPOIUID ?? "") {
try! realmBackground.write { realmBackground.delete(oldPoi) }
}
}
}
// keep the uis of the ephemeral sorting order
let oldSortingOrder = realm.objects(SmallPOI.self).filter("ephemeral_sorting_order > 0")
var dicSortingOrder: [Int: Int] = [:]
for poi in oldSortingOrder {
dicSortingOrder[poi.ephemeral_sorting_order] = poi.ephemeral_sorting_order
}
// write all new pois
DispatchQueue.global(qos: .background).async {
let realmBackground = try! Realm()
try! realmBackground.write {
for poi in pois { realmBackground.add(poi, update: .all) }
}
try! realmBackground.write {
for (uid, order) in dicSortingOrder {
if let poi = realmBackground.objects(SmallPOI.self).filter(NSPredicate(format: "ephemeral_sorting_order = %d", uid)).first {
poi.ephemeral_sorting_order = order
}
}
}
}
let finalSize = realm.objects(SmallPOI.self).count
print("\(self.LOG_TAG) - savePOIs - final size (all implans) = \(finalSize), new pois = \(pois.count), ")
// prefetch images for all pois
if Utils.hasInternetConnection() { ImageClient.sharedInstance.prefetchAllImages(prefetchType: .smallPOIs, implan: implan) }
}
}