From 57c5ce7b90b546c04a84d95d1a06fc05b5b1edd7 Mon Sep 17 00:00:00 2001 From: Nikita Arkhipov Date: Fri, 24 Jan 2020 14:40:34 +0300 Subject: [PATCH] Release --- Aurum.podspec | 2 +- Aurum/Classes/AurumActor.swift | 31 ++++++++++++--------- Aurum/Classes/AurumController.swift | 25 ++++++++++++++++- Aurum/Classes/AurumMiddleware.swift | 2 +- Aurum/Classes/AurumModuleConfigurator.swift | 9 +++--- Aurum/Classes/AurumReducer.swift | 3 +- Aurum/Classes/AurumStore.swift | 10 +++++-- 7 files changed, 58 insertions(+), 24 deletions(-) diff --git a/Aurum.podspec b/Aurum.podspec index bcdf052..182d447 100644 --- a/Aurum.podspec +++ b/Aurum.podspec @@ -8,7 +8,7 @@ Pod::Spec.new do |s| s.name = 'Aurum' - s.version = '0.5.0' + s.version = '1.0.0' s.summary = 'Evolution of Amber architecture' # This description is used to generate tags and improve search results. diff --git a/Aurum/Classes/AurumActor.swift b/Aurum/Classes/AurumActor.swift index 2637211..be72887 100644 --- a/Aurum/Classes/AurumActor.swift +++ b/Aurum/Classes/AurumActor.swift @@ -12,12 +12,17 @@ public struct AurumLink{ let storyboard: String let id: String + public init(storyboard: String, id: String) { + self.storyboard = storyboard + self.id = id + } + func instantiate() -> UIViewController{ return UIStoryboard(name: storyboard, bundle: nil).instantiateViewController(withIdentifier: id) } } -public enum AurumRouteType{ +public enum AurumTransitionType{ var isEmbedding: Bool{ switch self { case .embed(_), .embedFullscreen, .cleanEmbed(_), .cleanEmbedFullscreen: return true @@ -70,7 +75,7 @@ public class AurumActor(module: Module.Type, data: Module.RequiredData, type: AurumRouteType = .show, animated: Bool = true, outputListener: ((Module.OutputAction) -> Void)? = nil) -> AurumModuleData{ + @discardableResult public func route(module: Module.Type, data: Module.RequiredData, transition: AurumTransitionType = .show, animated: Bool = true, outputListener: ((Module.OutputAction) -> Void)? = nil) -> AurumModuleData{ let config = Module() - let data = config.create(data: data, rootController: type.isEmbedding ? rootController : nil, outputListener: outputListener) - route(to: data.controller, type: type, animated: animated) + let data = config.create(data: data, rootController: transition.isEmbedding ? rootController : nil, outputListener: outputListener) + route(to: data.controller, transition: transition, animated: animated) return data } - @discardableResult public func route(module: Module.Type, type: AurumRouteType = .show, animated: Bool = true, outputListener: ((Module.OutputAction) -> Void)? = nil) -> AurumModuleData where Module.RequiredData == Void{ - return route(module: module, data: (), type: type, animated: animated, outputListener: outputListener) + @discardableResult public func route(module: Module.Type, transition: AurumTransitionType = .show, animated: Bool = true, outputListener: ((Module.OutputAction) -> Void)? = nil) -> AurumModuleData where Module.RequiredData == Void{ + return route(module: module, data: (), transition: transition, animated: animated, outputListener: outputListener) } public func close(type: AurumRouteCloseType = .close, animated: Bool = true){ diff --git a/Aurum/Classes/AurumController.swift b/Aurum/Classes/AurumController.swift index cb719fa..e4bc774 100644 --- a/Aurum/Classes/AurumController.swift +++ b/Aurum/Classes/AurumController.swift @@ -7,6 +7,8 @@ // import UIKit +import Bond +import ReactiveKit public protocol AurumStoreSetupable { func set(store: AurumStore) @@ -18,13 +20,34 @@ public protocol AurumController: class, AurumStoreSetupable { var store: AurumStore! { get set } } -extension AurumController{ +public extension AurumController{ func set(store: AurumStore){ guard let s = store as? AurumStore else { fatalError("\(type(of: self)) failed to set store: expected <\(State.self), \(Action.self)> got <\(S.self), \(A.self)>") } self.store = s } } +public extension AurumController{ + var reduce: Subject { return store.reducer } + var state: State { return store.state.value } + + func field(_ extractor: @escaping (State) -> T) -> Signal{ + return store.state.map(extractor).removeDuplicates() + } + + func reduce(action: Action){ + store.reduce(action: action) + } +} + + +infix operator ~> + +public func ~>(left: (T, UIButton), right: T.Action){ + left.1.reactive.tap.replaceElements(with: right).bind(to: left.0.reduce) +} + + private var UIView_Associated_Embeded: UInt8 = 0 extension UIView{ var embedded: [UIViewController]{ diff --git a/Aurum/Classes/AurumMiddleware.swift b/Aurum/Classes/AurumMiddleware.swift index 070560f..4d4242c 100644 --- a/Aurum/Classes/AurumMiddleware.swift +++ b/Aurum/Classes/AurumMiddleware.swift @@ -38,7 +38,7 @@ public protocol AurumMiddlwareProvider { func provide(forOutputAction action: OutputAction, state: State) -> [AurumMiddleware] } -extension AurumMiddlwareProvider{ +public extension AurumMiddlwareProvider{ func provide(forInputAction action: InputAction, state: State) -> [AurumMiddleware] { return [] } func provide(forOutputAction action: OutputAction, state: State) -> [AurumMiddleware] { return [] } diff --git a/Aurum/Classes/AurumModuleConfigurator.swift b/Aurum/Classes/AurumModuleConfigurator.swift index c02194f..1d63912 100644 --- a/Aurum/Classes/AurumModuleConfigurator.swift +++ b/Aurum/Classes/AurumModuleConfigurator.swift @@ -21,9 +21,8 @@ public protocol AurumModuleConfigurator { init() - func initialize(data: RequiredData) -> (State, Reducer, MiddlewareProvider) - func controller(data: RequiredData) -> AurumLink - + func initialize(data: RequiredData) -> (State, Reducer, MiddlewareProvider, AurumLink) + func didLoad(actor: A) } @@ -31,8 +30,8 @@ public extension AurumModuleConfigurator{ func didLoad(actor: A){ } func create(data: RequiredData, rootController: UIViewController? = nil, outputListener: ((OutputAction) -> Void)? = nil) -> AurumModuleData{ - let (state, reducer, provider) = initialize(data: data) - let vc = controller(data: data).instantiate() + let (state, reducer, provider, link) = initialize(data: data) + let vc = link.instantiate() let store = AurumStorePerformer(state: state, reducer: reducer, provider: provider, rootController: rootController, controller: vc, outputListener: outputListener) guard let vcs = vc as? AurumStoreSetupable else { fatalError("\(type(of: vc)) does not conforms to AurumController") } diff --git a/Aurum/Classes/AurumReducer.swift b/Aurum/Classes/AurumReducer.swift index 9e3cfb1..74c5b5b 100644 --- a/Aurum/Classes/AurumReducer.swift +++ b/Aurum/Classes/AurumReducer.swift @@ -11,6 +11,7 @@ import Foundation public protocol AurumState {} public protocol AurumAction {} +public class AurumEmptyAction: AurumAction{} public protocol AurumReducer { associatedtype State: AurumState @@ -25,7 +26,7 @@ public protocol AurumReducer { } extension AurumReducer{ - func wrapped() -> AurumReducerWrapper{ + public func wrapped() -> AurumReducerWrapper{ return AurumReducerWrapper(reducer: self) } } diff --git a/Aurum/Classes/AurumStore.swift b/Aurum/Classes/AurumStore.swift index 46cee8d..330fb55 100644 --- a/Aurum/Classes/AurumStore.swift +++ b/Aurum/Classes/AurumStore.swift @@ -11,18 +11,24 @@ import UIKit import ReactiveKit public class AurumStore{ - let state: Property - + public let state: Property + public let reducer = Subject() + private let reduceAction: (Action) -> Void init(performer: AurumStorePerformer){ state = performer.state reduceAction = performer.reduce + subscribe() } func reduce(action: Action){ reduceAction(action) } + + func subscribe(){ + let _ = reducer.observeNext { [weak self] in self?.reduce(action: $0) } + } } public class AurumStorePerformer{