Slide 1

Slide 1 text

3Y4XJGUͰ࡞Δ"1*ϥούʔͷύλʔϯ ೥݄೔ଜా༎հ

Slide 2

Slide 2 text

ࣗݾ঺հ #&45*OD$50ଜా༎հ !NVSBUBZVTVLF IUUQNVSBUBZVTVLFDPN ɹژ౎େֶܦࡁֶ෦ଔۀ ʙָఱͷਓࣄʢ৽ଔ࠾༻ʣ ʙָఱͷΤϯδχΞ ʙ#&45גࣜձࣾ$50 ˞3Y4XJGUྺϲ݄ ɹ 3YܥϥΠϒϥϦ΋ॳ ུྺ

Slide 3

Slide 3 text

࡞͍ͬͯΔαʔϏεʢձࣾʣ IUUQTUSBWFMFSTBJ

Slide 4

Slide 4 text

࡞͍ͬͯΔαʔϏεʢݸਓʣ IUUQTCJUMZNVMUJUFBN

Slide 5

Slide 5 text

5SBWFMFSTͷߏ੒ʢ8ʣ ϒϥ΢β 3BJMT "1* ɾඳը͸3FBDU ɾ"KBYͰ3BJMTͷ"1*Λୟ͘ ɾ1SPNJTFͰෳ਺ͷ"1*ίʔϧΛνΣʔϯ͢Δ

Slide 6

Slide 6 text

5SBWFMFSTͷߏ੒ʢΞϓϦʣ ΞϓϦ 3BJMT "1* ɾඳը͸4UPSZCPBSEίʔυ ɾ"MBNPGJSFͰ3BJMTͷ"1*Λୟ͘ ɾ3Y4XJGU 3Y"MBNPGJSF Ͱෳ਺ͷ"1*ίʔϧΛ νΣʔϯ͢Δ

Slide 7

Slide 7 text

"1*ͷύλʔϯ ੒ޭPSࣦഊ͚ͩΘ͔Ε͹͍͍ ੒ޭ͚ͨ࣌ͩ͠஋͕ཉ͍͠ ࣦഊ͚ͨ࣌ͩ͠Τϥʔ಺༰͕ཉ͍͠ ੒ޭͨ͠Β஋͕ɺࣦഊͨ͠ΒΤϥʔ಺༰͕ཉ͍͠

Slide 8

Slide 8 text

"1*ͷύλʔϯ ੒ޭPSࣦഊ͚ͩΘ͔Ε͹͍͍ ੒ޭ͚ͨ࣌ͩ͠஋͕ཉ͍͠ ࣦഊ͚ͨ࣌ͩ͠Τϥʔ಺༰͕ཉ͍͠ ੒ޭͨ͠Β஋͕ɺࣦഊͨ͠ΒΤϥʔ಺༰͕ཉ͍͠

Slide 9

Slide 9 text

੒ޭPSࣦഊ͚ͩΘ͔Ε͹͍͍ ྫɿϩάΠϯ"1* ɾϩάΠϯ͕ඞཁͳॲཧͷલʹϩάΠϯը໘Λදࣔ ɾϝʔϧΞυϨεͱύεϫʔυΛ1045͢Δ ɾ੒ޭͨ͠ΒϩάΠϯը໘Λดͯ͡ଓ͖ͷॲཧΛ͢Δ ɾࣦഊͨ͠ΒݻఆͷจݴΛදࣔ ɹʢϝʔϧΞυϨεͱύεϫʔυΛ֬͝ೝ͍ͩ͘͞తͳʣ

Slide 10

Slide 10 text

੒ޭPSࣦഊ͚ͩΘ͔Ε͹͍͍ func signIn(email: String, password: String) -> Driver { let params = ["user[email]": email, "user[password]": password] return rx_responseJSON(.POST, endPoint: .SignIn, parameters: params) .map { success, _ in success } .asDriver(onErrorJustReturn: false) } ྫɿϩάΠϯ"1*

Slide 11

Slide 11 text

