Slide 1

Slide 1 text

J04ΞϓϦΤϥʔ؂ࢹͷ
 ઃܭͱͦͷޮՌ

Slide 2

Slide 2 text

"CPVUNF

Slide 3

Slide 3 text

,VOJXBL גࣜձࣾ%JWFSTFͷJ04ςοΫϦʔυɻ
 ͱ͋ΔΞϓϦͷϦχϡʔΞϧϓϩδΣΫτʹ
 ్த͔ΒՃΘͬͨ΋ͷͷɺςετࠔ೉ͳઃܭΛ
 ໨ͷ౰ͨΓʹͨͨ͠ΊɺཪϦχϡʔΞϧΛ։࢝ɻ
 ࠷ऴతʹςετΛಋೖ͠ɺ։ൃ଎౓Λഒʹͨ͠ɻ झຯ͸5%%ɻ

Slide 4

Slide 4 text

Τϥʔ؂ࢹͱ͸

Slide 5

Slide 5 text

w ΞϓϦͰൃੜͨ͠ΤϥʔΛαʔόʹૹΔͳͲͯ͠
 Τϥʔͷൃੜ਺ͳͲΛ؂ࢹ͢Δٕज़ w ྫ͑͹ɺΞϓϦ͕Ϋϥογϡͨ͠ΒϨϙʔτΛ
 ඈ͹͢ΫϥογϡϨϙʔτ͸͜ͷҰछ w ΫϥογϡϨϙʔτղੳαʔϏεͰ͸
 $SBTIMZUJDT͕༗໊

Slide 6

Slide 6 text

Τϥʔͷൃੜ਺΍66 Τϥʔͷ*% ΤϥʔͷΧςΰϦ Τϥʔൃੜ਺ͷ࣌ؒతਪҠ Τϥʔൃੜ࣌ͷσόΠε Τϥʔൃੜ࣌ͷ04

Slide 7

Slide 7 text

w ࣮͸ɺଟ͘ͷΫϥογϡϨϙʔταʔϏε͸
 ΫϥογϡҎ֎ͷΤϥʔ΋؂ࢹͰ͖Δ w ྫ͑͹ɺ8FC"1*ݺͼग़࣌͠ͷΤϥʔ΍ɺ
 ಺෦ঢ়ଶͷෆ੔߹ͳͲͷΤϥʔ΋؂ࢹͰ͖Δ ૹ৴ͷ࢓ํ͸ޙͰ঺հ͠·͢

Slide 8

Slide 8 text

Τϥʔ؂ࢹͷಛੑ

Slide 9

Slide 9 text

w Τϥʔ؂ࢹͷಛੑ͸ҎԼͷͭɿ w ඇৗʹ޿ൣͳόάΛݕ஌Ͱ͖Δ w Τϯόά͔Βൃݟ·Ͱͷ͕࣌ؒ௕͍

Slide 10

Slide 10 text

ਤղ

Slide 11

Slide 11 text

όάΛݟ͚ͭΔͨΊͷखஈ ߏจϋΠϥΠτ Ϧϯτ ੩తܕݕࠪ ୯ମɾ݁߹ςετ 6*ςετ ςελʔʹΑΔಈ࡞֬ೝ Τϥʔ؂ࢹ Ϣʔβʔ͔Βͷ͓໰͍߹Θͤ

Slide 12

Slide 12 text

όά9Λݟ͚ͭΒΕΔ৔ॴ όά9 ߏจϋΠϥΠτ Ϧϯτ ੩తܕݕࠪ ୯ମɾ݁߹ςετ 6*ςετ ςελʔʹΑΔಈ࡞֬ೝ Τϥʔ؂ࢹ Ϣʔβʔ͔Βͷ͓໰͍߹Θͤ

Slide 13

Slide 13 text

όά9 ߏจϋΠϥΠτ Ϧϯτ ੩తܕݕࠪ ୯ମɾ݁߹ςετ 6*ςετ ςελʔʹΑΔಈ࡞֬ೝ Τϥʔ؂ࢹ Ϣʔβʔ͔Βͷ͓໰͍߹Θͤ ্ͷํͰࢭ·Δͱ ݪҼڀ໌ͷ͕࣌ؒ୹͍ όά: ಛघͳΤϥʔ͸ԼͷํͰ
 ͔͠ݟ͚ͭΒΕͳ͍

