2018.03.22 iOS Flux / Redux 勉強会 の登壇資料です
https://wantedly.connpass.com/event/79914/
2018.3.22 -©2018 Wantedly, Inc.ReactorKit Λར༻ͨ͠؇͔ͳΞʔΩςΫνϟͷҠߦiOS Flux / ReduxษڧձJiro Nagashima
View Slide
©2018 Wantedly, Inc. ͡Ίʹ
©2018 Wantedly, Inc. ࣗݾհӬౡ࣍࿕@hedjirogUser Growth νʔϜϦʔμʔWantedly VisitΞϓϦͷ։ൃվળࢪࡦΛ࣮ࢪͭͭ͠શମͷ࣮ํͷܾఆͱ࣮ࡍͷมߋΛߦͳ͏
©2018 Wantedly, Inc. ൃදͷͶΒ͍෦త͔ͭஈ֊తͳΞʔΩςΫνϟͷҠߦͷࣄྫΛհWantedly VisitΞϓϦͷReactorKit Λར༻ͨ͠
©2018 Wantedly, Inc. ൃදͷͶΒ͍ ৽نࣄۀ େنͳϦϑΝΫλϦϯά# طଘΞϓϦͷվળࢪࡦͱಉ࣌ʹ࣮ࢪPOINT෦త͔ͭஈ֊తͳΞʔΩςΫνϟͷҠߦͷࣄྫΛհWantedly VisitΞϓϦͷReactorKit Λར༻ͨ͠
©2018 Wantedly, Inc. Wantedly Visit ΞϓϦͱ։ൃମ੍ Wantedly Visit ΞϓϦͷվम ReactorKit ͷಋೖReactorKit Λར༻࣮ͨ͠ReactorKitಋೖޙͷؾ͖ͮ ࣍
©2018 Wantedly, Inc. Wantedly VisitΞϓϦͱ։ൃମ੍ͳͥ෦త͔ͭஈ֊తʹΞʔΩςΫνϟͷҠߦΛਐΊͨͷ͔ʁ
©2018 Wantedly, Inc. https://wantedlyinc.com/ja/products Wantedly Visit
©2018 Wantedly, Inc. Wantedly Visit ΞϓϦͱ։ൃମ੍‣ ࣮มߋͷݕ౼͕ඞཁw J04ΞϓϦެ։͞Ε͕ͯܦաw Objective-C͔ΒSwiftͷ࣮Ҡߦw ϦϦʔεॳ͔ΒͷAPIΫϥΠΞϯτ࣮͕ଘࡏ‣ ݶΒΕͨϦιʔεͰ։ൃΛਐΊΔඞཁੑw ৽نࣄۀʹϦιʔε͕ूதw େنͳ࣮มߋΛߦͳ͏ϦιʔεΛ֬อͰ͖ͳ͍‣ ΤϯδχΞͷۀ୯७ͳ։ൃ͚ͩͰͳ͍• தظͷࢪࡦͷܾఆɾ࣮ࢪΛΤϯδχΞ͕ࣗߦͳ͏
©2018 Wantedly, Inc. ΞʔΩςΫνϟҠߦͷഎܠ‣ ࣮มߋͷݕ౼͕ඞཁ‣ ݶΒΕͨϦιʔεͰ։ൃΛਐΊΔඞཁੑ‣ ΤϯδχΞͷۀ୯७ͳ։ൃ͚ͩͰͳ͍େنͳ࣮มߋΛߦͳΘͣɺվળࢪࡦͷ࣮ࢪͱซͤͯ෦త͔ͭஈ֊తͳΞʔΩςΫνϟͷҠߦ͕ՄೳͳखஈΛٻΊ͍ͯͨ
©2018 Wantedly, Inc. Wantedly VisitΞϓϦͷվमͲͷ෦ͰΞʔΩςΫνϟͷҠߦΛਐΊͨͷ͔ʁ
©2018 Wantedly, Inc.վमՕॴืूը໘‣ ଟ༷ͳίϯςϯπw ձࣾใɺϝϯόʔͷϓϩϑΟʔϧɺԠԉίϝϯτ‣ ෳͷAPIϦΫΤετw ืूͷৄࡉɺλάͷҰཡɺؔ࿈ืूͷҰཡ‣ Ϣʔβʔૢ࡞ʹΑΔঢ়ଶมߋw ϒοΫϚʔΫɺԠืɺԠԉw දࣔϝϯόʔͷΓସ͑
©2018 Wantedly, Inc.վमՕॴืूը໘‣ ଟ༷ͳίϯςϯπ‣ ෳͷAPIϦΫΤετ‣ Ϣʔβʔૢ࡞ʹΑΔঢ়ଶมߋෳࡶͳը໘Ͱ෦తͳΞʔΩςΫνϟͷҠߦʹޭ
©2018 Wantedly, Inc. ΞʔΩςΫνϟҠߦͷཱऀReactorKithttps://github.com/ReactorKit/ReactorKit
©2018 Wantedly, Inc. ReactorKitͷಋೖReactorKitͱԿ͔ʁͳͥReactorKitΛಋೖͨ͠ͷ͔ʁ
©2018 Wantedly, Inc.‣ Fluxͷ࣮ݱw ୯Ұํͷσʔλϑϩʔw ঢ়ଶཧͷෳࡶ͞ͷղফ‣ Reactive ProgrammingΛԠ༻w ετϦʔϜʹΑΔ6*ૢ࡞ঢ়ଶͷൖw RxSwiftΛར༻w ඇಉظॲཧͷෳࡶ͞ͷղফ ReactorKit
©2018 Wantedly, Inc. ReactorKit ͷ֓೦ਤhttps://github.com/ReactorKit/ReactorKit#basic-conceptۃΊͯγϯϓϧ
©2018 Wantedly, Inc. ReactorKit ಋೖͷܾΊख‣ Flux ୯Ұํͷσʔλϑϩʔʹର͢Δظw Wantedly Visit ΞϓϦͷಛͱͯ͠ɺঢ়ଶཧΛඞཁͱ͢Δ༷ʑͳը໘Λ༗͢Δw ଟ༷ͳίϯςϯπͷදࣔɺߴͳݕࡧϑΟϧλʔɺνϟοτɺϓϩϑΟʔϧฤू‣ RxSwift ͱซ༻Մೳw RxSwiftΛར༻͍ͯ͠ΔͷͰɺซ༻͢Δख๏Λཱ֬͢Δඞཁ͕ͳ͍‣ ෦త͔ͭஈ֊తʹಋೖ͕Մೳ• “Start Small”ͱ͍͏σβΠϯΰʔϧΛܝ͍͛ͯΔ
©2018 Wantedly, Inc. ReactorKitΛར༻࣮ͨ͠ͲͷΑ͏ͳ࣮͔ʁ
©2018 Wantedly, Inc. ืूը໘ͷ࣮https://github.com/ReactorKit/ReactorKit#basic-concept
©2018 Wantedly, Inc. ืूը໘ͷ࣮https://github.com/ReactorKit/ReactorKit#reactor
©2018 Wantedly, Inc. ืूը໘ͷ࣮https://github.com/ReactorKit/ReactorKit#reactorProjectViewControllerProjectViewReactor
©2018 Wantedly, Inc. Reactor ͷ࣮ProjectViewReactor1. ActionͱStateͷఆٛ2. mutateϝιουͱredueϝιουͷ࣮POINThttps://github.com/ReactorKit/ReactorKit#reactor
©2018 Wantedly, Inc.enum Action {case loadcase additionalLoadcase toggleBookmarkingcase selectStaffing(Int)} Action ͷఆٛྫProjectViewReactor
©2018 Wantedly, Inc.struct State {var project: Projectvar summaryTags: [ProjectSummaryTag] = []var relatedProjectSections: [ProjectRelatedProjectSection] = []var companyProjects: [Project] = []var isProjectLoaded: Bool = falsevar isBookmarking: Boolvar isApplying: Boolvar isSupporting: Boolvar selectedStaffing: Staffing?} State ͷఆٛྫProjectViewReactor
©2018 Wantedly, Inc.func mutate(action: Action) -> Observable {switch action {case .load:return Observable.merge(Observable.concat([projectService.project(id: currentState.project.id).asObservable().map { .setProject($0) },Observable.just(.setProjectLoaded(true)),]),projectService.summaryTags(projectID: currentState.project.id).asObservable().map { .setSummaryTags($0) })…} mutate ϝιουͷ࣮ྫProjectViewReactor
©2018 Wantedly, Inc.func reduce(state: State, mutation: Mutation) -> State {switch mutation {case let .setProject(project):var state = statestate.project = projectstate.isBookmarking = project.isBookmarkingstate.isApplying = project.isAppliedstate.isSupporting = project.isSupportingstate.selectedStaffing = state.selectedStaffing ?? project.staffings?.firstreturn state…} reduce ϝιουͷ࣮ྫProjectViewReactor
©2018 Wantedly, Inc.ProjectViewController View ͷ࣮1. bindϝιουͷ࣮2. ActionͷൖͱStateͷөPOINThttps://github.com/ReactorKit/ReactorKit#reactor
©2018 Wantedly, Inc.ProjectViewControllerfunc bind(reactor: Reactor) {rx.methodInvoked(#selector(viewDidLoad)).map { _ in Reactor.Action.load }.bind(to: reactor.action).disposed(by: disposeBag)…state.map { $0.isBookmarking }.distinctUntilChanged().bind(to: bookmarkButton.rx.isSelected).disposed(by: disposeBag)…} bind ϝιουͷ࣮ྫ
©2018 Wantedly, Inc. ReactorKitಋೖޙͷؾ͖ͮಋೖ͔ͯͬͨ͜͠ͱԿ͔ʁ
©2018 Wantedly, Inc.ؾ͖ͮ‣ ςετख๏ཱ͕֬͞Ε͍ͯΔw ԿΛͲ͏ςετ͖͔͢໌ݴ͞Ε͍ͯͯɺखஈ༻ҙ͞Ε͍ͯΔw ςετख๏ཱ͕֬͞Εͣςετ͕ॻ͔Εͳ͍ͱ͍͏ࣄଶ͕ى͜ΓͮΒ͍‣ ඇΞϓϦΤϯδχΞ͕ΞʔΩςΫνϟΛཧղ͍͢͠w ࣾͰwebͷϑϩϯτ࣮ͰRedux Λར༻͍ͯ͠ΔͷͰલఏ͕ࣝ͋Δw ReactorKitͷγϯϓϧ͞ड͚ೖΒΕ͍͢‣ αϯϓϧ͕๛w ෳͷنͷΞϓϦͷαϯϓϧ͕ެ։͞Ε͍ͯΔw ඞཁͳ࣮ྫ͕ݟ͔ͭΔʢάϩʔόϧͳঢ়ଶͷѻ͍ɺςετίʔυͳͲʣ
©2018 Wantedly, Inc. ࠂ
ϖʔδλΠτϧ ϖʔδαϒλΠτϧ©2018 Wantedly, Inc.”ReactorKit Meetup” ։࠵͠·͢࡞ऀͷํΛ͓ট͖͢Δ༧ఆͰ͢ʂϢʔβʔͷํɺ-5رऀͷํֻ͓͚͍ͩ͘͞ʂ