[英]MVVM and RxSwift for Search Screen
In purpose of education MVVM and RxSwift I want to build simple search screen, which will have a table view and a search bar. 为了教育MVVM和RxSwift我想构建简单的搜索屏幕,它将有一个表格视图和一个搜索栏。 When user types something into the search bar I will show what he have in this table.
当用户在搜索栏中输入内容时,我将在此表中显示他所拥有的内容。 Sounds pretty simple, but I can't find any tutorial which suits me.
听起来很简单,但我找不到任何适合我的教程。
I have already written all code in view controller, I just can't understand have to observe search text changes and then call database method, which will filter items by search text. 我已经在视图控制器中编写了所有代码,我只是无法理解必须观察搜索文本的变化然后调用数据库方法,这将通过搜索文本过滤项目。
Some code, which I already have. 一些代码,我已经有了。
My ViewController 我的ViewController
import Foundation
import UIKit
import RxSwift
import RxCocoa
class PlaceSearchViewController: UIViewController {
//MARK: -
@IBOutlet weak var searchBar: UISearchBar!
@IBOutlet weak var tableView: UITableView!
//MARK: - Dependencies
private var viewModel: PlaceSearchViewModel!
private let disposeBag = DisposeBag()
//MARK: - Lifecycle
override func viewDidLoad() {
super.viewDidLoad()
viewModel = PlaceSearchViewModel()
addBindsToViewModel(viewModel)
}
//MARK: - Rx
private func addBindsToViewModel(viewModel: PlaceSearchViewModel) {
searchBar.rx_text.bindTo(viewModel.searchTextObservable)
viewModel.placesObservable.bindTo(tableView.rx_itemsWithCellFactory) {
(tableView: UITableView, index, place: Place) in
let indexPath = NSIndexPath(forItem: index, inSection: 0)
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as PlaceCell
cell.configureWithObject(place)
return cell
}
.addDisposableTo(disposeBag)
tableView.rx_contentOffset
.subscribe { _ in
if self.searchBar.isFirstResponder() {
_ = self.searchBar.resignFirstResponder()
}
}
.addDisposableTo(disposeBag)
}
}
And my view model: 我的观点模型:
import Foundation
import RxSwift
import RxCocoa
class PlaceSearchViewModel {
//MARK: - Dependecies
private let disposeBag = DisposeBag()
//MARK: - Model
private let placesObservable: Observable<[Place]>
var searchTextObservable = Variable<String>("")
//MARK: - Set up
init() {
placesObservable = searchTextObservable.asObservable()
//wait 0.3 s after the last value to fire a new value
.debounce(0.3, scheduler: MainScheduler.instance)
//only fire if the value is different than the last one
.distinctUntilChanged()
//convert Observable<String> to Observable<[Place]>
.flatMapLatest { searchString -> Observable<[Place]> in
// some code here which I can't write.
}
//make sure all subscribers use the same exact subscription
.shareReplay(1)
}
}
Also, I have method [DataBase searchPlaces:searchText]
which returns array of places - [Place]
. 另外,我有方法
[DataBase searchPlaces:searchText]
返回地方数组 - [Place]
。 I can't understand where and how place it in flatMapLatest
of my ViewModel. 我无法理解在我的ViewModel的
flatMapLatest
中放置它的位置和方式。
I create reactive wrapper for my DataBase by creating Observable<[Place]>. 我通过创建Observable <[Place]>为我的DataBase创建反应式包装器。
This is my code 这是我的代码
placesObservable = searchTextObservable.asObservable()
//wait 0.3 s after the last value to fire a new value
.debounce(0.0, scheduler: MainScheduler.instance)
//only fire if the value is different than the last one
.distinctUntilChanged()
//convert Observable<String> to Observable<Weather>
.flatMapLatest { searchString -> Observable<[AnyObject]> in
return TPReactiveDatabase.sharedInstance.searchPlacesByTitle(searchString)
}
//make sure all subscribers use the same exact subscription
.shareReplay(1)
And wrapper method searchPlacesByTitle
和包装器方法
searchPlacesByTitle
class TPReactiveDatabase: NSObject {
static let sharedInstance = TPReactiveDatabase()
// MARK: - Reactive Place database
func searchPlacesByTitle(title: String) -> Observable<[AnyObject]> {
return Observable.create { observer in
var places = [AnyObject]()
if (title.characters.count > 0) {
places = DBAccessKit.searchPlacesByTitle(title)
}
observer.on(.Next(places))
observer.on(.Completed)
return AnonymousDisposable {
}
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.