天天看点

Why used the RxSwift

Why(referring to :https://github.com/ReactiveX/RxSwift/blob/master/Documentation/Why.md)

Rx enables building apps in a decalrative way.

Bindings

Observable.combinelatest(firstName.rx.text, lastName.rx.text){ 0+“”+ 1}

.map{ “Greetings, (0)”}  

            .bind(to: greetingLabel.rx.text)  

This Also works with UITableViews and UICollectionViews.  

viewModel  

      .rows  

      .bind(to: resultsTableView.rx.items(cellIdentifier: “cell”, cellType:WikipediaSearchCell.self)){ (_, viewModel, cell) in  

               cell.title = viewModel.title  

               cell.url = viewModel.url  

}  

.disposed(by: disposeBag)  

Official suggestion is to always use .disposed(by: disposeBag) even though that’s not necessary for simple bindings.  

Retries  

It would be great if APIs wouldn’t fail,but unfortunately they do. Let’s say there is an API method:  

func doSomethingIncredible(forWho: String) throws -> IncredibleThing  

Ideally,you would want to capture the essence of retrying, and to be able to apply it to any operation.  

This is how you can do simple retries with Rx  

doSomethingIncredible(“me”)  

            .retry(3)  

You can also easily creat custom retry operators.  

Delegate  

Instead of doing the tedious and non-expressive:  

public func scrollViewDidScroll(scrollView: UIScrollView) { [weak self]// what scroll view is this bound to?  

           self?.leftPositionConstraint.constant = scrollView.contentOffset.x  

}  

…write  

self.resultsTableView  

       .rx.contentOffset  

       .map {0.x }

.bind(to: self.leftPositionConstraint.rx.constant)

and

- (void) observeValueForKeyPath:(NSString )keyPath ofObject:(id)object change:(NSDictionary )change context:(void *)context

use rx.observe and rx.observeWeakly

this is how they can be used:

view.rx.observe(CGRect.self,”frame”)

.subscribe(onNext: { frame in

print(“Got new frame (frame)”)

})

.disposed(by: disposeBag)

or

someSusipiciousViewController

.rx.observeWeakly(Bool.self, “behavingOK”)

.subscribe(onNext: { behavingOk in

print(“Cats can purr? (behavingOk)”)

})

.disposed(by: disposeBag)

Insteading of using

@available(iOS 4.0, *)

public func addObserverForName(name: String?, object obj: AnyObject?, queue: NSOperationQueue?, usingBlock block: (NSNotification) -> Void) -> NSObjectProtocol

…just write

NotificationCenter.defaul

.rx.notification(NSNotification.name.UITextViewTextDidBeginEditing, object: myTextView)

.map{ }

searchTextField.rx.text

.throttle(0.3, scheduler: MainScheduler.instance)

.distincUntilChanged()

.flatMapLatest { query in

API.getSearchResults(query)

.retry(3)

.startWith([])//clears results on new search term

.catchErrorJustReturn([])

}

.subscribe(onNext: { results in

//bind to ui

})

.disposed(by: disposeBag)

//this is a conceptual solution

let imageSubsription = imageURLs

.throttle(0.2, scheduler: MainScheduler.instance)

.flatMapLatest { imageURL in

API.fetchImage(imageURL)

}

.obseveOn(operationScheduler)

.map { imageData in

return decodeAndBlurImage(imageData)

}

.observeOn(MainScheduler.instance)

.subscribe(onNext: { blurredImage in

imageView.image = blurredImage

})

.disposed(by: reuseDisposeBag)

let userRequest: Observable = API.getUser(“me”)

let friendsRequest: Observable<[Friend]> = API.getFriends(“me”)

Observable.zip(userRequest, friendsRequest) { users, friends in

return(user, friends)

}

.subscribe(onNext: { user, friends in

// bind them to the user interface

})

.disposed(by: disposeBag)

let userRequest: Observable = API.getUser(“me”)

let friendsRequest: Observable<[Friend]> = API.getFriends(“me”)

Observable.zip(userRequest, friendsRequest) { user, friends in

return (user, friends)

}

.observeOn(MainScheduler.instance)

.subscribe(onNext: {user, friends in

//bind them to the user interface

})

.disposed(by: disposeBag)

extension Reative where Base: URLSession {

public func response(request: URLRequest)) -> Observable<(Data, HTTPURLResponse)> {

return Observable.create { observer in

let task = self.base.dataTask(wih: request)) {(data, reponse,error) in

guard let reponse = reponse, let data = data else {

observer.on(.error(error ?? RxCocoaURLError.unknown))

return

}

guard let httpResponse = response as? HTTPURLResponse else {

observer.on(.error(RxCocoaURLError.nonHttpResponse(reponse: response)))

return

}

observer.on(.next(data, httpResponse))

observer.on(.completed)

}

task.resume()

return Disposables.create(with: task.cancel)

}

}

}