Slide 14

Slide 14 text

ߏจϋΠϥΠτ Ϧϯτ ੩తܕݕࠪ ୯ମɾ݁߹ςετ 6*ςετ ςελʔʹΑΔಈ࡞֬ೝ Τϥʔ؂ࢹ Ϣʔβʔ͔Βͷ͓໰͍߹Θͤ Τϥʔ؂ࢹ͸ಛघͳ
 ΤϥʔΛݟ͚ͭΒΕΔ
 ΄΅࠷ޙͷࡆ όά: ͔͠͠ɺ্ͷ૚ΑΓ΋
 Τϯόά͔Βൃݟ·Ͱͷ
 ͕࣌ؒͱͯ΋௕͍

Slide 15

Slide 15 text

Τϥʔ؂ࢹͰݟ͚ͭΔ΂͖
 Τϥʔͱ͸

Slide 16

Slide 16 text

ߏจϋΠϥΠτ Ϧϯτ ੩తܕݕࠪ ୯ମɾ݁߹ςετ 6*ςετ ςελʔʹΑΔಈ࡞֬ೝ Τϥʔ؂ࢹ Ϣʔβʔ͔Βͷ͓໰͍߹Θͤ ༧໿ޠλΠϙ ม਺໊λΠϙ ϓϩύςΟ໊
 λΠϙ ෼ذߟྀ࿙Ε ίϯϙʔωϯτ
 ࢓༷ͷෆ੔߹ ࢓༷΁ͷޡղ ಛघͳ؀ڥͰ͔͠
 ࠶ݱ͠ͳ͍Τϥʔ ҋ ཧ૝ͷόάݕ஌ͷ࢟

Slide 17

Slide 17 text

ߏจϋΠϥΠτ Ϧϯτ ੩తܕݕࠪ ୯ମɾ݁߹ςετ 6*ςετ ςελʔʹΑΔಈ࡞֬ೝ Τϥʔ؂ࢹ Ϣʔβʔ͔Βͷ͓໰͍߹Θͤ ༧໿ޠλΠϙ ม਺໊λΠϙ ϓϩύςΟ໊
 λΠϙ ෼ذߟྀ࿙Ε ίϯϙʔωϯτ
 ࢓༷ͷෆ੔߹ ࢓༷΁ͷޡղ ಛघͳ؀ڥͰ͔͠
 ࠶ݱ͠ͳ͍Τϥʔ ҋ όά͕Լͷ૚·Ͱ
 ಥ͖ൈ͚ͯ͠·͏ͷͰ
 ݪҼڀ໌ʹ͕͔͔࣌ؒΔ μϝͳόάݕ஌ͷ࢟

Slide 18

Slide 18 text

ߏจϋΠϥΠτ Ϧϯτ ੩తܕݕࠪ ୯ମɾ݁߹ςετ 6*ςετ ςελʔʹΑΔಈ࡞֬ೝ Τϥʔ؂ࢹ Ϣʔβʔ͔Βͷ͓໰͍߹Θͤ ༧໿ޠλΠϙ ม਺໊λΠϙ ϓϩύςΟ໊
 λΠϙ ෼ذߟྀ࿙Ε ίϯϙʔωϯτ
 ࢓༷ͷෆ੔߹ ࢓༷΁ͷޡղ ಛघͳ؀ڥͰ͔͠
 ࠶ݱ͠ͳ͍Τϥʔ ҋ ཧ૝ͷόάݕ஌ͷ࢟

Slide 19

Slide 19 text

ߏจϋΠϥΠτ Ϧϯτ ੩తܕݕࠪ ୯ମɾ݁߹ςετ 6*ςετ ςελʔʹΑΔಈ࡞֬ೝ Τϥʔ؂ࢹ Ϣʔβʔ͔Βͷ͓໰͍߹Θͤ ༧໿ޠλΠϙ ม਺໊λΠϙ ϓϩύςΟ໊
 λΠϙ ෼ذߟྀ࿙Ε ίϯϙʔωϯτ
 ࢓༷ͷෆ੔߹ ࢓༷΁ͷޡղ ಛघͳ؀ڥͰ͔͠
 ࠶ݱ͠ͳ͍Τϥʔ ҋ Τϥʔ؂ࢹͰݕ஌͢΂͖
 Τϥʔ͸͜ͷ͋ͨΓ

