Slide 1

Slide 1 text

©2018 Wantedly, Inc. ReactorKit at Wantedly ReactorKit Meetup Japan 28.Jun.2018 - Jiro Nagashima

Slide 2

Slide 2 text

©2018 Wantedly, Inc. ReactorKit is simple and powerful Page Title Page Subtitle

Slide 3

Slide 3 text

ϖʔδλΠτϧ ϖʔδαϒλΠτϧ ©2018 Wantedly, Inc. Jiro Nagashima @hedjirog Software Engineer Wantedly Visit App

Slide 4

Slide 4 text

©2018 Wantedly, Inc. https://wantedlyinc.com/ja/products

Slide 5

Slide 5 text

©2018 Wantedly, Inc. An app which requires a lot of state management search, profile, chat, etc… Page Title Page Subtitle

Slide 6

Slide 6 text

©2018 Wantedly, Inc. ReactorKit took care of it all ❤ Page Title Page Subtitle

Slide 7

Slide 7 text

©2018 Wantedly, Inc. 2017 Page Title Page Subtitle 2018 Used in one screen Used everywhere

Slide 8

Slide 8 text

©2018 Wantedly, Inc. ReactorKit is simple Page Title Page Subtitle

Slide 9

Slide 9 text

ϖʔδλΠτϧ ϖʔδαϒλΠτϧ ©2018 Wantedly, Inc. https://github.com/ReactorKit/ReactorKit#basic-concept

Slide 10

Slide 10 text

©2018 Wantedly, Inc. Less typing Easy to understand Easy to code review ReactorKit is simple, therefore

Slide 11

Slide 11 text

©2018 Wantedly, Inc. ReactorKit is powerful Page Title Page Subtitle

Slide 12

Slide 12 text

©2018 Wantedly, Inc. Example 1 Showing bookmarked status Page Title Page Subtitle

Slide 13

Slide 13 text

ϖʔδλΠτϧ ϖʔδαϒλΠτϧ ©2018 Wantedly, Inc.

Slide 14

Slide 14 text

ϖʔδλΠτϧ ϖʔδαϒλΠτϧ ©2018 Wantedly, Inc. Reactor View Action State

Slide 15

Slide 15 text

ϖʔδλΠτϧ ϖʔδαϒλΠτϧ ©2018 Wantedly, Inc. Reactor View Action State

Slide 16

Slide 16 text

ϖʔδλΠτϧ ϖʔδαϒλΠτϧ ©2018 Wantedly, Inc. // ProjectViewController func bind(reactor: ProjectReactor) { // Action rx.methodInvoked(#selector(viewDidLoad)) .map { _ in Reactor.Action.load } .bind(to: reactor.action) .disposed(by: disposeBag) // State reactor.state.map { $0.isBookmarking } .bind(to: bookmarkButton.rx.isSelected) .disposed(by: disposeBag) }

Slide 17

Slide 17 text

ϖʔδλΠτϧ ϖʔδαϒλΠτϧ ©2018 Wantedly, Inc. Reactor View Action State

Slide 18

Slide 18 text

ϖʔδλΠτϧ ϖʔδαϒλΠτϧ ©2018 Wantedly, Inc. // ProjectReactor enum Action { case load } enum Mutation { case setProject(Project) } struct State { let projectId: Int var isBookmarking: Bool }

Slide 19

Slide 19 text

ϖʔδλΠτϧ ϖʔδαϒλΠτϧ ©2018 Wantedly, Inc. // ProjectReactor func mutate(action: Action) -> Observable { switch action { case .load: return projectRepository.project(id: currentState.projectId) .asObservable() .map(Mutation.setProject) } } func reduce(state: State, mutation: Mutation) -> State { var state = state switch mutation { case let .setProject(project): state.isBookmarking = project.bookmarked } return state }

Slide 20

Slide 20 text

©2018 Wantedly, Inc. Example 2 Bookmark event propagation Page Title Page Subtitle

