Search code examples
iosarraysswiftcombine

Listening to updates in an Array of Objects in Swift


I'm working on a project where I need to listen to any changes in an array of objects. By changes I refer:

  1. Add/Remove element in the array
  2. Any change in the existing array elements

Here is the sample code,

enum DownloadState {
    case queued
    case completed
}

class DownloadTask: ObservableObject {
    var downloadState: DownloadState = .queued
}

class DownloadManager {
    var downloadTasks = [DownloadTask]()
}

In the above code, DownloadManager contains an array of DownloadTask. I want to listen to the changes when,

  1. A new DownloadTask instance is added into downloadTasks array
  2. An existing DownloadTask instance is removed from downloadTasks array
  3. The underlying DownloadState is changed for a particular DownloadTask in downloadTasks array

Solution

  • The approach that worked for us:

    1. Create a protocol to listen to any changes in the DownloadTask

    public protocol DownloadStateHandlerDelegate: AnyObject {
        func didUpdateDownloadState(title: String, downloadState: DownloadState)
    }
    

    2. Passed the delegate instance to the DownloadManager during initialization.

    class DownloadManager {
        private weak var delegate: DownloadStateHandlerDelegate?
        private var downloadTasks = [DownloadTask]()
    
        init(delegate: DownloadStateHandlerDelegate) {
            self.delegate = delegate
        }
    }
    

    3. Called the delegate method didUpdateDownloadState whenever the downloadState of a DownloadTask is updated.

    Example:

    class DownloadTask {
        @Published private var downloadState: DownloadState {
            didSet {
                self.delegate?.didUpdateDownloadState(title: self.title, downloadState: self.downloadState)
            }
        }
    }