2016-08-24 8 views
4

教育の目的MVVMとRxSwift私はテーブルビューと検索バーを持つ簡単な検索画面を構築したいと思います。ユーザーが検索バーに何かを入力すると、彼はこのテーブルに何を持っているかを表示します。かなり簡単ですが、私に合ったチュートリアルは見つかりません。検索画面のMVVMとRxSwift

私はすでにビューコントローラにすべてのコードを書いていますが、検索テキストの変更を観察してから、検索テキストで項目をフィルタリングするデータベースメソッドを呼び出す必要があります。

私がすでに持っているコードです。

私の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) 
    } 
} 

そして、私のビューモデル: - [Place]また

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) 
    } 

} 

、私は場所の配列を返すメソッド[DataBase searchPlaces:searchText]を持っています。私はViewModelのflatMapLatestにどこにどのように配置するのか理解できません。

+0

あなたはRxSwiftレポで[RxExample](https://github.com/ReactiveX/RxSwift)プロジェクトをチェックしましたか? – KhanXc

+0

@KhanXcはい。私は彼らのRxDelegatesを今のところ使いたくない。新しいフレームワークが多すぎます。だからこそ私は彼らがいなくても解決策を見つけたいのです。 –

+0

デリゲートの一部が組み込まれています(RxDatasourceを使用している場合を除く)。 RxExampleのウィキペディア画像検索コードはあなたの目的に合っています。オブザーバーの代わりにドライバーを使用しています。 – KhanXc

答えて

1

私はObservable < [Place]>を作成して、自分のDataBase用のリアクティブラッパーを作成します。

は、これは私のコード

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) 

とラッパー方法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 { 

      } 
     } 
    } 
} 
関連する問題