Slide 20

Slide 20 text

͜͜·Ͱͷ·ͱΊ w Τϥʔ؂ࢹ͸ಛघͳόάΛ
 ݕ஌͢ΔͨΊͷखஈ w ͳ͓ɺͦͷલͷखஈͰόάΛ
 ݟ͚ͭΒΕΔͳΒͦͷํ͕
 ݪҼڀ໌Λ଎͘Ͱ͖Δ

Slide 21

Slide 21 text

Τϥʔ؂ࢹͷ࣮૷ํ๏

Slide 22

Slide 22 text

Τϥʔ؂ࢹαʔϏεͷ"1*Λ೺Ѳ͢Δ ΤϥʔϨϙʔλʔΛΧελϚΠζ͢Δ ΤϥʔϨϙʔλʔΛ૊ΈࠐΉ

Slide 23

Slide 23 text

Τϥʔ؂ࢹαʔϏεͷ
 "1*Λ೺Ѳ͢Δ

Slide 24

Slide 24 text

Crashlytics.sharedInstance().recordError(error) $SBTIMZUJDTʹΤϥʔΛૹ৴͢Δίʔυ &SSPSͰ͸ͳ͘/4&SSPSͳͷͰ஫ҙ

Slide 25

Slide 25 text

ΤϥʔϨϙʔλʔΛ
 ΧελϚΠζ͢Δ

Slide 26

Slide 26 text

౎౓/4&SSPSʹม׵͢Δͷ͸
 ໘౗ͳͷͰɺ4XJGUͷ&SSPSΛ
 /4&SSPS΁͍͍ײ͡ʹ
 ม׵ͯ͘͠ΕΔϥούʔΛॻ͘ $SBTIMZUJDTͷ৔߹

Slide 27

Slide 27 text

