AlertReactor 0.3.0

AlertReactor 0.3.0

TestsTested βœ—
LangLanguage SwiftSwift
License MIT
ReleasedLast Release Aug 2017
SwiftSwift Version 3.0
SPMSupports SPM βœ“

Maintained by Suyeol Jeon.


Downloads

Total1,789
Week210
Month798

Installs

Apps4
Apps WeekApps This Week 1
Test Targets2
Test WeekTests This week 1
powered by Segment

GitHub

Stars6
Watchers1
Forks0
Issues0
Contributors1
Pull Requests1

Code

Files3
LOCLines of Code 170


 
Depends on:
ReactorKit>= 0
RxSwift>= 3.0.0
RxCocoa>= 3.0.0
 

  • By
  • Suyeol Jeon

AlertReactor

AlertReactor is a ReactorKit extension for UIAlertController. It provides an elegant way to deal with an UIAlertController. Best fits if you have lazy-loaded alert actions.

alertreactor

Features

  • ✏️ Statically typed alert actions
  • πŸ•Ή Reactive and dynamic action bindings

At a Glance

This is an example implementation of an AlertReactor:

final class UserAlertReactor: AlertReactor<UserAlertAction> {
  override func mutate(action: Action) -> Observable<Mutation> {
    switch action {
    case .prepare:
      return .just(.setActions([.copy, .follow, .block, .cancel]))

    case let .selectAction(alertAction):
      switch alertAction {
      case .copy: return foo()
      case .follow: return foo()
      case .unfollow: return foo()
      case .block: return foo()
      case .cancel: return foo()
      }
    }
  }
}

Getting Started

1. Defining an Alert Action

First you should define a new type which conforms to a protocol AlertActionType. This is an abstraction model of UIAlertAction. This protocol requires a title(required), style(optional) and isEnabled(optional) property.

enum UserAlertAction: AlertActionType {
  case loading
  case follow
  case block
  case cancel

  // required
  var title: String {
    switch self {
    case .loading: return "Loading"
    case .follow: return "Follow"
    case .block: return "Block"
    case .cancel: return "Cancel"
    }
  }

  // optional
  var style: UIAlertActionStyle {
    switch self {
    case .loading: return .default
    case .follow: return .default
    case .block: return .destructive
    case .cancel: return .cancel
    }
  }

  // optional
  var isEnabled: Bool {
    switch self {
    case .loading: return false
    default: return true
    }
  }
}

2. Creating an Alert Reactor

AlertReactor is a generic reactor class. It takes a single generic type which conforms to a protocol AlertActionType. This reactor provides a default action, mutation and a state. Here is a simplified definition of AlertReactor. You may subclass this class and override mutate(action:) method to implement specific business logic.

class AlertReactor<AlertAction: AlertActionType>: Reactor {
  enum Action {
    case prepare // on viewDidLoad()
    case selectAction(AlertAction) // on select action
  }

  enum Mutation {
    case setTitle(String?)
    case setMessage(String?)
    case setActions([AlertAction])
  }

  struct State {
    public var title: String?
    public var message: String?
    public var actions: [AlertAction]
  }
}

We’re gonna use the UserAlertAction as a generic parameter to create a new subclass of AlertReactor.

final class UserAlertReactor: AlertReactor<UserAlertAction> {
  override func mutate(action: Action) -> Observable<Mutation> {
    switch action {
    case .prepare:
      return .just(Mutation.setActions([.copy, .follow, .block, .cancel]))

    case let .selectAction(alertAction):
      switch alertAction {
      case .loading: return .empty()
      case .follow: return UserAPI.follow()
      case .block: return UserAPI.block()
      case .cancel: return .empty()
      }
    }
  }
}

3. Presenting an Alert Controller

AlertController is a subclass of UIAlertController which conforms to a protocol View from ReactorKit. This class also takes a single generic type of AlertActionType. You can initialize this class with some optional parameters: reactor and preferredStyle. Just present it then the reactor will handle the business logic for you.

let reactor = UserAlertReactor()
let controller = AlertController<UserAlertAction>(reactor: reactor, preferredStyle: .actionSheet)
self.present(controller, animated: true, completion: nil)

Installation

pod 'AlertReactor'

License

AlertReactor is under MIT license. See the LICENSE for more info.