How do you pass data between operations in swift

Viewed 33

I am trying to learn swift. I am currently looking at operations. I can queue up a series of operations and they run. Where I run into a problem is trying to pass data between operations. My getVOOCSVData operation retrieves the correct data which I can confirm by placing a print statement in its completion block. Unfortunately, I cannot figure out how to pass this retrieved data onto the next operation. The next operation (convertStringToArray) runs but the data I attempt to pass in is empty. Below are my operation setup and ConvertStringToArray2 class which is assigned to the convertStringToArray variable.

// operation setup
struct VOOModel {
    init() {
        let operationQueue = OperationQueue()
        let checkForUpdatedVOOData = IsUpdatedVOODataAvailable()
        checkForUpdatedVOOData.completionBlock = {
            print("Updated CSV Data = \(checkForUpdatedVOOData.updatedCSVData)")
            print("Latest Date = \(checkForUpdatedVOOData.latestCSVDate)")
        }
        let getVOOCSVData = GetVOOCSVData()
        getVOOCSVData.addDependency(checkForUpdatedVOOData)
        getVOOCSVData.completionBlock = {
            print("completion block get voo csv data")
            print("\(getVOOCSVData.csvData)") // prints out all of the data correctly
        }
        let convertStringToArray = ConvertStringToArray2(csvData: getVOOCSVData.csvData)
        convertStringToArray.addDependency(getVOOCSVData)
        convertStringToArray.completionBlock = {
            print("completion block convert string to array")
        }
        operationQueue.addOperations([checkForUpdatedVOOData, getVOOCSVData, convertStringToArray], waitUntilFinished: true)
    } // end init
} // end structure

// operation class
final class ConvertStringToArray2: Operation {
    var localData: String
    var sortedDataArray : [IndexFund] = []
    init(csvData: String) {
        localData = csvData
    }
    override func main() {
        var dataArray = [IndexFund]()
        var rows = localData.components(separatedBy: "\n")  // gives rows a value of 1
        rows.removeFirst()
        for row in rows {
            let columns = row.components(separatedBy: ",")
            if columns.count == 6 {
                let theDate = columns[0].replacingOccurrences(of: "-", with: "")
                let timeStamp = stringDateFormatter.date(from: theDate)!
                let open = Double(columns[1])!
                let high = Double(columns[2])!
                let low = Double(columns[3])!
                let close = Double(columns[4])!
                let theVolume = columns[5].trimmingCharacters(in: CharacterSet.whitespacesAndNewlines)
                let volume = Int64(theVolume)
                let fundValuesByDay = IndexFund(
                    timeStamp: timeStamp,
                    open: open,
                    high: high,
                    low: low,
                    close: close,
                    volume: volume!)
                dataArray.append(fundValuesByDay)
            }
            sortedDataArray = dataArray.sorted {
                $0.timeStamp < $1.timeStamp
            }
        }
    }
}
1 Answers

After some additional research I found that a block operation allows me to pass data between operations. Below is the updated code. It all runs in the init of my model as above. The link below is the site used to understand how to utilize the block operation.

https://medium.com/@marcosantadev/4-ways-to-pass-data-between-operations-with-swift-2fa5b3a3d561

       let operationQueue = OperationQueue()
        let updatedVOOData = IsUpdatedVOODataAvailable()
        updatedVOOData.completionBlock = {
            if updatedVOOData.updatedCSVData == true {
                let fetchVOO = GetVOOCSVData()
                let updateVOO = UpdateVOOPersistentStore()
                let vooAdapter = BlockOperation() { [unowned updateVOO, unowned fetchVOO] in
                    updateVOO.dataArray = fetchVOO.dataArray
                }
                vooAdapter.addDependency(fetchVOO)
                updateVOO.addDependency(vooAdapter)
                operationQueue.addOperations([fetchVOO, updateVOO, vooAdapter], waitUntilFinished: true)
            } // end if block
            print("Updated CSV Data = \(updatedVOOData.updatedCSVData)")
            print("Latest Date = \(updatedVOOData.latestCSVDate)")
        } // end completion block
        operationQueue.addOperations([updatedVOOData], waitUntilFinished: true)

Related