class CrashlyticsErrorReporter { private let crashlytics = Crashlytics.sharedInstance() func report(error: Error, from reporter: Any) { #if DEBUG let prefix = "DEBUG " #else let prefix = "" #endif let detailedError = NSError( domain: "\(prefix)\(type(of: reporter))", code: CrashlyticsErrorTracker.getNSErrorCode(bySwiftError: error), userInfo: [ NSLocalizedDescriptionKey: "\(error)", ] ) self.crashlytics.recordError(detailedError) } private static func getNSErrorCode(bySwiftError error: Error) -> Int { let bridgedError = error as NSError return bridgedError.code } } %(ϏϧυΛ۠ผͰ͖ΔΑ͏ʹ͓ͯ͘͠ͱ
 ຊ൪؀ڥͱ։ൃ؀ڥΛ۠ผ͠΍͘͢ͳΔ ΤϥʔϨϙʔλʔʹͲͷΑ͏ʹ
 ूܭ͞ΕΔ͔Λҙࣝ͢Δ ྫ͑͹ɺ$SBTIMZUJDT͸/4&SSPSͷ
 EPNBJOͱDPEFͷ૊ͰΤϥʔΛ
 άϧʔϐϯά͢ΔͷͰɺͦΕͧΕ
 Τϥʔ*%ͱൃੜݩΛࢦఆ͢Δͱ
 ៉ྷʹΤϥʔ͕·ͱ·Δ Τϥʔͷશจ͸άϧʔϐϯάʹ࢖Θͳ͍Α͏ʹ͢Δ
 ʢϢʔβʔ*%ͱ͔͕ೖΔͱݸผͷΤϥʔʹͳͬͯ
 ૯਺Λ೺ѲͰ͖ͳ͘ͳΔͷͰʣ $SBTIMZUJDT༻ͷΤϥʔϨϙʔλʔΛ࡞੒ SFQPSUؔ਺ΛݺͿͱΤϥʔϨϙʔτ͕
 ૹ৴͞ΕΔΑ͏ʹ࣮૷͍ͯ͠Δ ΤϥʔͱҰॹʹൃੜݩ͕
 Θ͔ΔΑ͏ʹ͓ͯ͘͠ͱ
 ݪҼͷݟ౰͕͖ͭ΍͘͢ͳΔ

Slide 28

Slide 28 text

ΤϥʔϨϙʔλʔΛ
 ૊ΈࠐΉ

Slide 29

Slide 29 text

Α͘ΈΔ૊ΈࠐΈํ๏

Slide 30

Slide 30 text

class UserApiRepository: UserRepositoryProtocol { private let api: GitHubApiClientProtocol func get(by id: GitHubUser.Id) -> Promise { return self.api .fetch( endpoint: GitHubApiEndpoint(path: "/user/" + id.text), headers: [:], parameters: [] ) .then { data -> GitHubUser in let response: GitHubUserResponse = try unbox(data: data) return response.user } .catch { error in ErrorReporter.shared.report( error: error, reporter: self ) } } } Τϥʔ͕ฦ͖ͬͯͨΒ
 ΤϥʔϨϙʔτΛૹ৴
 ʢͭ·Γϋʔυίʔυʣ "1*ݺͼग़͠ͷίʔυ

Slide 31

Slide 31 text

w ͔͠͠ϋʔυίʔυʹ͸໰୊͕ଟ͍ɿ w "1*ͷݺͼग़͠ʹؔ܎ͷͳ͍ίʔυ͕ೖΔͨΊ
 ୯Ұ੹຿ݪଇʹҧ൓͢Δ w ୯ମςετͰΤϥʔϨϙʔτ͕ૹΒΕͯ͠·͏ w ςετ͚࣌ͩ༗ޮͳϑϥάΛ௥Ճͯ͠
 ΤϥʔϨϙʔτΛૹ৴͠ͳ͍Α͏ʹ
 Ͱ͖ͳ͘͸ͳ͍͕΍Γͨ͘ͳ͍

Slide 32

Slide 32 text

ͦ͜Ͱ0CTFSWFSύλʔϯ

Slide 33

Slide 33 text

w 0CTFSWFSύλʔϯͰ͸ɺ؂ࢹऀ͕؂ࢹର৅ͷ
 ঢ়ଶมԽΛ࡯஌ͯ͠ಈ࡞͢Δ w ΤϥʔϨϙʔτʹԠ༻͢Δͱɿ w ؂ࢹऀ͸ΤϥʔϨϙʔλʔ w ؂ࢹର৅͸Τϥʔ͕ൃੜ͠͏ΔΦϒδΣΫτ w 0CTFSWFSύλʔϯΛ࢖͑͹ϋʔυίʔυͷ
 ໰୊఺ΛղফͰ͖Δ

Slide 34

Slide 34 text

Τϥʔͷൃੜݯ Τϥʔ͕ൃੜ͠·ͨ͠ ΤϥʔϨϙʔλʔ ؂ࢹ

Slide 35

Slide 35 text

Τϥʔͷൃੜݯ ΤϥʔϨϙʔλʔ ؂ࢹ Τϥʔ͕ى͖ͨͷͰ
 ΤϥʔϨϙʔτΛ
 ૹ৴͠·͢

Slide 36

Slide 36 text

Τϥʔͷൃੜݯ ΤϥʔϨϙʔλʔ ΤϥʔϨϙʔτૹ৴
 ͷ੹຿ Τϥʔ͕ى͜Γ͏Δ
 ॲཧͷ੹຿

Slide 37

Slide 37 text

Τϥʔͷൃੜݯ ΤϥʔϨϙʔλʔ ςετͷͱ͖͸
 ΤϥʔϨϙʔλʔ
 ΛऔΓ෇͚ͳ͍

Slide 38

Slide 38 text

w ͨͩ͠ɺ0CTFSWFSύλʔϯΛ࢖͑Δ৔ॴ͸
 ݶΒΕ͍ͯΔ w ؂ࢹର৅͕؂ࢹՄೳͳΠϯλʔϑΣʔεΛ
 උ͍͑ͯͳ͍ͱ͍͚ͳ͍ͨΊ w .7ΞʔΩςΫνϟͳΒɺ.PEFM͸؂ࢹՄೳͳ
 ΠϯλʔϑΣʔεΛ͍࣋ͬͯΔ͸ͣͳͷͰɺ.PEFMʹ
 ΤϥʔϨϙʔλʔΛ૊ΈࠐΈ΍͍͢͸ͣ w 'MVYΞʔΩςΫνϟͷ৔߹͸4UPSF͕؂ࢹՄೳͳ
 ΠϯλʔϑΣʔεΛ͍࣋ͬͯΔ͸ͣ

Slide 39

Slide 39 text

.PEFM 7JFX &SSPS3FQPSUFS ؂ࢹ ؂ࢹ Τϥʔ͕ൃੜ͠·ͨ͠

Slide 40

Slide 40 text

.PEFM 7JFX &SSPS3FQPSUFS ؂ࢹ ؂ࢹ ΤϥʔΛදࣔ͠·͢ ΤϥʔϨϙʔτΛ
 ૹ৴͠·͢

Slide 41

Slide 41 text

func fetch() { switch self.currentState { case .fetching: return case .fetched: self.stateMachine.transit(to: .fetching) self.repository.get(by: self.id) .then { user in self.stateMachine.transit(to: .fetched( result: .success(user) )) } .catch { error in self.stateMachine.transit(to: .fetched( result: .failure(.unspecified(debugInfo: "\(error) )) } } } ͜ͷ.PEFM͸"1*ݺͼग़͕͠Τϥʔʹ
 ͳͬͨΒΤϥʔঢ়ଶ΁มԽ͢Δ ͦͷͨΊɺΤϥʔϨϙʔλʔ͔Β؂ࢹ͠΍͍͢ .PEFM૚ͷ"1*ݺͼग़͠ͷίʔυ ͜ͷΑ͏ͳ.PEFM૚ͷઃܭͷৄࡉ͸IUUQTHPPHM1G'+-Λࢀর͍ͯͩ͘͠͞

Slide 42

Slide 42 text

class UserModelErrorReporter { private let model: UserModelProtocol private let errorReporter: ErrorReporterProtocol private let disposeBag = RxSwift.DisposeBag() init( observing model: UserModelProtocol, reportingBy errorReporter: ErrorReporterProtocol ) { self.model = model self.errorReporter = errorReporter self.model.didChange .subscribe(onNext: { [weak self] (state: UserModelState) in guard let `self` = self else { return } switch state { case let .fetched(result: .failure(error)): self.errorReporter.report(error: error, reporter: self) default: return } }) .disposed(by: disposeBag) } } .PEFM͕Τϥʔঢ়ଶʹͳͬͨΒ
 ΤϥʔϨϙʔτΛૹ৴ .PEFMͷঢ়ଶભҠΛ؂ࢹ .PEFMΛ؂ࢹ͢ΔΤϥʔϨϙʔλʔΛ࡞੒

Slide 43

Slide 43 text

͜͜·Ͱͷ·ͱΊ w Τϥʔ؂ࢹͷ࣮૷ํ๏ʹ͸
 0CTFSWFSύλʔϯ͕ద͍ͯ͠Δ w .PEFM΍4UPSFΛ؂ࢹ͢ΔͱΑ͍

Slide 44

Slide 44 text

Τϥʔ؂ࢹͷίπ

Slide 45

Slide 45 text

Τϥʔ؂ࢹΛ։࢝͢Δͱ
 ࠔౕ͕ͬͨͪΐͪ͘ΐ͘ग़ͯ͘Δ

Slide 46

Slide 46 text

Fatal Exception: SomethingError *** nil ৘ใྔ͕΄ͱΜͲͳ͍ʂ

Slide 47

Slide 47 text

Τϥʔʹ͸ͳΔ΂͘
 ΫϦςΟΧϧͳ৘ใΛ٧ΊΑ͏

Slide 48

Slide 48 text

func example(input: String) -> String? { guard validate1(input) else { return nil } guard validate2(input) else { return nil } guard validate3(input) else { return nil } return "OK! Hello \(input)" } ݪҼڀ໌Λ஗͘͢Δѱ͍ྫ ࣦഊͨ͠ݪҼ͕۠ผͰ͖ͳ͍

Slide 49

Slide 49 text

enum ExampleError: Error { case validate1(debugInfo: String) case validate2(debugInfo: String) case validate3(debugInfo: String) } ͦ͏͍͏࣌͸FOVNͰΤϥʔΛ۠ผͰ͖ΔΑ͏ʹ͢Δ

Slide 50

Slide 50 text

func example(input: String) -> Result { guard validate1(input) else { return .failure(.validate1(debugInfo: input)) } guard validate2(input) else { return .failure(.validate2(debugInfo: input)) } guard validate3(input) else { return .failure(.validate3(debugInfo: input)) } return .success("OK! Hello \(input)") } ΤϥʔΛ۠ผ͠΍͍͢Α͍ྫ ࣦഊͨ͠ݪҼ͕۠ผͰ͖Δ ࣦഊͨ͠ࡍͷೖྗ΋ೖखͰ͖Δ

Slide 51

Slide 51 text

Τϥʔ؂ࢹͷ݁Ռ

Slide 52

Slide 52 text

w ϢʔβʔͷखݩͰൃੜ͍ͯ͠Δόάͷछྨ΍
 ن໛Λ೺ѲͰ͖ΔΑ͏ʹͳͬͨ w छྨ΍ن໛͕೺ѲͰ͖ΔΑ͏ʹͳΔͱɺόάमਖ਼ͷ
 τϦΞʔδΛ΍Γ΍͘͢ͳΔ w ՝ۚܥ͸࠷༏ઌͱ͔ɺΤϥʔ਺ͷଟ͍΋ͷ
 ͔ΒରॲͳͲ

Slide 53

Slide 53 text

w ϢʔβʔͷखݩͰ͸༧૝֎ͷΤϥʔ͕ى͍ͬͯͨ͜ w ςελʔʹΑΔಈ࡞֬ೝͱ͸؀ڥ͕
 ҟͳ͍ͬͯͨͨΊɺൃݟͰ͖ͳ͔ͬͨΑ͏ͩ w ໘ന͍͜ͱʹɺ"QQMFͷϨϏϡʔΞ͕ૺ۰ͨ͠
 όάͷݪҼڀ໌ʹ΋໾ཱͬͨ w 4BOECPYͷϨγʔτ͡Όͳ͍ͱ࠶ݱ͠ͳ͍
 όάͩͬͨ

Slide 54

Slide 54 text

w خ͍͠෭࡞༻ͱͯ͠ɺςελʔͷૺ۰ͨ͠όάͷ
 ৄࡉ͕ೖखͰ͖ΔΑ͏ʹͳͬͨ w ςελʔͷಈ࡞֬ೝதʹΤϥʔϨϙʔτ͕
 ඈΜͰ͘ΔͨΊʢ%(ϏϧυͳͷͰ͙͢Θ͔Δʣ w σόοά͕͍͢͝ḿΓ·͢

Slide 55

Slide 55 text

·ͱΊ w Τϥʔ؂ࢹʹΑΓɺςελʔʹΑΔಈ࡞֬ೝͰ΋
 ݟ͚ͭΒΕͳ͔ͬͨΤϥʔΛൃݟͰ͖ΔΑ͏ʹ
 ͳͬͨ w ઃܭͷίπ͸ҎԼͷͭɿ w 0CTFSWFSύλʔϯΛ࢖͏ w ͳΔ΂͘Τϥʔ৘ใΛΘ͔Γ΍͘͢͢Δ

Slide 56

Slide 56 text

એ఻ w %JWFSTFͰ͸৽نࣄۀͷJ04։ൃνʔϜͷ
 νʔϜϦʔμʔΛืू͍ͯ͠·͢ʂ w ੒௕தͷαʔϏεΛࣗ෼ͷྗͰಋ͍ͯΈ͍ͨͱ
 ࢥ͏ํʹɺͥͻ͖ͯ΄͍͠ͱࢥ͍ͬͯ·͢ʂ w ͝ڵຯ͕͋Γ·ͨ͠ΒɺҰॹʹϥϯνʹ
 ߦ͖·ͤΜ͔ʁ