੒ޭ͚ͨ࣌ͩ͠஋͕ཉ͍͠ private func rx_responseJSON(method: Alamofire.Method, url: String, parameters: [String: AnyObject]? = nil, encoding: ParameterEncoding = .URL, headers: [String: String]? = nil) -> Observable<(Bool, AnyObject?)> { return manager .rx_responseJSON(method, url, parameters: parameters, ɹɹɹɹɹɹɹɹɹɹɹɹɹɹɹencoding: encoding, headers: headers) .map { response, json in if 200 ..< 300 ~= response.statusCode { return (true, json) } else { return (false, json) } } } SY@SFTQPOTF+40/ͷத਎

Slide 12

Slide 12 text

੒ޭPSࣦഊ͚ͩΘ͔Ε͹͍͍ func signIn(email: String, password: String) -> Driver { let params = ["user[email]": email, "user[password]": password] return rx_responseJSON(.POST, endPoint: .SignIn, parameters: params) .map { success, _ in success } .asDriver(onErrorJustReturn: false) } ྫɿϩάΠϯ"1* ɾجຊ%SJWFSΛฦ͢ ɹˠඇಉظͷ6*ૢ࡞ʹ΋͍ͬͯ͜ ɹɹ$BO`UFSSPSPVU ɹɹ0CTFSWFPONBJOTDIFEVMFS ɹɹ4IBSJOHTJEFFGGFDUT ɹɹIUUQTHJUIVCDPN3FBDUJWF93Y4XJGUCMPCNBTUFS%PDVNFOUBUJPO6OJUTNEESJWFSVOJU

Slide 13

Slide 13 text

੒ޭPSࣦഊ͚ͩΘ͔Ε͹͍͍ func signIn(email: String, password: String) -> Driver { let params = ["user[email]": email, "user[password]": password] return rx_responseJSON(.POST, endPoint: .SignIn, parameters: params) .map { success, _ in success } .asDriver(onErrorJustReturn: false) } ྫɿϩάΠϯ"1* ɾܕ͸#PPMʹ͢Δ ɹˠ੒ޭ͔ࣦഊ͔ͷ୒ ɹˠ0QUJPOBMͰ͋Δඞཁ΋ͳ͍

Slide 14

Slide 14 text

੒ޭPSࣦഊ͚ͩΘ͔Ε͹͍͍ func signIn(email: String, password: String) -> Driver { let params = ["user[email]": email, "user[password]": password] return rx_responseJSON(.POST, endPoint: .SignIn, parameters: params) .map { success, _ in success } .asDriver(onErrorJustReturn: false) } ྫɿϩάΠϯ"1* ɾͳͷͰࣦഊͨ͠ΒGBMTFฦ͠ͱ͚͹͍͍

Slide 15

Slide 15 text

