Advertisement
Guest User

Untitled

a guest
Jul 19th, 2019
90
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Swift 4.70 KB | None | 0 0
  1. public protocol CellRepresentable {
  2.     static var reuseIdentifier: String { get }
  3. }
  4.  
  5. public extension CellRepresentable {
  6.     static var reuseIdentifier: String {
  7.         return String(describing: Self.self)
  8.     }
  9. }
  10.  
  11. public typealias ViewModelConfigurable = Configurable & AnyConfigurable
  12.  
  13. public protocol Configurable {
  14.     associatedtype ViewModel
  15.     func configure(with model: ViewModel)
  16. }
  17.  
  18. public protocol AnyConfigurable {
  19.     func configure(with model: Any)
  20. }
  21.  
  22. public extension AnyConfigurable where Self: Configurable {
  23.     func configure(with model: Any) {
  24.         guard let viewModel = model as? ViewModel else { return }
  25.         configure(with: viewModel)
  26.     }
  27. }
  28.  
  29. // Создает дата сурс, способный извлекать события из ячеек таблицы (damn good, right?)
  30. /// Для этого возвращает промежуточное замыкание в котором имеем объект содержащий эмиттер (иными словами - rx-subject)
  31. /// Содержащий интересующие нас события из ячеек
  32. /// В этом замыкании необходимо обработать эмиттер как правило построить биндинг
  33. /// S - тип возвращаемого ивента
  34. func eventEmittableDataSource<T: SectionModelType, S>()
  35.     -> (_ emittersHandler: @escaping (S) -> Void)
  36.     -> RxTableViewSectionedReloadDataSource<T> {
  37.         return { emittersHandler in
  38.             let dataSource = RxTableViewSectionedReloadDataSource<T>(configureCell: { dataSource, tableView, indexPath, model -> UITableViewCell in
  39.                 guard let model = model as? CellRepresentable else { return UITableViewCell() }
  40.                 let cell = tableView.dequeueReusableCell(withIdentifier: type(of: model).reuseIdentifier, for: indexPath)
  41.                 if let configurableCell = cell as? AnyConfigurable {
  42.                     configurableCell.configure(with: model)
  43.                 }
  44.                 if let emitterCell = cell as? AnyEventsCollector {
  45.                     let events = EventsCollectableViewModel<S>(viewModel: emitterCell).collectEvents()
  46.                     emittersHandler(events)
  47.                 }
  48.                 return cell
  49.             })
  50.             return dataSource
  51.         }
  52. }
  53.  
  54. public func defaultDataSource<T: SectionModelType>() -> RxTableViewSectionedReloadDataSource<T> {
  55.     let dataSource = RxTableViewSectionedReloadDataSource<T>(configureCell: { dataSource, tableView, indexPath, model -> UITableViewCell in
  56.         guard let model = model as? CellRepresentable else { return UITableViewCell() }
  57.         let cell = tableView.dequeueReusableCell(withIdentifier: type(of: model).reuseIdentifier, for: indexPath)
  58.         if let configurableCell = cell as? AnyConfigurable {
  59.             configurableCell.configure(with: model)
  60.         }
  61.         return cell
  62.     })
  63.     return dataSource
  64. }
  65.  
  66. /// Это реализовываем во всем что может создавать события (etc. - ячейка)
  67. public typealias EventsEmitter = AnyEventsCollector & EventsCollector
  68.  
  69.  
  70. /// Внутренняя реализация
  71. /// Структура для избежания каста в дата сурсах
  72. /// или на любой принимающей стороне
  73. /// Необходимо быть осторожным с типами, если ивент не совпадет - крашится
  74. /// Тип ивента должен совпадать с тем что возвращает эмиттер
  75. struct EventsCollectableViewModel<E>: EventsCollector {
  76.     private let viewModel: AnyEventsCollector
  77.    
  78.     init(viewModel: AnyEventsCollector) {
  79.         self.viewModel = viewModel
  80.     }
  81.    
  82.     func collectEvents() -> E {
  83.         guard let event = collectEvents() as? Event else {
  84.             // Этого никогда не должно произойти если ты не конченый
  85.             fatalError("Event not casted")
  86.         }
  87.         return event
  88.     }
  89. }
  90.  
  91. /// Протокол для обхода ограничения на генерик параметры
  92. /// для передачи эмиттера в функции использовать его
  93. /// После чего обернуть в структуру выше и уже у нее дергать ивенты
  94. /// Или же использовать каст из Any но это менее красиво
  95. public protocol AnyEventsCollector {
  96.     func collectEvents() -> Any
  97. }
  98.  
  99. public extension AnyEventsCollector where Self: EventsCollector {
  100.     func collectEvents() -> Any {
  101.         return collectEvents() as Event
  102.     }
  103. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement