swiftcore-dataviewcontext

How do I loop through all open background view contexts and perform a save?


I have a program that concurrently reads the data from 3 separate CSV files into 3 separate background view contexts all based on the same persistent container. Once the data has been inserted into the view contexts I use a series of if statements to test if changes have been made, and if so, save the view contexts to the common persistent store. The program works. But it seems to me that I should be able to query core data for a listing of these view contexts and then in turn loop through them and perform the save, simplifying the code. Unfortunately I have been unable to determine how to do it. Below is a subset of my code which is all contained within the same view model class.

let BGContext1 = persistentContainer.newBackgroundContext()
let BGContext2 = persistentContainer.newBackgroundContext()
let BGContext3 = persistentContainer.newBackgroundContext()

... code that loads view contexts with data via withTaskGroup

if BGContext1.hasChanges {
    do {
        try BGContext1.save()
    } catch {
        print("error saving \(error)")
    }
}
if BGContext2.hasChanges {
    do {
        try BGContext2.save()
    } catch {
        print("error saving \(error)")
    }
}
if BGContext3.hasChanges {
    do {
        try BGContext3.save()
    } catch {
        print("error saving \(error)")
    }
}

Solution

  • Larme is correct. Putting the save functionality into my parsing function works. Since then, I learned that you can save the CSV data directly into Core Data i.e. an SQLite file with a batch insert. Below is the function that performs the batch insert. This eliminates having to perform a save on the view contexts and its is very fast.

    func CSVtoCoreData(latestDate: Date, bgContext: NSManagedObjectContext) async {
        bgContext.performAndWait {
            var arrayOfDict: [[String:Any]] = []
            var data: String = ""
            do {
                data = try String(contentsOfFile: filePath)
            } catch {
                print(error)
                return
            }
            var rows = data.components(separatedBy: "\n")
            rows.removeFirst()
            for row in rows {
                let columns = row.components(separatedBy: ",")
                let tempDate = columns[0].replacingOccurrences(of: "/", with: "")
                let tempTimeStamp = stringToDateFormatterWSJ.date(from: tempDate)!
                let close = Float(columns[4].replacingOccurrences(of: " ", with: ""))!
                
                let newRecord: [String:Any] = [
                    "fundName": fundName,
                    "id": UUID(),
                    "timeStamp": tempTimeStamp,
                    "close": close
                ]
                arrayOfDict.append(newRecord)
            }
            let insertRequest = NSBatchInsertRequest(entity: TradingDayClose.entity(), objects: arrayOfDict)
            bgContext.mergePolicy = NSMergeByPropertyStoreTrumpMergePolicy
            _ = try? bgContext.execute(insertRequest) as? NSBatchInsertResult
        }
    }