Skip to content

Commit

Permalink
Merge pull request #14 from cats-oss/improve-logic
Browse files Browse the repository at this point in the history
Improve LogicType implementation
  • Loading branch information
marty-suzuki authored Oct 24, 2019
2 parents 5d17e82 + aea1309 commit 316531e
Show file tree
Hide file tree
Showing 11 changed files with 92 additions and 133 deletions.
15 changes: 15 additions & 0 deletions Documentation/Unio0_6_0MigrationGuide.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Unio 0.6.0 Migration Guide

Unio 0.6.0 introduces some breaking changes.

## Classes

- [RENAME] `UnioStream<Logic>` -> `PrimitiveStream<Logic>`

## Methods

- [REPLACE] `LogicType func bind(from:)` -> `LogicType static func bind(from:disposeBag:)`

## Typealias

- [ADD] `typealias UnioStream<Logic: LogicType> = PrimitiveStream<Logic> & LogicType`
22 changes: 5 additions & 17 deletions Example/UnioSample/GitHubSearchAPIStream.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,16 @@ protocol GitHubSearchAPIStreamType: AnyObject {
var output: OutputWrapper<GitHubSearchAPIStream.Output> { get }
}

final class GitHubSearchAPIStream: UnioStream<GitHubSearchAPIStream.Logic>, GitHubSearchAPIStreamType {
final class GitHubSearchAPIStream: UnioStream<GitHubSearchAPIStream>, GitHubSearchAPIStreamType {

init(extra: Extra = .init()) {
init(extra: Extra = .init(session: .shared)) {
super.init(input: Input(),
state: State(),
extra: extra,
logic: Logic())
extra: extra)
}
}

extension GitHubSearchAPIStream {
typealias State = NoState

struct Input: InputType {

Expand All @@ -41,20 +39,10 @@ extension GitHubSearchAPIStream {

struct Extra: ExtraType {

let session = URLSession.shared
let session: URLSession
}

struct Logic: LogicType {
typealias Input = GitHubSearchAPIStream.Input
typealias Output = GitHubSearchAPIStream.Output
typealias State = GitHubSearchAPIStream.State
typealias Extra = GitHubSearchAPIStream.Extra
}
}

extension GitHubSearchAPIStream.Logic {

func bind(from dependency: Dependency<Input, State, Extra>) -> Output {
static func bind(from dependency: Dependency<Input, NoState, Extra>, disposeBag: DisposeBag) -> Output {

let session = dependency.extra.session

Expand Down
19 changes: 3 additions & 16 deletions Example/UnioSample/GitHubSearchLogicStream.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,12 @@ protocol GitHubSearchLogicStreamType: AnyObject {
var output: OutputWrapper<GitHubSearchLogicStream.Output> { get }
}

final class GitHubSearchLogicStream: UnioStream<GitHubSearchLogicStream.Logic>, GitHubSearchLogicStreamType {
final class GitHubSearchLogicStream: UnioStream<GitHubSearchLogicStream>, GitHubSearchLogicStreamType {

init(extra: Extra = .init(searchAPIStream: GitHubSearchAPIStream(), scheduler: ConcurrentMainScheduler.instance)) {
super.init(input: Input(),
state: State(),
extra: extra,
logic: Logic())
extra: extra)
}
}

Expand Down Expand Up @@ -49,19 +48,7 @@ extension GitHubSearchLogicStream {
let scheduler: SchedulerType
}

struct Logic: LogicType {
typealias Input = GitHubSearchLogicStream.Input
typealias Output = GitHubSearchLogicStream.Output
typealias State = GitHubSearchLogicStream.State
typealias Extra = GitHubSearchLogicStream.Extra

let disposeBag = DisposeBag()
}
}

extension GitHubSearchLogicStream.Logic {

func bind(from dependency: Dependency<Input, State, Extra>) -> Output {
static func bind(from dependency: Dependency<Input, State, Extra>, disposeBag: DisposeBag) -> Output {

let state = dependency.state
let extra = dependency.extra
Expand Down
22 changes: 3 additions & 19 deletions Example/UnioSample/GitHubSearchViewStream.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,17 @@ protocol GitHubSearchViewStreamType: AnyObject {
var output: OutputWrapper<GitHubSearchViewStream.Output> { get }
}

final class GitHubSearchViewStream: UnioStream<GitHubSearchViewStream.Logic>, GitHubSearchViewStreamType {
final class GitHubSearchViewStream: UnioStream<GitHubSearchViewStream>, GitHubSearchViewStreamType {

init(extra: Extra = .init(logicStream: GitHubSearchLogicStream())) {
super.init(input: Input(),
state: State(),
extra: extra,
logic: Logic())
extra: extra)
}
}

extension GitHubSearchViewStream {

typealias State = NoState

struct Input: InputType {

let searchText = PublishRelay<String?>()
Expand All @@ -43,22 +40,9 @@ extension GitHubSearchViewStream {
struct Extra: ExtraType {

let logicStream: GitHubSearchLogicStreamType
let disposeBag = DisposeBag()
}

struct Logic: LogicType {
typealias Input = GitHubSearchViewStream.Input
typealias Output = GitHubSearchViewStream.Output
typealias State = GitHubSearchViewStream.State
typealias Extra = GitHubSearchViewStream.Extra

let disposeBag = DisposeBag()
}
}

extension GitHubSearchViewStream.Logic {

func bind(from dependency: Dependency<Input, State, Extra>) -> Output {
static func bind(from dependency: Dependency<Input, NoState, Extra>, disposeBag: DisposeBag) -> Output {

let logicStream = dependency.extra.logicStream

Expand Down
51 changes: 20 additions & 31 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -160,35 +160,33 @@ struct Extra: ExtraType {
### Logic

The rule of Logic is generating [Output](#output) from Dependency<Input, State, Extra>.
It generates [Output](#output) to call `func bind(from:)`.
`func bind(from:)` is called once when [UnioStream](#uniostream) is initialized.
If you want to use DisposeBags in `func bind(from:)`, define properties of DisposeBag in Logic.
It generates [Output](#output) to call `static func bind(from:disposeBag:)`.
`static func bind(from:disposeBag:)` is called once when [UnioStream](#uniostream) is initialized.

```swift
struct Logic: LogicType {
enum Logic: LogicType {
typealias Input = GitHubSearchViewStream.Input
typealias Output = GitHubSearchViewStream.Output
typealias State = GitHubSearchViewStream.State
typealias Extra = GitHubSearchViewStream.Extra

let disposeBag = DisposeBag()

func bind(from dependency: Dependency<Input, State, Extra>) -> Output
static func bind(from dependency: Dependency<Input, State, Extra>, disposeBag: DisposeBag) -> Output
}
```

Connect sequences and generate [Output](#output) in `func bind(from:)` to use below properties and methods.
Connect sequences and generate [Output](#output) in `static func bind(from:disposeBag:)` to use below properties and methods.

- `dependency.state`
- `dependency.extra`
- `dependency.inputObservables` ... returns a Observable that is property of [Input](#input).
- `dependency.inputObservables` ... Returns a Observable that is property of [Input](#input).
- `disposeBag` ... Same lifecycle with UnioStream.

Here is a exmaple of implementation.

```swift
extension GitHubSearchViewStream.Logic {
extension Logic {

func bind(from dependency: Dependency<Input, State, Extra>) -> Output {
static func bind(from dependency: Dependency<Input, State, Extra>, disposeBag: DisposeBag) -> Output {
let apiStream = dependency.extra.apiStream

dependency.inputObservables.searchText
Expand All @@ -210,22 +208,24 @@ It has `input: InputWrapper<Input>` and `output: OutputWrapper<Output>`.
It automatically generates `input: InputWrapper<Input>` and `output: OutputWrapper<Output>` from instances of [Input](#input), [State](#state), [Extra](#extra) and [Logic](#logic).

```swift
class UnioStream<Logic: LogicType> {
typealias UnioStream<Logic: LogicType> = PrimitiveStream<Logic> & LogicType

class PrimitiveStream<Logic: LogicType> {

let input: InputWrapper<Logic.Input>
let output: OutputWrapper<Logic.Output>

init(input: Logic.Input, state: Logic.State, extra: Logic.Extra, logic: Logic)
init(input: Logic.Input, state: Logic.State, extra: Logic.Extra)
}
```

Be able to define a subclass of UnioStream like this.

```swift
fianl class GitHubSearchViewStream: UnioStream<GitHubSearchViewStream.Logic> {
fianl class GitHubSearchViewStream: UnioStream<GitHubSearchViewStream> {

init() {
super.init(input: Input(), state: State(), extra: Extra(), logic: Logic())
super.init(input: Input(), state: State(), extra: Extra())
}
}
```
Expand All @@ -244,10 +244,10 @@ protocol GitHubSearchViewStreamType: AnyObject {
var output: OutputWrapper<GitHubSearchViewStream.Output> { get }
}

final class GitHubSearchViewStream: UnioStream<GitHubSearchViewStream.Logic>, GitHubSearchViewStreamType {
final class GitHubSearchViewStream: UnioStream<GitHubSearchViewStream>, GitHubSearchViewStreamType {

init() {
super.init(input: Input(), state: State(), extra: Extra(), logic: Logic())
super.init(input: Input(), state: State(), extra: Extra())
}

typealias State = NoState
Expand All @@ -264,19 +264,7 @@ final class GitHubSearchViewStream: UnioStream<GitHubSearchViewStream.Logic>, Gi
let apiStream: GitHubSearchAPIStream()
}

struct Logic: LogicType {
typealias Input = GitHubSearchViewStream.Input
typealias Output = GitHubSearchViewStream.Output
typealias State = GitHubSearchViewStream.State
typealias Extra = GitHubSearchViewStream.Extra

let disposeBag = DisposeBag()
}
}

extension GitHubSearchViewStream.Logic {

func bind(from dependency: Dependency<Input, State, Extra>) -> Output {
static func bind(from dependency: Dependency<Input, State, Extra>, disposeBag: DisposeBag) -> Output {
let apiStream = dependency.extra.apiStream

dependency.inputObservables.searchText
Expand All @@ -299,7 +287,7 @@ final class GitHubSearchViewController: UIViewController {
let searchBar = UISearchBar(frame: .zero)
let tableView = UITableView(frame: .zero)

private let viewStream = GitHubSearchViewStream()
private let viewStream: GitHubSearchViewStreamType = GitHubSearchViewStream()
private let disposeBag = DisposeBag()

override func viewDidLoad() {
Expand All @@ -325,6 +313,7 @@ The documentation which does not use `KeyPath Dynamic Member Lookup` is [here](h
#### Migration Guides

- [Unio 0.5.0 Migration Guide](./Documentation/Unio0_5_0MigrationGuide.md)
- [Unio 0.6.0 Migration Guide](./Documentation/Unio0_6_0MigrationGuide.md)

### Xcode Template

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,12 @@ protocol ___VARIABLE_productName___ViewStreamType: AnyObject {
var output: OutputWrapper<___VARIABLE_productName___ViewStream.Output> { get }
}

final class ___VARIABLE_productName___ViewStream: UnioStream<___VARIABLE_productName___ViewStream.Logic>, ___VARIABLE_productName___ViewStreamType {
final class ___VARIABLE_productName___ViewStream: UnioStream<___VARIABLE_productName___ViewStream>, ___VARIABLE_productName___ViewStreamType {

init(extra: Extra = .init()) {
super.init(input: Input(),
state: State(),
extra: extra,
logic: Logic())
extra: extra)
}
}

Expand Down Expand Up @@ -52,19 +51,7 @@ extension ___VARIABLE_productName___ViewStream {

}

struct Logic: LogicType {
typealias Input = ___VARIABLE_productName___ViewStream.Input
typealias Output = ___VARIABLE_productName___ViewStream.Output
typealias State = ___VARIABLE_productName___ViewStream.State
typealias Extra = ___VARIABLE_productName___ViewStream.Extra

let disposeBag = DisposeBag()
}
}

extension ___VARIABLE_productName___ViewStream.Logic {

func bind(from dependency: Dependency<Input, State, Extra>) -> Output {
static func bind(from dependency: Dependency<Input, State, Extra>, disposeBag: DisposeBag) -> Output {

let state = dependency.state

Expand Down
19 changes: 3 additions & 16 deletions Tools/UnioStream.xctemplate/___FILEBASENAME___Stream.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,12 @@ protocol ___VARIABLE_productName___StreamType: AnyObject {
var output: OutputWrapper<___VARIABLE_productName___Stream.Output> { get }
}

final class ___VARIABLE_productName___Stream: UnioStream<___VARIABLE_productName___Stream.Logic>, ___VARIABLE_productName___StreamType {
final class ___VARIABLE_productName___Stream: UnioStream<___VARIABLE_productName___Stream>, ___VARIABLE_productName___StreamType {

init(extra: Extra = .init()) {
super.init(input: Input(),
state: State(),
extra: extra,
logic: Logic())
extra: extra)
}
}

Expand Down Expand Up @@ -52,19 +51,7 @@ extension ___VARIABLE_productName___Stream {

}

struct Logic: LogicType {
typealias Input = ___VARIABLE_productName___Stream.Input
typealias Output = ___VARIABLE_productName___Stream.Output
typealias State = ___VARIABLE_productName___Stream.State
typealias Extra = ___VARIABLE_productName___Stream.Extra

let disposeBag = DisposeBag()
}
}

extension ___VARIABLE_productName___Stream.Logic {

func bind(from dependency: Dependency<Input, State, Extra>) -> Output {
static func bind(from dependency: Dependency<Input, State, Extra>, disposeBag: DisposeBag) -> Output {

let state = dependency.state

Expand Down
2 changes: 1 addition & 1 deletion Unio.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

Pod::Spec.new do |s|
s.name = "Unio"
s.version = "0.5.0"
s.version = "0.6.0"
s.summary = "KeyPath based Unidirectionarl Input / Output framework with RxSwift."
s.homepage = "https://github.com/cats-oss/Unio"
s.license = { :type => "MIT", :file => "LICENSE" }
Expand Down
4 changes: 3 additions & 1 deletion Unio/LogicType.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
// Copyright © 2019 tv.abema. All rights reserved.
//

import RxSwift

/// Represents definitions and implementations of UnioStream logic.
public protocol LogicType {
associatedtype Input: InputType
Expand All @@ -16,5 +18,5 @@ public protocol LogicType {
/// Generates Output from Dependency.
///
/// - note: This method called once when a linked UnioStream is initialized.
func bind(from dependency: Dependency<Input, State, Extra>) -> Output
static func bind(from dependency: Dependency<Input, State, Extra>, disposeBag: DisposeBag) -> Output
}
Loading

0 comments on commit 316531e

Please sign in to comment.