RxSwift những khái niệm cơ bản P.3
Bài đăng này đã không được cập nhật trong 8 năm
Chào các bạn, hôm nay tôi tiếp tục nói về những khái niệm cơ bản của thư viện RxSwift bao gồm :
- KVO
- UI layer tips
- Making HTTP requests
KVO
Có 2 cách để sử dụng KVO.
// KVO
extension Reactive where Base: NSObject {
public func observe<E>(type: E.Type, _ keyPath: String, options: NSKeyValueObservingOptions, retainSelf: Bool = true) -> Observable<E?> {}
}
#if !DISABLE_SWIZZLING
// KVO
extension Reactive where Base: NSObject {
public func observeWeakly<E>(type: E.Type, _ keyPath: String, options: NSKeyValueObservingOptions) -> Observable<E?> {}
}
#endif
Ví dụ cách quan sát frame của UIView. Chú ý : UIKit không hỗ trợ KVO.
view
.rx.observe(CGRect.self, "frame")
.subscribe(onNext: { frame in
...
})
hoặc
view
.rx.observeWeakly(CGRect.self, "frame")
.subscribe(onNext: { frame in
...
})
UI layer tips
Observables cần tuân theo UI layer khi làm việc với UIKit controls.
Threading
Observables cần gửi giá trị trên MainScheduler(UIThread). Trường hợp bạn muốn gửi gì đó lên UI trong background thread, RxCocoa sẽ gửi exception. Để giải quyết vấn đề này bạn cần thêm observeOn(MainScheduler.instance). NSURLSession extensions mặc định sẽ không trả kết quả trên MainScheduler.
Errors
Nếu không biết Observable có thể lỗi hay không, bạn có thể sử dụng catchErrorJustReturn(valueThatIsReturnedWhenErrorHappens), để đảm bảo nó không bị lỗi. Nếu muốn sequence tiếp tục sinh ra element có thể sử dụng retry operator.
Dùng chung subscription
Bạn thường muốn sử dụng chung subscription trong UI layer vì không cần thiết phải gọi nhiều HTTP request khác nhau để đưa cùng một dữ liệu lên nhiều UI element. Ví dụ:
let searchResults = searchText
.throttle(0.3, $.mainScheduler)
.distinctUntilChanged
.flatMapLatest { query in
API.getSearchResults(query)
.retry(3)
.startWith([]) //
.catchErrorJustReturn([])
}
.shareReplay(1)
Sử dụng shareReplay để chia sẻ kết quả tìm kiếm mỗi lần tính toán như vậy sẽ không cần thiết phải sử dụng nhiều kết nối HTTP để đưa kết quả searchResults lên nhiều UI elements.
Thực hiện HTTP requests
Đầu tiên, ta sẽ tạo NSURLRequest object tương ứng với công việc cần thực hiện. Request được xác đinh là GET hay POST, phần body, các query parameters . Cách tạo GET request
let request = NSURLRequest(URL: NSURL(string: "http://en.wikipedia.org/w/api.php?action=parse&page=Pizza&format=json")!)
Nếu muốn thực hiện request với các observable khác:
let responseJSON = NSURLSession.sharedSession().rx.JSON(request)
// ở đây sẽ request sẽ không được thực hiện
// `responseJSON` mô tả cách fetch dữ liệu trả về
let cancelRequest = responseJSON
// request được thực hiện
.subscribe(onNext: { json in
print(json)
})
NSThread.sleep(forTimeInterval: 3.0)
// Nếu muốn hủy request sau 3s
cancelRequest.dispose()
NSURLSession extensions mặc định sẽ không trả về kết quả trên MainScheduler.
Bạn cũng có thể sử dụng :
NSURLSession.shared.rx.response(myNSURLRequest)
.debug("my request")
.flatMap { (data: NSData!, response: NSURLResponse!) -> Observable<String> in
if let response = response as? NSHTTPURLResponse {
if 200 ..< 300 ~= response.statusCode {
return just(transform(data))
}
else {
return Observable.error(yourNSError)
}
}
else {
rxFatalError("response = nil")
return Observable.error(yourNSError)
}
}
.subscribe { event in
print(event)
}
trong lần sau tôi sẽ nói về ứng dụng của rxswift trong giải quyết một số bài toán trong lập trình iOS, hẹn gặp lại các bạn.
All rights reserved