Skip to content

Commit 5364b3c

Browse files
committed
Merge pull request #2 from yonekawa/redesign_api
Redesign Dispatcher and EventEmitter
2 parents 3e21ffa + bf69c06 commit 5364b3c

File tree

17 files changed

+303
-235
lines changed

17 files changed

+303
-235
lines changed

Demo.playground/Contents.swift

Lines changed: 0 additions & 67 deletions
This file was deleted.

Demo.playground/Sources/SupportCode.swift

Lines changed: 0 additions & 3 deletions
This file was deleted.

Demo.playground/contents.xcplayground

Lines changed: 0 additions & 2 deletions
This file was deleted.

DemoApp/TodoAction.swift

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,24 +13,22 @@ import Result
1313
class TodoAction {
1414
class List: Action {
1515
typealias Payload = [Todo]
16-
func invoke() {
16+
func invoke(dispatcher: Dispatcher) {
1717
let todos = [Todo(title: "List ToDo 1"), Todo(title: "List ToDo 2"), Todo(title: "List ToDo 3")]
18-
Dispatcher.dispatch(self.dynamicType, result: Result(value: todos))
18+
dispatcher.dispatch(self, result: Result(value: todos))
1919
}
2020
}
2121

2222
class Create: Action {
2323
typealias Payload = Todo
2424

2525
private var title: String = ""
26-
27-
init() {}
2826
init(title: String) {
2927
self.title = title
3028
}
31-
32-
func invoke() {
33-
Dispatcher.dispatch(self.dynamicType, result: Result(value: Todo(title: self.title)))
29+
30+
func invoke(dispatcher: Dispatcher) {
31+
dispatcher.dispatch(self, result: Result(value: Todo(title: self.title)))
3432
}
3533
}
3634
}

DemoApp/TodoStore.swift

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,14 @@ import Result
1212
import Box
1313

1414
class TodoStore : Store {
15-
static let instance = TodoStore()
16-
1715
enum TodoEvent {
1816
case List
1917
case Created
2018
}
2119
typealias Event = TodoEvent
22-
20+
21+
let eventEmitter = EventEmitter<TodoStore>()
22+
2323
private var todos = [Todo]()
2424
var list: Array<Todo> {
2525
get {
@@ -28,21 +28,21 @@ class TodoStore : Store {
2828
}
2929

3030
init() {
31-
Dispatcher.register(TodoAction.List.self) { (result) -> Void in
31+
ActionCreator.dispatcher.register(TodoAction.List.self) { (result) -> Void in
3232
switch result {
3333
case .Success(let box):
3434
self.todos = box.value
35-
EventEmitter.emit(self, event: TodoEvent.List)
35+
self.eventEmitter.emit(TodoEvent.List)
3636
case .Failure(let box):
3737
break;
3838
}
3939
}
4040

41-
Dispatcher.register(TodoAction.Create.self) { (result) -> Void in
41+
ActionCreator.dispatcher.register(TodoAction.Create.self) { (result) -> Void in
4242
switch result {
4343
case .Success(let box):
4444
self.todos.insert(box.value, atIndex: 0)
45-
EventEmitter.emit(self, event: TodoEvent.Created)
45+
self.eventEmitter.emit(TodoEvent.Created)
4646
case .Failure(let box):
4747
break;
4848
}

DemoApp/ViewController.swift

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,31 +10,32 @@ import UIKit
1010
import SwiftFlux
1111

1212
class ViewController: UITableViewController {
13+
let todoStore = TodoStore()
1314

1415
override func viewDidLoad() {
1516
super.viewDidLoad()
1617

17-
EventEmitter.listen(TodoStore.instance, event: TodoStore.Event.List) { () -> Void in
18+
self.todoStore.eventEmitter.listen(TodoStore.Event.List) { () -> Void in
1819
self.tableView.reloadData()
1920
}
20-
EventEmitter.listen(TodoStore.instance, event: TodoStore.Event.Created) { () -> Void in
21+
self.todoStore.eventEmitter.listen(TodoStore.Event.Created) { () -> Void in
2122
self.tableView.reloadData()
2223
}
23-
TodoAction.List().invoke()
24+
ActionCreator.invoke(TodoAction.List())
2425
}
2526

2627
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
27-
return TodoStore.instance.list.count
28+
return self.todoStore.list.count
2829
}
2930

3031
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
3132
var cell = tableView.dequeueReusableCellWithIdentifier("TodoCell") as! UITableViewCell
32-
cell.textLabel!.text = TodoStore.instance.list[indexPath.row].title
33+
cell.textLabel!.text = self.todoStore.list[indexPath.row].title
3334
return cell
3435
}
3536

3637
@IBAction func createTodo() {
37-
TodoAction.Create(title: "New ToDo").invoke()
38+
ActionCreator.invoke(TodoAction.Create(title: "New ToDo"))
3839
}
3940
}
4041

README.md

Lines changed: 70 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,9 @@ It provides concept of "one-way data flow" with **type-safe** modules by Swift l
3636
class TodoAction {
3737
class Create : Action {
3838
typealias Payload = Todo
39-
func invoke() {
39+
func invoke(dispatcher: Dispatcher) {
4040
let todo = Todo(title: "New ToDo")
41-
Dispatcher.dispatch(self, result: Result(value: todo))
41+
dispatcher.dispatch(self, result: Result(value: todo))
4242
}
4343
}
4444
}
@@ -47,31 +47,32 @@ class TodoAction {
4747
### Step 2: Define Store and register action to dispatch
4848

4949
- Define event enum and assign type to Event `typealiase`.
50+
- Define `EventEmitter` instance with generic type.
5051
- Register any subscribe action callback to dispatcher.
5152
- Unbox action result value by Either in callback.
5253

5354
```swift
5455
class TodoStore : Store {
55-
static let instance = TodoStore()
56-
5756
enum TodoEvent {
5857
case Created
5958
}
6059
typealias Event = TodoEvent
6160

62-
var todos = [Todo]()
61+
let eventEmitter = EventEmitter<TodoStore>()
62+
63+
var todos = [Todo]()
6364
var list: Array<Todo> {
6465
get {
6566
return todos;
6667
}
6768
}
6869

6970
init() {
70-
Dispatcher.register(TodoAction.List.self) { (result) -> Void in
71+
ActionCreator.dispatcher.register(TodoAction.List.self) { (result) -> Void in
7172
switch result {
7273
case .Success(let box):
7374
self.todo = box.value
74-
EventEmitter.emit(self, event: TodoEvent.Created)
75+
self.eventEmitter.emit(TodoEvent.Created)
7576
case .Failure(let box):
7677
break;
7778
}
@@ -82,21 +83,78 @@ class TodoStore : Store {
8283

8384
### Step 3: Listen store's event at View
8485

85-
- Listen store's event by `EventEmitter`
86+
- Listen store's event by `EventEmitter` created at Step2.
8687
- Get result from store's public interface.
8788

8889
```swift
89-
EventEmitter.listen(TodoStore.instance, event: TodoStore.Event.List) { () -> Void in
90-
for todo in TodoStore.instance.list {
90+
let todoStore = TodoStore()
91+
store.eventEmitter.listen(TodoStore.Event.List) { () -> Void in
92+
for todo in todoStore.list {
9193
plintln(todo.title)
9294
}
9395
}
9496
```
9597

96-
### Step 4: Create and invoke Action from View
98+
### Step 4: Create and invoke Action by ActionCreator
99+
100+
```swift
101+
ActionCreator.invoke(TodoAction.List())
102+
```
103+
104+
## Advanced
105+
106+
### Destroy callbacks
107+
108+
Store registerer handler to Action by Dispatcher.
109+
Dispatcher has handler reference in collection.
110+
You need to release when store instance released.
97111

98112
```swift
99-
TodoAction.List().invoke()
113+
class TodoStore {
114+
private var dispatchIdentifiers: Array<String> = []
115+
init() {
116+
dispatchIdentifiers.append(
117+
ActionCreator.dispatcher.register(TodoAction.self) { (result) -> Void in
118+
...
119+
}
120+
)
121+
}
122+
123+
deinit {
124+
for identifier in dispatchIdentifiers {
125+
ActionCreator.dispatcher.unregister(identifier)
126+
}
127+
}
128+
```
129+
130+
### Replace to your own Dispatcher
131+
132+
Override dispatcher getter of `ActionCreator`, you can replace app dispatcher.
133+
134+
```swift
135+
class MyActionCreator: ActionCreator {
136+
class MyActionCreator: ActionCreator {
137+
override class var dispatcher: Dispatcher {
138+
get {
139+
return YourOwnDispatcher()
140+
}
141+
}
142+
}
143+
class YourOwnDispatcher: Dispatcher {
144+
func dispatch<T: Action>(action: T, result: Result<T.Payload, NSError>) {
145+
...
146+
}
147+
func register<T: Action>(type: T.Type, handler: (Result<T.Payload, NSError>) -> Void) -> String {
148+
...
149+
}
150+
151+
func unregister(identifier: String) {
152+
...
153+
}
154+
func waitFor<T: Action>(identifiers: Array<String>, type: T.Type, result: Result<T.Payload, NSError>) {
155+
...
156+
}
157+
}
100158
```
101159

102160
## License

0 commit comments

Comments
 (0)