美文网首页
Katana 介绍

Katana 介绍

作者: 阿奈 | 来源:发表于2021-01-14 09:39 被阅读0次

    Katana是一个现代的Swift框架,用于编写可测试且易于推理的iOS应用程序的业务逻辑。Katana受到Redux的强烈启发。

    Overview

    应用程序状态完全由一个可序列化的数据结构描述,更改状态的唯一方法是调度StateUpdater。AStateUpdater旨在改变状态,并包含所有要做的信息。因为所有更改都是集中的,并且是按严格顺序进行的,所以没有任何需要注意的微妙的竞争条件。

    struct CounterState:State {

     var counter:Int=0

     }

    应用程序的状态只能通过状态更新器修改。StateUpdater表示一个导致应用程序状态改变的事件。你通过实现updateState(:)方法来定义状态更新器的行为,该方法基于当前应用程序状态和StateUpdater本身来改变状态。updateState应该是一个纯函数,这意味着它只依赖于输入(即状态和状态更新器本身),而且它没有副作用,比如网络交互。

     struct IncrementCounter: StateUpdater {

        func updateState(_ state: inout CounterState) {

         state.counter += 1

      }

    }

    Store 包含并管理你的整个应用状态。它负责管理被分派的项(例如,刚才提到的状态更新器)。

    let store=Store<CounterState,AppDependencies()

    store.dispatch(IncrementCounter())

    你可以要求store在应用状态的每一个变化时都得到通知。

    store.addListener() {

     //the app state has changed

    }

    Side Effects

    使用纯函数更新应用程序的状态很好,而且有很多好处。如果应用程序必须处理外部世界(例如,API调用,磁盘文件管理)。对于所有这类操作,Katana提供了Side Effects 的概念。可以使用Side Effects 与应用程序的其他部分交互,然后分发新的状态更新器来更新状态。对于更复杂的情况,您还可以分派其他Side Effects。

    struct GenerateRandomNumberFromBackend: SideEffect {

      func sideEffect(_ context: SideEffectContext<CounterState, AppDependencies>) throws {

        // invokes the `getRandomNumber` method that returns a promise that is fullfilled

        // when the number is received. At that point we dispatch a State Updater

        // that updates the state

        context.dependencies.APIManager

            .getRandomNumber()

            .then({ randomNumber in context.dispatch(SetCounter(newValue: randomNumber)) })

      }

    }

    struct SetCounter: StateUpdater {

      let newValue: Int

      func updateState(_ state: inout CounterState) {

        state.counter = self.newValue

      }

    }

    此外,您可以利用await操作符来编写模仿Async / Await模式的逻辑,该逻辑允许您以同步方式编写异步代码。

    struct GenerateRandomNumberFromBackend: SideEffect {

      func sideEffect(_ context: SideEffectContext<CounterState, AppDependencies>) throws {

        // invokes the `getRandomNumber` method that returns a promise that is fullfilled

        // when the number is received.

        let promise = context.dependencies.APIManager.getRandomNumber()

        // we use await to wait for the promise to be fullfilled

        let randomNumber = try await(promise)

        // then the state is updated using the proper state updater

        try await(context.dispatch(SetCounter(newValue: randomNumber)))

      }

    }

    Dependencies(依赖关系)

    Side Effects示例利用了一个APIManager方法。Side Effects是可以通过使用上下文的dependencies参数来获取APIManager(context.dependencies.APIManager)。依赖容器是执行依赖注入的Katana。我们测试我们的副作用,因此我们需要摆脱单例或其他阻止我们编写测试的坏习惯。创建依赖项容器非常简单:只需创建一个符合SideEffectDependencyContainer协议的类,使存储对它具有通用性,并在Side Effects中使用它。

    final class AppDependencies: SideEffectDependencyContainer {

      required init(dispatch: @escaping PromisableStoreDispatch, getState: @escaping GetState) {

    // initialize your dependencies here

    }

    }

    Interceptors

    当定义一个存储时,你可以提供一个拦截器列表,当一个项目被分派时,这些拦截器会按照给定的顺序被触发。拦截器就像一个包罗万象的系统,可以用来实现日志记录或动态更改存储的行为等功能。每次要处理可分派项时都会调用拦截器。

    Katana自带一个内置的dispatchabllogger拦截器,它记录所有的dispatchables,除了黑名单参数中列出的那些。

    let dispatchableLogger = DispatchableLogger.interceptor(blackList: [NotToLog.self])

    let store = Store<CounterState>(interceptor: [dispatchableLogger])

    有时,监听系统中发生的事件并对它们作出反应是很有用的。Katana提供了可以用来实现这个结果的Observer Interceptor。

    特别是,您会在以下情况下指示拦截器调度项目:

    Store已初始化

    状态以特定方式变化

    特定的可调度物料由Store管理

    特定的通知将发送到默认的NotificationCenter

    let observerInterceptor = ObserverInterceptor.observe([

      .onStart([

        // list of dispatchable items dispatched when the store is initialized

      ])

    ])

    let store = Store<CounterState>(interceptor: [observerInterceptor])

    注意,当使用ObserverInterceptor拦截Side Effects时,dispatchable的返回值对拦截器本身是不可用的。

    Requirements

    iOS 9.0+ / macOS 10.10+

    Xcode 8.0+

    Swift 4.0+

    CocoaPods

    use_frameworks!

    source 'https://github.com/CocoaPods/Specs.git'

    platform :ios, '9.0'

    target 'MyApp' do

      pod 'Katana'

    end

    相关文章

      网友评论

          本文标题:Katana 介绍

          本文链接:https://www.haomeiwen.com/subject/epysaktx.html