Skip to content

Instantly share code, notes, and snippets.

@fjcaetano
Created September 27, 2016 21:57
Show Gist options
  • Save fjcaetano/be736b3c8ed61289240f921d38d119dd to your computer and use it in GitHub Desktop.
Save fjcaetano/be736b3c8ed61289240f921d38d119dd to your computer and use it in GitHub Desktop.
RxSwift error example
//
// ChallengeViewController.swift
// WinninApp
//
// Created by Flávio Caetano on 9/26/16.
// Copyright © 2016 Winnin. All rights reserved.
//
import UIKit
import RxSwift
import RxCocoa
import RxDataSources
class ChallengeViewController: UIViewController {
private struct Constants {
struct CellIdentifiers {
static let Indicator = "IndicatorCell"
static let Contestant = "ContestantCell"
}
}
var challenge: ChallengeViewModel!
var challengeId: Int64!
private let player = RxPlayer()
private let screen = ChallengeScreen()
private let disposeBag = DisposeBag()
private let itemsDataSource = RxTableViewSectionedAnimatedDataSource<ElementSection<ChallengeScreen.DataContent>>()
// MARK: Outlets
@IBOutlet private weak var titleLabel: UILabel!
@IBOutlet private weak var imageView: UIImageView!
@IBOutlet private weak var tableView: UITableView!
@IBOutlet private weak var downVoteButton: UIButton!
@IBOutlet private weak var upVoteButton: UIButton!
@IBOutlet private weak var errorLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
player.playbackLoops = true
player.addToViewController(self) { view in
self.view.insertSubview(view, atIndex: 0)
}
loadChallenge()
.driveNext { [weak self] challenge in
self?.titleLabel.text = challenge.title
self?.imageView.sd_setImageWithURL(challenge.contestants.first?.image)
if let videoURL = challenge.contestants.first?.video {
self?.player.setUrl(videoURL)
}
}
.addDisposableTo(disposeBag)
// Expand
tableView.rx_modelSelected(ChallengeScreen.DataContent.self)
.filter { [weak self] in $0 == .Indicator(.Count(self?.challenge.viewCount ?? 0)) }
.subscribeNext { [weak self] _ in _ = try? self?.screen.expandItems() }
.addDisposableTo(disposeBag)
// Contract
tableView.rx_modelSelected(ChallengeScreen.DataContent.self)
.filter { $0 == .Indicator(.Contract) }
.subscribeNext { [weak self] _ in _ = try? self?.screen.contractItems() }
.addDisposableTo(disposeBag)
screen.items
.bindTo(tableView.rx_itemsWithDataSource(itemsDataSource)) { tableView, indexPath, item in
switch item {
case .Contestant(let contestant):
let cell = tableView.dequeueReusableCellWithIdentifier(Constants.CellIdentifiers.Contestant, forIndexPath: indexPath) as! ContestantTableViewCell
cell.contestant = contestant
return cell
case .Indicator(let indicator):
let cell = tableView.dequeueReusableCellWithIdentifier(Constants.CellIdentifiers.Indicator, forIndexPath: indexPath) as! ChallengeIndicatorTableViewCell
cell.indicator = indicator
return cell
}
}
.addDisposableTo(disposeBag)
// Player
player.rx_ready
.bindTo(player.rx_playbackFromBeginning)
.addDisposableTo(disposeBag)
player.rx_playbackState
.map { $0 != .Failed }
.bindTo(errorLabel.rx_hidden)
.addDisposableTo(disposeBag)
}
}
// MARK: - Private Methods
extension ChallengeViewController {
private func loadChallenge() -> Driver<ChallengeViewModel> {
if let challenge = self.challenge {
return Driver.just(challenge)
}
return screen.loadChallenge(challengeId)
.doOnNext { [weak self] in self?.challenge = $0 }
.driveShowError(self)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment