2016.10.23 追記:Swift 3.0 対応版を作成しました
RxSwift のメリットを理解するには実際に使ってみるのが一番!ということで、とりあえず foursquare のベニューを取得するサンプルを作ってみました。
※RxSwift は絶賛勉強中なので間違ったことを書いている可能性が高いです。ツッコミ歓迎です!
動作環境
- Swift 2.2
- RxCocoa (2.4)
- RxSwift (2.4)
- SwiftyJSON (2.3.2)
- Xcode 7
APIクライアント
APIにアクセスする部分を作ります。戻り値を Observable<[Venue]>
にしているのがポイントです。
func send() -> Observable<[Venue]> { return Observable.create{ (observer) in let client = FoursquareAPIClient(accessToken: "YOUR_TOKEN") let parameter: [String: String] = [ "ll": "40.7,-74", ]; client.requestWithPath("venues/search", parameter: parameter) { [weak self] (data, error) in let json = JSON(data: data!) let venues = (self?.parseVenues(json["response"]["venues"])) ?? [Venue]() observer.on(.Next(venues)) observer.on(.Completed) } return AnonymousDisposable {} } } func parseVenues(venuesJSON: JSON) -> [Venue] { var venues = [Venue]() for (key: _, venueJSON: JSON) in venuesJSON { venues.append(Venue(json: JSON)) } return venues }
通信ライブラリは拙作 FoursquareAPIClient を使用しました。
ViewModel
ViewModel から先ほどの send
を呼び出す部分です。
public func fetch() { self.send() .subscribe { [weak self] (event) -> Void in switch event { case .Next(let value): self?.venues.value = value case .Error(_): () case .Completed: () } } .addDisposableTo(disposeBag) }
戻り値が Observable<[Venue]>
なので、これを subscribe して、返ってくる値(ベニューリストなど)を処理しています。
ViewController
ViewController は30行程と、かなりスッキリしました。rx_itemsWithDataSource
でベニューリストとTableViewをBindしているのがポイントです。ViewModel のベニューリストに変化があるとTableViewがリロードされます。
import UIKit import RxSwift import RxCocoa class ViewController: UIViewController { @IBOutlet weak var tableView: UITableView! var viewModel = ViewModel() var dataSource = DataSource() var delegate = Delegate() let disposeBag = DisposeBag() override func viewDidLoad() { super.viewDidLoad() self.tableView.delegate = self.delegate self.viewModel.fetch() self.viewModel.venues .asDriver() .drive ( self.tableView.rx_itemsWithDataSource(self.dataSource) ) .addDisposableTo(self.disposeBag) } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() // Dispose of any resources that can be recreated. } }
完全なソースコードはこちらです。
GitHub - koogawa/RxSwiftSample: RxSwiftSample