ios - MVVM and RxSwift for Search Screen -
in purpose of education mvvm , rxswift want build simple search screen, have table view , search bar. when user types search bar show have in table. sounds pretty simple, can't find tutorial suits me.
i have written code in view controller, can't understand have observe search text changes , call database method, filter items search text.
some code, have.
my 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) placecell cell.configurewithobject(place) return cell } .adddisposableto(disposebag) tableview.rx_contentoffset .subscribe { _ in if self.searchbar.isfirstresponder() { _ = self.searchbar.resignfirstresponder() } } .adddisposableto(disposebag) } }
and 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 init() { placesobservable = searchtextobservable.asobservable() //wait 0.3 s after last value fire new value .debounce(0.3, scheduler: mainscheduler.instance) //only fire if value different last 1 .distinctuntilchanged() //convert observable<string> observable<[place]> .flatmaplatest { searchstring -> observable<[place]> in // code here can't write. } //make sure subscribers use same exact subscription .sharereplay(1) } }
also, have method [database searchplaces:searchtext]
returns array of places - [place]
. can't understand , how place in flatmaplatest
of viewmodel.
i create reactive wrapper database creating observable<[place]>.
this code
placesobservable = searchtextobservable.asobservable() //wait 0.3 s after last value fire new value .debounce(0.0, scheduler: mainscheduler.instance) //only fire if value different last 1 .distinctuntilchanged() //convert observable<string> observable<weather> .flatmaplatest { searchstring -> observable<[anyobject]> in return tpreactivedatabase.sharedinstance.searchplacesbytitle(searchstring) } //make sure subscribers use same exact subscription .sharereplay(1)
and wrapper method 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 { } } } }
Comments
Post a Comment