CoreEngine

CI Version License

简洁轻巧

image Core 是一个用于构建更具响应式应用程序的框架,其灵感来源于 ReactorKitRedux

可扩展性

Core 是一个与 Reactive 无关的框架,这意味着你可以扩展任何你想导入的内容,例如 CombineRxSwift

它是一个非常轻量级且简单的架构,因此你可以使用 CocoaPods 或 SPM 来保持更新,或者直接拖放到你的项目中即可使用。或者你可以浏览代码并自行构建。

安装

CoreEngine 可以通过 CocoaPods 获取。要安装它,只需将以下行添加到你的 Podfile

CocoaPods

pod 'CoreEngine'

Swift Package Manager

Swift Package Manager 是一个用于管理 Swift 代码分发的工具。它与 Swift 构建系统集成,以自动化下载、编译和链接依赖项的过程。

要使用 Swift Package Manager 将 SnapKit 集成到你的 Xcode 项目中,请将其添加到你的 Package.swift 文件的 dependencies 值中

dependencies: [
    .package(url: "https://github.com/sobabear/CoreEngine.git", .upToNextMajor(from: "1.3.1"))
]

性能

Screenshot 2023-04-28 at 1 39 26 PM

与类似的框架相比,Core Engine 异常快速且轻量,你可以在这里查看详细信息:CoreEngineBenchMark

强烈推荐:使用 AsyncCore

虽然 CoreEngine 提供了传统的响应式方法和状态管理模式,但我们强烈推荐使用 AsyncCore 来进行现代、异步和更高效的状态处理。

AsyncCore 利用 Swift 的结构化并发和 async/await,提供了一种清晰直观的方式来管理状态更新、处理副作用,并使用 Swift 的 Actor 模型确保线程安全。

为什么使用 AsyncCore?

副作用 & 错误处理

不仅支持简单的核心,也支持复杂的核心。例如,副作用和错误处理。当涉及到这些时,你可以使用 AsyncCorePublisherCore

它与 Core 没有太大区别,因为 AnyCore 也符合。

func dispatch(effect: any Publisher) & func handleError(error: Error)

此方法在 AnyCore 中定义,当你处理由副作用生成的 publisher 时,将其发送到该函数中。你也可以在 handleError(error: Error) 函数中处理所有错误

这是 PublisherCore 的一个示例

class MainCore: PublisherCore {
 var subscription: Set<AnyCancellable> = .init()

 enum Action {
     case increase
     case decrease
     case jump(Int)
     case setNumber(Int)
 }

 struct State {
     var count = 0
 }

 @Published var state: State = .init()
 @Published var tenGap: Int = 10
 
 private let sessionService = SessionService()
 
 init {
     dispatch(effect: sessionService.randomUInt$().map(Action.setNumber))
 }
 
 func reduce(state: State, action: Action) -> State {
     var newState = state
     
     switch action {
     case .increase:
         newState.count += 1
     case .decrease:
         newState.count -= 1
     case let .jump(value):
         newState.count += value
     case let .setNumber(value):
         newState.count = value
     }
     return newState
 }
 
 func handleError(error: Error) {
     if let errpr = error as? MyError {
         //handle
     }
 }
 
 func tenJumpAction() {
     self.dispatch(effect: $tenGap.map(Action.jump))
 } 
}


class SessionService {
 func randomUInt$() -> AnyPublisher<Int, Error> {
 // blahblah
 }
}

示例 + RxSwift

复制这些代码用于 RxSwift

import Foundation
import CoreEngine
import RxSwift

protocol RxCore: Core {
    var disposeBag: DisposeBag { get set }
    
    func mutate(effect: Observable<Action>)
    func handleError(error: Error)
}

extension RxCore {
    public func mutate(effect: Observable<Action>) {
        effect
            .subscribe(onNext: { [weak self] in
                if let self {
                    self.state = self.reduce(state: self.state, action: $0)
                }
                
            }, onError: { [weak self] in
                self?.handleError(error: $0)
            })
            .disposed(by: disposeBag)
    }
    
    public func handleError(error: Error) { }
}


@propertyWrapper
class ObservableProperty<Element>: ObservableType {
  var wrappedValue: Element {
    didSet {
      subject.onNext(wrappedValue)
    }
  }
  
  private let subject: BehaviorSubject<Element>
  
  init(wrappedValue: Element) {
    self.wrappedValue = wrappedValue
    self.subject = BehaviorSubject<Element>(value: wrappedValue)
  }
  
  var projectedValue: Observable<Element> {
    return subject.asObservable()
  }
  
  func subscribe<Observer>(_ observer: Observer) -> Disposable where Observer : ObserverType, Element == Observer.Element {
    return subject.subscribe(observer)
  }
}

作者

stareta1202, stareta1202@gmail.com

许可证

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