੒ޭPSࣦഊ͚ͩΘ͔Ε͹͍͍ let input = Driver.combineLatest(email, password) { ($0, $1) } loginButton.rx_tap.asDriver() .withLatestFrom(input) .flatMapLatest { mail, password in api.signIn(mail, password: password) } .driveNext { [unowned self] success in if success { self.dismissViewControllerAnimated(true, completion: nil) } else { // show error message } } .addDisposableTo(disposeBag) ྫɿϩάΠϯ"1* ɾ࢖͏ଆʢ6*7JFXªPOUSPMMFSʣ͸͜Μͳײ͡

Slide 16

Slide 16 text

"1*ͷύλʔϯ ੒ޭPSࣦഊ͚ͩΘ͔Ε͹͍͍ ੒ޭ͚ͨ࣌ͩ͠஋͕ཉ͍͠ ࣦഊ͚ͨ࣌ͩ͠Τϥʔ಺༰͕ཉ͍͠ ੒ޭͨ͠Β஋͕ɺࣦഊͨ͠ΒΤϥʔ಺༰͕ཉ͍͠

Slide 17

Slide 17 text

੒ޭ͚ͨ࣌ͩ͠஋͕ཉ͍͠ ྫɿϢʔβʔ৘ใ ɾઃఆը໘ͰϩάΠϯதͷϢʔβʔͷ৘ใΛද͍ࣔͨ͠ ɾ"1*͕੒ޭͨ͠ΒϨεϙϯε಺༰Λදࣔ ɾࣦഊͨ͠ΒϩάΠϯϘλϯΛදࣔʢະϩάΠϯѻ͍ʣ

Slide 18

Slide 18 text

੒ޭ͚ͨ࣌ͩ͠஋͕ཉ͍͠ func fetchUserInfo() -> Driver { return rx_responseJSON(.GET, endPoint: .Users) .map { success, json in if success { guard let json = json as? [String: AnyObject] else { throw apiError("User parse error") } return try User(json: json) } else { return nil } } .asDriver(onErrorJustReturn: nil) } ྫɿϢʔβʔ৘ใ

Slide 19

Slide 19 text

੒ޭ͚ͨ࣌ͩ͠஋͕ཉ͍͠ func fetchUserInfo() -> Driver { return rx_responseJSON(.GET, endPoint: .Users) .map { success, json in if success { guard let json = json as? [String: AnyObject] else { throw apiError("User parse error") } return try User(json: json) } else { return nil } } .asDriver(onErrorJustReturn: nil) } ྫɿϢʔβʔ৘ใ ɾཉ͍͠σʔλͷܕΛࢦఆ

Slide 20

Slide 20 text

੒ޭ͚ͨ࣌ͩ͠஋͕ཉ͍͠ func fetchUserInfo() -> Driver { return rx_responseJSON(.GET, endPoint: .Users) .map { success, json in if success { guard let json = json as? [String: AnyObject] else { throw apiError("User parse error") } return try User(json: json) } else { return nil } } .asDriver(onErrorJustReturn: nil) } ྫɿϢʔβʔ৘ใ ɾ੒ޭ࣌͸ཉ͍͠ܕͷσʔλΛฦ͢

Slide 21

Slide 21 text

੒ޭ͚ͨ࣌ͩ͠஋͕ཉ͍͠ func fetchUserInfo() -> Driver { return rx_responseJSON(.GET, endPoint: .Users) .map { success, json in if success { guard let json = json as? [String: AnyObject] else { throw apiError("User parse error") } return try User(json: json) } else { return nil } } .asDriver(onErrorJustReturn: nil) } ྫɿϢʔβʔ৘ใ ɾ0QUJPOBMʹͯ͠ɺࣦഊͳΒOJMΛฦ͢

Slide 22

Slide 22 text

੒ޭ͚ͨ࣌ͩ͠஋͕ཉ͍͠ api.fetchUserInfo() .driveNext { [unowned self] (user: User?) in self.user = user } .addDisposableTo(disposeBag) ྫɿϢʔβʔ৘ใ ɾ࢖͏ଆʢ6*7JFXªPOUSPMMFSʣ͸͜Μͳײ͡

Slide 23

Slide 23 text

"1*ͷύλʔϯ ੒ޭPSࣦഊ͚ͩΘ͔Ε͹͍͍ ੒ޭ͚ͨ࣌ͩ͠஋͕ཉ͍͠ ࣦഊ͚ͨ࣌ͩ͠Τϥʔ಺༰͕ཉ͍͠ ੒ޭͨ͠Β஋͕ɺࣦഊͨ͠ΒΤϥʔ಺༰͕ཉ͍͠

Slide 24

Slide 24 text

ࣦഊ͚ͨ࣌ͩ͠Τϥʔ಺༰͕ཉ͍͠ ྫɿϢʔβʔొ࿥ ɾϩάΠϯը໘ͱಉ͡γνϡΤʔγϣϯ ɾϩάΠϯ͢Δ͔৽نొ࿥͢Δ͔ΛλϒͰ੾Γସ͑Δ ɾ੒ޭͨ͠ΒϩάΠϯը໘Λดͯ͡ଓ͖ͷॲཧ ɾࣦഊͨ͠ΒԿ͕͔͋Μ͔ͷΤϥʔ಺༰Λදࣔ

Slide 25

Slide 25 text

ࣦഊ͚ͨ࣌ͩ͠Τϥʔ಺༰͕ཉ͍͠ func signUp(email: String, password: String, passwordConfirm: String, firstName: String, lastName: String) -> Driver<(Bool, [String])> { let params = [ "user[email]": email, "user[password]": password, "user[password_confirmation]": passwordConfirm, "user[first_name]": firstName, "user[last_name]": lastName ] return rx_responseJSON(.POST, endPoint: .Users, parameters: params) .map { success, json in return (success, parseJSON(json)) } .asDriver(onErrorJustReturn: (false, [])) } ྫɿϢʔβʔొ࿥

Slide 26

Slide 26 text

ࣦഊ͚ͨ࣌ͩ͠Τϥʔ಺༰͕ཉ͍͠ func signUp(email: String, password: String, passwordConfirm: String, firstName: String, lastName: String) -> Driver<(Bool, [String])> { let params = [ "user[email]": email, "user[password]": password, "user[password_confirmation]": passwordConfirm, "user[first_name]": firstName, "user[last_name]": lastName ] return rx_responseJSON(.POST, endPoint: .Users, parameters: params) .map { success, json in return (success, parseJSON(json)) } .asDriver(onErrorJustReturn: (false, [])) } ྫɿϢʔβʔొ࿥ ɾ੒ޭͨ͠ΒUSVF͚ͩฦͬͯ͘Ε͹͍͍

Slide 27

Slide 27 text

ࣦഊ͚ͨ࣌ͩ͠Τϥʔ಺༰͕ཉ͍͠ func signUp(email: String, password: String, passwordConfirm: String, firstName: String, lastName: String) -> Driver<(Bool, [String])> { let params = [ "user[email]": email, "user[password]": password, "user[password_confirmation]": passwordConfirm, "user[first_name]": firstName, "user[last_name]": lastName ] return rx_responseJSON(.POST, endPoint: .Users, parameters: params) .map { success, json in return (success, parseJSON(json)) } .asDriver(onErrorJustReturn: (false, [])) } ྫɿϢʔβʔొ࿥ ɾࣦഊͷ಺༰͸จࣈྻͷ഑ྻͰฦ͢ ɹˠϝʔϧΞυϨεΛೖྗ͍ͯͩ͘͠͞ ɹɹύεϫʔυΛೖྗ͍ͯͩ͘͠͞FUD

Slide 28

Slide 28 text

ࣦഊ͚ͨ࣌ͩ͠Τϥʔ಺༰͕ཉ͍͠ signupButton.rx_tap.asDriver() .withLatestFrom(input) .flatMapLatest { api.signUp($0.0, password: $0.1, passwordConfirm: $0.2, firstName: $0.3, lastName: $0.4) } .driveNext { [unowned self] success, errors in self.signupErrorLabel.hidden = success self.signupErrorLabel.text = errors.joinWithSeparator("\n") } .addDisposableTo(disposeBag) ྫɿϢʔβʔొ࿥ ɾ࢖͏ଆʢ6*7JFXªPOUSPMMFSʣ͸͜Μͳײ͡

Slide 29

Slide 29 text

"1*ͷύλʔϯ ੒ޭPSࣦഊ͚ͩΘ͔Ε͹͍͍ ੒ޭ͚ͨ࣌ͩ͠஋͕ཉ͍͠ ࣦഊ͚ͨ࣌ͩ͠Τϥʔ಺༰͕ཉ͍͠ ੒ޭͨ͠Β஋͕ɺࣦഊͨ͠ΒΤϥʔ಺༰͕ཉ͍͠

Slide 30

Slide 30 text

੒ޭͨ͠Β஋͕ɺࣦഊͨ͠ΒΤϥʔ಺༰͕ཉ͍͠ func hoge(fuga: String) -> Driver<(Piyo?, [String])> { let params = ["fuga": fuga] return rx_responseJSON(.POST, endPoint: .Hoge, parameters: params) .map { success, json in if success { return (Piyo.parseJSON(json), []) } else { return (nil, parseJSON(json)) } } .asDriver(onErrorJustReturn: (nil, [])) } ྫɿʁʁʁ

Slide 31

Slide 31 text

੒ޭͨ͠Β஋͕ɺࣦഊͨ͠ΒΤϥʔ಺༰͕ཉ͍͠ func hoge(fuga: String) -> Driver<(Piyo?, [String])> { let params = ["fuga": fuga] return rx_responseJSON(.POST, endPoint: .Hoge, parameters: params) .map { success, json in if success { return (Piyo.parseJSON(json), []) } else { return (nil, parseJSON(json)) } } .asDriver(onErrorJustReturn: (nil, [])) } ྫɿʁʁʁ ɾͱͷ૊Έ߹Θͤ

Slide 32

Slide 32 text

੒ޭͨ͠Β஋͕ɺࣦഊͨ͠ΒΤϥʔ಺༰͕ཉ͍͠ func hoge(fuga: String) -> Driver<(Piyo?, [String])> { let params = ["fuga": fuga] return rx_responseJSON(.POST, endPoint: .Hoge, parameters: params) .map { success, json in if success { return (Piyo.parseJSON(json), []) } else { return (nil, parseJSON(json)) } } .asDriver(onErrorJustReturn: (nil, [])) } ྫɿʁʁʁ ɾCPEZͷKTPO͸ɺ੒ޭͯͨ͠Βཉ͔ͬͨ͠஋

Slide 33

Slide 33 text

੒ޭͨ͠Β஋͕ɺࣦഊͨ͠ΒΤϥʔ಺༰͕ཉ͍͠ func hoge(fuga: String) -> Driver<(Piyo?, [String])> { let params = ["fuga": fuga] return rx_responseJSON(.POST, endPoint: .Hoge, parameters: params) .map { success, json in if success { return (Piyo.parseJSON(json), []) } else { return (nil, parseJSON(json)) } } .asDriver(onErrorJustReturn: (nil, [])) } ྫɿʁʁʁ ɾCPEZͷKTPO͸ɺࣦഊͯͨ͠ΒΤϥʔ಺༰

Slide 34

Slide 34 text

"1*ͷύλʔϯ ੒ޭPSࣦഊ͚ͩΘ͔Ε͹͍͍ ੒ޭ͚ͨ࣌ͩ͠஋͕ཉ͍͠ ࣦഊ͚ͨ࣌ͩ͠Τϥʔ಺༰͕ཉ͍͠ ੒ޭͨ͠Β஋͕ɺࣦഊͨ͠ΒΤϥʔ಺༰͕ཉ͍͠

Slide 35

Slide 35 text

೰ΈͲ͜Ζ ɾશ෦ʹ౷Ұͨ͠ํ͕͍͍ʁ ɹˠ౷Ұͨ͠ํ͕Θ͔Γ΍͍͢ʁ ɹɹ౷Ұͨ͠ΒδΣωϦΫεͰ៉ྷʹॻ͚Δ͔΋ʁ ɹɹͰ΋ඞཁ࠷௿ݶͷ৘ใ͚ͩฦͨ͠ํ͕࢖͍΍͍͢ʁ

Slide 36

Slide 36 text

·ͱΊ ɾ͋͘·Ͱ͜ͷΞϓϦ಺Ͱ༗ޮͳͭͷ੔ཧͷ࢓ํ ɾ͜ͷͭͷ෼ྨͰશ͕ͯ͏·͍͘͘Θ͚Ͱ͸ͳ͍͔΋ ɾ࢖͑ͦ͏ͳ࣌͸࢖ͬͯΈͯͶ

Slide 37

Slide 37 text

ࢀߟʹͳͬͨϖʔδ ɾʲ຋༁ʳ͋ͳ͕ͨٻΊ͍ͯͨϦΞΫςΟϒϓϩάϥϛϯάೖ໳ ɾຊՈͷ(FUUJOH4UBSUFE ɾຊՈͷ6OJUTϖʔδ ɾຊՈͷ3Y&YBNQMF ɾ3Yͷ)PUͱ$PMEʹ͍ͭͯ

Slide 38

Slide 38 text

࠷ޙʹ ͝ਗ਼ௌ͋Γ͕ͱ͏͍͟͝·ͨ͠ʂ