Getting started with RxSwift and RxCocoa
Getting started with RxSwift and RxCocoaIt’s great when code does exactly what you tell it to (unlike my cat). Change something inthe program, tell the code to update, and it does. Good code!Most programming in the Object-Oriented era has been imperative like that: Your codetells your program wdisposed of when their parent object is deallocatedWhen deinito is called on the object which has a Dispose Bag as a property, the bag isemptied"and each disposable Observer is automatically unsubscribed from what it wasobserving. This allows aRC to take back memory as it normally wouldWithout a Dispose Bag, you' d get one of two results: either the Observer would create aretain cycle, hanging on to what it,'s observing indefinitely, or it could get deallocated outfrom under your object, causing a crashSo to be a good aRC citizen remember to add any observable objects to the dispose Bagwhen you set them up. That way, they'll be cleaned up nicely for youGetting StartedLet's get to the chocolate! The starter app for this tutorial, Chocotastic, is available hereDownload the zip file andand open the project in XcodeNote: The project utilizes Cocoa Pods, so you'll need to openthe chocotastic xcworkspace file in XcodeBuild and run the application Eventually you'll see the following screen, which lists severalkinds of chocolate you can buy from Europe, along with respective pricesCarrier令7:20PMChocolate!!!0$800Belgium令照700Great Britain$800The Netherlands令口$700Germany$1000SwitzerlandTapping on a chocolate row will add that product to your cartCarrier令7:21PMChocolate!!!1$800Belgium令照700Great Britain$800The Netherlands令口$700Germany$1000SwitzerlandTap on the cart in the upper right-hand corner to be taken to a page where you can eithercheck out or reset the cartCarrier令7:22PMChocolate!! Cart〓◆:1s8.00CheckoutResetIf you choose Checkout, a credit card entry form will be presentedCarrier令7:23PMCartE InfoCard numberExDCVVBuy Chocolate!Later in the tutorial, you'll come back to set this up using purely reactive programming. Tapthe Cart button to return to the cart summary, then tap the Reset button to return to themain screen with an empty cartThe Starting Point: Non-reactiveNow that you've seen what the application does, it's time to examine how it worksOpen ChocolatesOfTheWorld View Controller. swift, where you'll see some prettystandard UITable View Delegate and UITable View Data SourceextensionsThere's also a method, update Cart Button(, which updates the cart button with the currentnumber of chocolates in the cart. This is called from two different placesin view WillAppear(: ) whenever the view controller is about to be shown, andin table view( :did SelectRowAt: ) after a new chocolate has been added to the cartThese are both imperative ways of changing the count: you must explicitly call the methodto update the countRight now you have to keep track of where you're changing the value, but you're going torewrite the code to use a reactive technique. That way the button will update on its own nomatter how or where the count is changedRxSwift: Making the Cart Count ReactiveAll of the methods referring to items in the cart use a Shopping Cart. shared Cart singletonOpen up shopping Cart. swift and you'll see a pretty standard setup of a variable on thesingleton instancevar chocolates=[ChocolateroRight now, changes to the contents of chocolates can 't really be observed. You could adda didSet closure to its definition, but that would only get called when the entire array, ratherthan any of its elements, was updatedFortunately, RXSwift has a solution. Replace the line creating the chocolates variable withthis.let chocolates: Variable<[chocolate)= variable(nNote: This change will cause a bunch of errors to show up in the sidebar, but you'll fixthose in a momentThis syntax can be a little hard to wrap your head around, so it helps to understand what'sgoing on under the hoodRather than setting chocolates to a Swift array of Chocolates objects, you've now defined itas a Rx Swift Variable that has a type of a Swift array of chocolate objectsVariable is a class, so it uses reference semantics -meaning that chocolates refers to aninstance of variableVariable has a property called value. This is where your array of Chocolate objects is storedThe magic of Variable comes from a method called asObservableO. Instead of manuallychecking value every time, you can add an observer to keep an eye on the value for youWhen the value changes, the observer lets you know so you can react to any updatesThe downside of this setup is that if you need to access or change something in that arrayof Chocolates, you must do it via the value property rather than directly; that 's why thecompiler is throwing a tantrum and a fistful of errors. time to fix them up!In Shopping Cart. swift, look for the method totalCost( and change this linereturn chocolates. reduce(0)(return chocolates. value. reduce(0)tIn itemCountStringO, changeguard chocolates. count >0 else tguard chocolates. value count>0 else tand changelet setof Chocolates Set(chocolateslet setofChocolates= Set(chocolates. valueFinally, changelet count: Int= chocolates. reduce(o)tlet count: Int chocolates value. reduce(o)iIn CartView Controller swift, find reset( and changeShopping Cart. shared Cart chocolates =lShopping Cart. shared Cart chocolates. value =0Back in ChocolatesOfTheWorldview Controller, swift, change the implementationof update CartButtono to thiscartButton. title =Shopping Cart. shared Cart chocolates.value count)\u(1f36b)and in table View(: didSelectRow At: ) change this lineShopping Cart. shared Cart chocolates. append(chocolate)to the followingShopping Cart. shared Cart chocolates. value append(chocolate)Whew! After all that, Xcode will be happy and there should be no errors now you can takeadvantage of the fact that chocolates can now be observed!Go to ChocolatesofTheWorld view Controller. swift and add the following to the list ofpropertieslet dispose Bag= DisposeBagoThis creates a Dispose Bag you'l use to ensure that the observers you set up will becleaned up when deinit( is calledAdd the following under the //MARK: Rx Setupcomment/MARK: RX Setupprivate func setupCartobserverotShopping Cart. sharedCart. chocolates. asobservableOsubscribe(on Next: /12chocolates inself. cart Button. title =(chocolates. count)\u 1f36b)add Disposable To(dispose Bag)/3This sets up a reactive observer to update the cart automatically. As you can see, RXSwiftmakes heavy use of chained functions, meaning that each function takes the result of theprevious functionHow that's happening in this case1. First, you grab the shopping cart's chocolates variable as an Observable2. You call subscribe(on Next: )on that Observable in order to find out about changes tothe Observable's value subscribe(onNext: ) accepts a closure that will be executedevery time the value changes. The incoming parameter to the closure is the new valueof your Observable, and you'll keep getting these notifications until you eitherunsubscribe or your subscription is disposed. What you get back from this method isan Observer conforming to Disposable3. You add the observer from the previous step to your dispose Bag to ensure that yoursubscription is disposed of when the subscribing object is deallocatedTo finish up, delete the imperative update CartButtono method. This will cause errors toappear where it was being called in view WillAppear( )and table View(: didSelectRow AtTo fix them, delete the entire view WillAppear(: )method(since calling update CartButtonO isthe only thing it's doing beyond calling super), then delete the call
暂无评论