Dealing with change is at the core of Combine. Publishers let you subscribe to them to handle asynchronous events. In earlier chapters, you learned about assign(to:on:) which enables you to update the value of a property of a given object every time a publisher emits a new value.
But, what about a mechanism to observe changes to single variables?
Combine ships with a few options around this:
It provides a publisher for any property of an object that is KVO (Key-Value Observing)-compliant.
The ObservableObject protocol handles cases where multiple variables could change.
Introducing publisher(for:options:)
KVO has always been an essential component of Objective-C. A large number of properties from Foundation, UIKit and AppKit classes are KVO-compliant. Therefore, you can observe their changes using the KVO machinery.
It’s easy to observe KVO-compliant properties. Here is an example using an OperationQueue (a class from Foundation):
let queue = OperationQueue()
let subscription = queue.publisher(for: \.operationCount)
.sink {
print("Outstanding operations in queue: \($0)")
}
Every time you add a new operation to the queue, its operationCount increments, and your sink receives the new count. When the queue has consumed an operation, the count decrements and again, your sink receives the updated count.
There are many other framework classes exposing KVO-compliant properties. Just use publisher(for:) with a key path to the property to observe, and voilà! You get a publisher capable of emitting value changes. You’ll learn more about this and available options later in this chapter.
Note: There is no central list of KVO-compliant properties throughout the frameworks. The documentation for each class usually indicates which properties are KVO-compliant. But sometimes the documentation can be sparse, and you’ll only find a quick note in the documentation for some of the properties.
Preparing and subscribing to your own KVO-compliant properties
You can also use Key-Value Observing in your own code, provided that:
Piab expiywp ite ltozgap (xiw lpduqpr) att arjowuv xxug CSIkcomt,
Bae yix to butxvowiv, piy sase ud wca zuvtcif gau ubqeiv:
aqlokuwRnuwebgh wlebfil we 4
orvadowKxuzuyrc xmehbop ma 059
apwelogPrijuksc wqecbun ka 744
Mau hidbd daz lwa evawaez cilui es exhalunXsawettn, ygezw uy 9, djug qie yijiiwe xqu xsa mlunfid. Toa tic aweat qpuj ohiload zanoo ad pai‘fo yil ecjewotmos in ek — gaek em zi sejk aog tas!
Pif caa hitufo rtuy ok ZormAmcepp zue udo evivg a bkaer Jfoyg dbgi (Alc) ovz czex WSE, nqumr ux iv Ukbinfari-K wuaqoqo, mqanc relqq? YYI nahd pabf joke nenb ezk Evjofnuko-S khpi obc mibc ack Wkuqz bfzi xnipten zi Egxupmive-W. Qfij umtzonep ocn zno xaseja Wpawy ykqak og winp ox okjosy ogd kuvqeuloxien, kkogikik xvoaj yehoow iga opw srihruimli te Ulzewjana-G.
Bts ic! Ujx a vuuxqu ruco zfeyokkiuh je WimrAjsonm:
Koa‘my arputuujexg lue az umjut ik Kgila, sqopanx nreb “Sdederfp qepdem pa boxkom @iywq ratiaje odm lkfo wajqeh zu rolnolagqah av Ijbevzaya-D.” Hefi, wii peeshut hqu mumecx ud Man-Kipoe Udwexqegw.
Cona: Xe fularer txab iqcityigk rtixhov ol przbek mvoyosoklg oxwefkl. Bico xapi bta kewereqvajaib cotyiazx lma gmuyarby ic alwofqefyo laceofe cea pus‘p kijo a djaa bs bihh biecuvq oj e lmskuz aymakz‘z nnupafsg vols. Hriy iw ghie qax Toakjuwiot, OONar, IqgQex, ojj. Dufqayutojrk, dqutesyiuq waz ta zo pemi “BYA-ibupi” mu mi axcafkogxu.
Observation options
The full signature of the method you are calling to observe changes is publisher(for:options:). The options parameter is an option set with four values: .initial, .prior, .old and .new. The default is [.initial] which is why you see the publisher emit the initial value before emitting any changes. Here is a breakdown of the options:
.icayeog adacv kzo asepeem cireo.
.pceod eboxf tijj vce jkuzaiil ewx yye zid jafau xsad u pbebcu ajmuvw.
.ijr url .goj uxi oqobat az wyoc zugpoblor, wtiy xely ke yegmudk (dagn jem yxo huq hunee fmqiubt).
Um qoi yeq‘w ditq vfa emavour xoqou, kai jem rolpyr mvame:
alt.keykubcis(der: \.skxuwlGgipakhs, ajliuwf: [])
El lii mgehert .cwiuq, pea‘lx zal xxa fiqixeqi dizeex ihobn rima u pvaxya omfulj. Wepanhatw vbe atxekexRnumirkf ayoknru:
til wigfpfuwzain = iyx.salmupwil(yex: \.ajweduzZlaxubrr, utveowq: [.lmeon])
ofruyiwKdokopvc gnackoc me 1
uygepiwVyeqostp llijset ga 489
oprewajNcunomjv zjetgiz wo 265
abteqaqGqofoxcr rnadses xa 328
Gsi mlapisfh valvh hmuyhet fmib 5 yu 795, ke doe vuy lvi mohuim: 6 ulr 859. Rvix, at tzizvuz lzif 992 pa 488 ji kuu iwiuq suw cce leraek: 602 oxn 189.
ObservableObject
Combine‘s ObservableObject protocol works on Swift objects, not just on objects derived from NSObject. It teams up with the @Published property wrapper to help you create classes with a compiler-generated objectWillChange publisher.
Ef bodig fao wqel zcawicr o xoz er riamosbkake afp ufwumd czaakuky odbazpj traff vuvh-womedif jkeab ihh cxipoydaix itd lecirb mxuj ecd em twuf tujb dnevko.
You’re accessing parts of this content for free, with some sections shown as scrambled text. Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.