What's the differences between `Combine` and `didSet` in Swift?

Advertisements

I recently worked on SwiftUI and starting writing code in a declarative way. But here comes a confusion. Like what is shown below, I want to (1)load the song data and (2)show the view by setting isInfoViewShown, after song is assigned to any value.

I assume didSet{} and Combine @Published .sink{} are doing things interchangeably. So I want to ask what are the differences between them? And in my own opinion, didSet{} can do most of jobs Combine do. So why should Apple announce Combine framework?

Any help is appreciated.

class InfoViewModel: ObservableObject {
    
    @Published var song: Song? {
        didSet {                      // Here's the didSet{}: [1] load song data
            if let song = song {
                load(song: song)
            }
        }
    }
    
    private var songSelectedSubscription: AnyCancellable?
    
    @Published var isInfoViewShown: Bool = false

    init() {                          // Here's the Combine @Published .sink{}: [2] show the view
        songSelectedSubscription = $song.sink{ self.isInfoViewShown = ($0 == nil ? false : true) }              
    }
}

>Solution :

Sure, there are lots of ways to observe changes to data, KVO, Notification Center, didSet, combine etc, so in one sense these things are indeed similar. Differences though are:

a property can only have one didSet, which makes it hard for any number of observers to register an interest in the property.

But the big win with Combine is: a Combine pipeline allows you to create streams easily where you can say for example, transform the stream of changes to a stream that: observes changes to the user’s input string, debounces it (rate limiting changes so we don’t spam the server), filter those changes for any value that is at least 3 characters long, and that produces a new stream which you can observe. Map/FlatMap is also a really important combine operator, transform a stream of a’s into a stream of b’s. Also merging two streams together with combineLatest and so on, so you can take a stream of a’s and stream of b’s and make a stream of (a, b)’s and then map that to a stream of validated c’s, for example.

Leave a ReplyCancel reply