I am kind of performing an upsert (update or insert) operation after fetching from an JSON API for some entities which have many to one relations.
Eg: Sections contains Categories, Categories contains Songs
So while going through a for loop I kind of get a crash while performing operation.
This is my fetch logic using a predicate.
public extension SongEntity {
static func fetchOrCreate(for songID: String, in context: NSManagedObjectContext) -> SongEntity {
PersistenceController.shared.fetchSingle(SongEntity.self, predicate: SongEntity.bySongID(songID)) ?? SongEntity(context: context)
}
static func bySongID(_ songID: String) -> NSPredicate {
NSPredicate(format: "identifier == %@", songID)
}
}
public func fetchSingle<T: NSManagedObject>(
_ entityClass: T.Type,
sortBy sortDescriptors: [NSSortDescriptor]? = nil,
predicate: NSPredicate? = nil
) -> T? {
let entityName = String(describing: entityClass)
let fetchRequest = NSFetchRequest<T>(entityName: entityName)
fetchRequest.sortDescriptors = sortDescriptors
fetchRequest.predicate = predicate
fetchRequest.fetchLimit = 1
do {
let items = try PersistenceController.shared.container.viewContext.fetch(fetchRequest)
return items.first
} catch {
debugPrint(error.localizedDescription)
return nil
}
}
This is where the crash tends to appear
for section in songsData.sections {
let sectionEntity = Section.fetchOrCreate(for: section.identifier, in: viewContext)
sectionEntity.identifier = section.identifier
sectionEntity.title = section.title
var categories: [Category] = []
for category in songsData.sectionCategories {
if category.sectionID == section.identifier {
let existingCategory = Category.fetchOrCreate(for: category.identifier, in: viewContext)
existingCategory.title = category.title
existingCategory.identifier = category.identifier
existingCategory.sectionID = category.sectionID
var songs: [SongEntity] = []
for song in songsData.songs {
if song.categoryID == category.identifier {
// CRASH OCCURS HERE
let existingSong = SongEntity.fetchOrCreate(for: song.identifier, in: viewContext)
existingSong.categoryID = song.categoryID
existingSong.identifier = song.identifier
existingSong.title = song.title
songs.append(existingSong)
}
}
existingCategory.addToSongs(NSOrderedSet(array: songs))
categories.append(existingCategory)
}
}
sectionEntity.addToCategories(NSOrderedSet(array: categories))
}
What am I doing wrong? Am I handling the relationships correctly?
Sometimes I also get EXC_BAD_ACCESS error as well? I am novice to relationships upserts. So please help me out where I am wrong exactly
hb_dev is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.