0

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
PGDev
  • 23,751
  • 6
  • 34
  • 88

2 Answers2

0

A possible approach is to make task a value type and manager as ObservableObject with published property for array of tasks, like

struct DownloadTask {
    var downloadState: DownloadState = .queued
}

class DownloadManager: ObservableObject {
    @Published var downloadTasks = [DownloadTask]()
}

So requested changes can be observed either via @ObservedObject wrapper in SwiftUI view or via manager.$downloadTasks publisher in any other place.

Asperi
  • 228,894
  • 20
  • 464
  • 690
0

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)
        }
    }
}
PGDev
  • 23,751
  • 6
  • 34
  • 88