Slide 21

Slide 21 text

ϖʔδλΠτϧ ϖʔδαϒλΠτϧ ©2018 Wantedly, Inc.

Slide 22

Slide 22 text

ϖʔδλΠτϧ ϖʔδαϒλΠτϧ ©2018 Wantedly, Inc. Reactor View Action State Reactor View Action State Event Stream

Slide 23

Slide 23 text

ϖʔδλΠτϧ ϖʔδαϒλΠτϧ ©2018 Wantedly, Inc. Reactor View Action State Reactor View Action State Event Stream

Slide 24

Slide 24 text

ϖʔδλΠτϧ ϖʔδαϒλΠτϧ ©2018 Wantedly, Inc. // ProjectRepository func bookmark(projectId: Int) -> Single { return provider.rx.request(.bookmark(projectId: projectId)) .filterSuccessfulStatusCodes() .map { _ in } .do(onSubscribe: { _ in ProjectEvent.stream.onNext( .updateBookmarking(projectId: projectId, isBookmarking: true) ) }) .do(onError: { _ in ProjectEvent.stream.onNext( .updateBookmarking(projectId: projectId, isBookmarking: false) ) }) }

Slide 25

Slide 25 text

ϖʔδλΠτϧ ϖʔδαϒλΠτϧ ©2018 Wantedly, Inc. // ProjectReactor enum Action { case toggleBookmarking } func mutate(action: Action) -> Observable { switch action { case .toggleBookmarking: if currentState.isBookmarking { _ = projectRepository.unbookmark(projectId: currentState.projectId).subscribe() } else { _ = projectRepository.bookmark(projectId: currentState.projectId).subscribe() } return .empty() } }

Slide 26

Slide 26 text

ϖʔδλΠτϧ ϖʔδαϒλΠτϧ ©2018 Wantedly, Inc. Reactor View Action State Reactor View Action State Event Stream

Slide 27

Slide 27 text

ϖʔδλΠτϧ ϖʔδαϒλΠτϧ ©2018 Wantedly, Inc. // ProjectCellReactor func transform(mutation: Observable) -> Observable { let projectId = currentState.projectId let fromProjectEvent = ProjectEvent.stream .flatMap { event -> Observable in switch event { case let .updateBookmarking(id, isBookmarking): return id == projectId ? .just(.setBookmarking(isBookmarking)) : .empty() } } return Observable.merge(mutation, fromProjectEvent) } func reduce(state: State, mutation: Mutation) -> State { var state = state switch mutation { case let .setBookmarking(isBookmarking): state.isBookmarking = isBookmarking } return state }

Slide 28

Slide 28 text

©2018 Wantedly, Inc. Example 3 Company page Page Title Page Subtitle

Slide 29

Slide 29 text

ϖʔδλΠτϧ ϖʔδαϒλΠτϧ ©2018 Wantedly, Inc.

Slide 30

Slide 30 text

ϖʔδλΠτϧ ϖʔδαϒλΠτϧ ©2018 Wantedly, Inc. Company Home Posts Info Projects Employees

Slide 31

Slide 31 text

ϖʔδλΠτϧ ϖʔδαϒλΠτϧ ©2018 Wantedly, Inc. Company Home Posts Info Projects Employees

Slide 32

Slide 32 text

ϖʔδλΠτϧ ϖʔδαϒλΠτϧ ©2018 Wantedly, Inc. Company Home Posts Info Projects Employees Event Stream Reactor View Action State Reactor View Action State

Slide 33

Slide 33 text

©2018 Wantedly, Inc. Complicated state management is possible Covers most use cases ReactorKit is powerful, therefore

Slide 34

Slide 34 text

©2018 Wantedly, Inc. ReactorKit is simple and powerful Page Title Page Subtitle

Slide 35

Slide 35 text

©2018 Wantedly, Inc. I can wholeheartedly recommend it! Page Title Page Subtitle

Slide 36

Slide 36 text

No content