CombineReactor 0.3.0

CombineReactor 0.3.0

Muhammet Ilendemli 维护。



  • 作者
  • Muhammet Ilendemli

CombineReactor

Version License Platform

CombineReactor 是一个受 Reactorkit 启发的 Swift Combine 包装器,包含一个 "Binder",通过实现 ReactiveCompatible 和扩展 Reactive 来添加可绑定功能。以下是一个示例。

欢迎和感谢贡献和建议。

示例用法

Reactor

import Foundation
import Combine

import CombineReactor

class CounterReactor: Reactor {
    enum Action {
        case decrease
        case increase
    }

    enum Mutation {
        case decreaseValue
        case increaseValue
        case setIsLoading(Bool)
    }

    struct State {
        var value: Int = 0
        var isLoading: Bool = false
    }

    let initialState = State()

    func mutate(action: Action) -> AnyPublisher<Mutation, Never> {
        switch action {
        case .decrease:
            let step: AnyPublisher<Mutation, Never> = Empty()
                .append(.decreaseValue)
                .delay(for: .seconds(1), scheduler: RunLoop.current)
                .eraseToAnyPublisher()
            
            return Empty()
                .append(.setIsLoading(true))
                .append(step)
                .append(.setIsLoading(false))
                .eraseToAnyPublisher()
            
        case .increase:
            let step: AnyPublisher<Mutation, Never> = Empty()
                .append(.increaseValue)
                .delay(for: .seconds(1), scheduler: RunLoop.current)
                .eraseToAnyPublisher()
        
            return Empty()
                .append(.setIsLoading(true))
                .append(step)
                .append(.setIsLoading(false))
                .eraseToAnyPublisher()
        }
    }

    func reduce(state: State, mutation: Mutation) -> State {
        var newState = state
        
        switch mutation {
        case .decreaseValue:
            newState.value -= 1
            
        case .increaseValue:
            newState.value += 1
            
        case .setIsLoading(let isLoading):
            newState.isLoading = isLoading
        }
        
        return newState
    }
}

ReactiveCompatible & Reactive

extension UILabel: ReactiveCompatible {}

extension Reactive where Base: UILabel {
   var text: Binder<String?> {
        Binder(base) { (label, text) in
            label.text = text
        }
    }
}

extension UIActivityIndicatorView: ReactiveCompatible {}

extension Reactive where Base: UIActivityIndicatorView {
   var isAnimating: Binder<Bool> {
        Binder(base) { (activityIndicator, isAnimating) in
            isAnimating ? activityIndicator.startAnimating() : activityIndicator.stopAnimating()
        }
    }
}

ViewController & View

extension ViewController: View {
    func bind(reactor: CounterReactor) {
        buttonActionPassthrough
            .eraseToAnyPublisher()
            .sink(receiveValue: reactor.action.send)
            .store(in: &cancellables)
            
        reactor.state
            .map { $0.value }
            .map { String(format: "%i", $0) }
            .bind(to: valueLabel.r.text )
            .store(in: &cancellables)

        reactor.state
            .map { $0.isLoading }
            .removeDuplicates()
            .bind(to: activityIndicator.r.isAnimating)
            .store(in: &cancellables)
    }
}

安装

Cocoapods

pod 'CombineReactor', git: 'https://github.com/ilendemli/CombineReactor.git'

SPM

.package(url: "https://github.com/ilendemli/CombineReactor.git", .upToNextMajor(from: "0.1"))

其他管理者

请随意创建一个 pull request

要求

  • Swift 5.1
  • iOS 13
  • watchOS 6
  • tvOS 13
  • macOS 10.15

许可证

CombineReactor 在 MIT 许可证下可用。有关更多信息,请参阅 LICENSE 文件。