Slide 1

Slide 1 text

$"TXJGU ,PLJ)JSPLBXB "#&."ͷϦΞʔΩςΫνϟ

Slide 2

Slide 2 text

ΞδΣϯμ എܠ ߏ੒ͱ࣮૷ ·ͱΊ

Slide 3

Slide 3 text

,PLJ)JSPLBXB ೥౓৽ଔೖࣾJ04ΤϯδχΞ גࣜձࣾ"CFNB57/BUJWFνʔϜ !QJIFSP ,PLJ)JSPLBXB

Slide 4

Slide 4 text

ΞδΣϯμ ߏ੒ͱ࣮૷ ·ͱΊ എܠ

Slide 5

Slide 5 text

ΞδΣϯμ w ԿނϦΞʔΩςΫνϟΛ͢Δ͜ͱʹͨ͠ͷ͔ʁ w Ϟνϕʔγϣϯ w ՝୊ ߏ੒ͱ࣮૷ ·ͱΊ എܠ

Slide 6

Slide 6 text

Ϟνϕʔγϣϯ w ೥݄ɺ"OESPJEνʔϜͱJ04νʔϜ͕౷߹͞Ε/BUJWFνʔϜʹͳͬͨ

Slide 7

Slide 7 text

Ϟνϕʔγϣϯ w ೥݄ɺ"OESPJEνʔϜͱJ04νʔϜ͕౷߹͞Ε/BUJWFνʔϜʹͳͬͨ w ֤ϓϥοτϑΥʔϜΛ၆ᛌͯ͠։ൃͰ͖ΔΤϯδχΞνʔϜΛ໨ࢦ͢

Slide 8

Slide 8 text

Ϟνϕʔγϣϯ w ೥݄ɺ"OESPJEνʔϜͱJ04νʔϜ͕౷߹͞Ε/BUJWFνʔϜʹͳͬͨ w ֤ϓϥοτϑΥʔϜΛ၆ᛌͯ͠։ൃͰ͖ΔΤϯδχΞνʔϜΛ໨ࢦ͢ w ಉ͡ωΠςΟϒΞϓϦͱͯ͠ڞ௨͢Δ࢓༷͕ଟ͍ w "#&."ͱͯ͠ϓϥοτϑΥʔϜͷҧ͍ʹΑΔ࢓༷ࠩҟ΍αʔϏε඼࣭ͷࠩ Λͳ͘͢

Slide 9

Slide 9 text

Ϟνϕʔγϣϯ w ೥݄ɺ"OESPJEνʔϜͱJ04νʔϜ͕౷߹͞Ε/BUJWFνʔϜʹͳͬͨ w ֤ϓϥοτϑΥʔϜΛ၆ᛌͯ͠։ൃͰ͖ΔΤϯδχΞνʔϜΛ໨ࢦ͢ w ಉ͡ωΠςΟϒΞϓϦͱͯ͠ڞ௨͢Δ࢓༷͕ଟ͍ w "#&."ͱͯ͠ϓϥοτϑΥʔϜͷҧ͍ʹΑΔ࢓༷ࠩҟ΍αʔϏε඼࣭ͷࠩ Λͳ͘͢ ▶︎ ڞ௨Խ͢΂͖࢓༷Λɺ࣮૷ͷதͰ໌֬Խ͍ͨ͠

Slide 10

Slide 10 text

Ϟνϕʔγϣϯ J04 "OESPJE w ڞ௨ͷ࢓༷ͱ͸ʁ

Slide 11

Slide 11 text

Ϟνϕʔγϣϯ w ڞ௨ͷ࢓༷ͱ͸ʁ w υϝΠϯϞσϧ w αʔϏεશମͰڞ௨

Slide 12

Slide 12 text

Ϟνϕʔγϣϯ w ڞ௨ͷ࢓༷ͱ͸ʁ w υϝΠϯϞσϧ w αʔϏεશମͰڞ௨ w Ϣʔεέʔε w ಉ͡ωΠςΟϒΞϓϦͳΒۙ͘͠ͳΔ͸ͣ

Slide 13

Slide 13 text

Ϟνϕʔγϣϯ w ڞ௨ͷ࢓༷ͱ͸ʁ w υϝΠϯϞσϧ w αʔϏεશମͰڞ௨ w Ϣʔεέʔε w ಉ͡ωΠςΟϒΞϓϦͳΒۙ͘͠ͳΔ͸ͣ ▶︎ ڞ௨Խ͢΂͖࢓༷Λɺ࣮૷ͷதͰ໌֬Խ͍ͨ͠

Slide 14

Slide 14 text

Ϟνϕʔγϣϯ w ڞ௨ͷ࢓༷ͱ͸ʁ w υϝΠϯϞσϧ w αʔϏεશମͰڞ௨ w Ϣʔεέʔε w ಉ͡ωΠςΟϒΞϓϦͳΒۙ͘͠ͳΔ͸ͣ ▶︎ υϝΠϯϞσϧͱϢʔεέʔεΛຬ࣮ͨ͢૷Λɺ໌֬Խ͍ͨ͠

Slide 15

Slide 15 text

՝୊ w ڞ௨ͷ࢓༷Λຬͨ͢ϩδοΫ͸ɺͦΕҎ֎ͷϩδοΫ͔Β෼཭͞Ε͍͔ͯͨʁ

Slide 16

Slide 16 text

՝୊ w ڞ௨ͷ࢓༷Λຬͨ͢ϩδοΫ͸ɺͦΕҎ֎ͷϩδοΫ͔Β෼཭͞Ε͍͔ͯͨʁ w ͞Ε͍ͯͳ͔ͬͨ

Slide 17

Slide 17 text

՝୊ w ͍··ͰͷJ04ΞϓϦͷઃܭ w .77.'MVY 7JFX 7JFX4USFBN 7JFX 7JFX4USFBN "DUJPO %JTQBUDIFS 4UPSF

Slide 18

Slide 18 text

՝୊ w .77.'MVY w 7JFX4USFBN w ը໘Ͱऩ·Δσʔλͷ؅ཧ 7JFX 7JFX4USFBN 7JFX 7JFX4USFBN "DUJPO %JTQBUDIFS 4UPSF

Slide 19

Slide 19 text

՝୊ w .77.'MVY w 7JFX4USFBN w ը໘Ͱऩ·Δσʔλͷ؅ཧ 7JFX 7JFX4USFBN 7JFX 7JFX4USFBN "DUJPO %JTQBUDIFS 4UPSF 7JFX 7JFX4USFBN 7JFX 7JFX4USFBN "DUJPO %JTQBUDIFS 4UPSF w .77.'MVY w 7JFX4USFBN w ը໘Ͱऩ·Δσʔλͷ؅ཧ w 'MVY w ը໘είʔϓΛ௒͑Δσʔλ w ΞϓϦશମͰ࢖༻͢Δσʔλ

Slide 20

Slide 20 text

՝୊ w .77.'MVYͱ͍͏ઃܭ͸͋ͬͨ΋ͷͷʜ

Slide 21

Slide 21 text

՝୊ w .77.'MVYͱ͍͏ઃܭ͸͋ͬͨ΋ͷͷʜ w Ϣʔεέʔε΍υϝΠϯϞσϧΛຬͨ͢ϩδοΫ͕ɺ7JFX4USFBNʹ΋'MVY ʹ΋ؚ·Ε͍ͯͨ w 7JFX4USFBNͷதͰ΋ɺϓϨθϯςʔγϣϯϩδοΫ΍ΞϓϦέʔγϣϯϩ δοΫɺυϝΠϯϩδοΫ͕໌֬ʹ෼཭͞Ε͍ͯͳ͔ͬͨ

Slide 22

Slide 22 text

՝୊ w .77.'MVYͱ͍͏ઃܭ͸͋ͬͨ΋ͷͷʜ w 7JFX4USFBNͱ'MVYͷ੹຿͕ᐆດͰɺڞ௨ͷ࢓༷͕ෆ໌֬ w ࢓༷Λ೺Ѳ͢ΔͨΊʹ͸ɺؾ߹͍ͰίʔυΛಡΉඞཁ͕͋Δ

Slide 23

Slide 23 text

՝୊ w .77.'MVYͱ͍͏ઃܭ͸͋ͬͨ΋ͷͷʜ w 7JFX4USFBNͱ'MVYͷ੹຿͕ᐆດͰɺڞ௨ͷ࢓༷͕ෆ໌֬ w ࢓༷Λ೺Ѳ͢ΔͨΊʹ͸ɺؾ߹͍ͰίʔυΛಡΉඞཁ͕͋Δ ▶︎ ڞ௨Խ͢΂͖࢓༷Λ໌֬ʹ͢ΔͨΊͷઃܭΛݕ౼

Slide 24

Slide 24 text

ํ਑ w υϝΠϯϞσϧͱϢʔεέʔεͷ໌֬Խ w কདྷతͳมߋͷॊೈੑ w 7JFX࣮૷ͷมߋɺ"1*௨৴ϓϩτίϧͷมߋͳͲ

Slide 25

Slide 25 text

ํ਑ w υϝΠϯϞσϧͱϢʔεέʔεͷ໌֬Խ w কདྷతͳมߋͷॊೈੑ w 7JFX࣮૷ͷมߋɺ"1*௨৴ϓϩτίϧͷมߋͳͲ ▶︎ $MFBO"SDIJUFDUVSFΛϕʔεʹͨ͠ΞʔΩςΫνϟ

Slide 26

Slide 26 text

ΞδΣϯμ ߏ੒ͱ࣮૷ എܠ ·ͱΊ

Slide 27

Slide 27 text

ΞδΣϯμ ߏ੒ͱ࣮૷ എܠ ·ͱΊ w Ϟδϡʔϧͷ෼͚ํ͸Ͳ͏ͯ͠Δͷʁ w ࣮૷͸ͲΜͳײ͡ʁ

Slide 28

Slide 28 text

Ϟδϡʔϧߏ੒ 3FQPTJUPSZ 6TF$BTF 6TF$BTF*OUFSGBDF 6*-PHJD*OUFSGBDF 6*$PNQPOFOU %PNBJO 6*-PHJD "QQ

Slide 29

Slide 29 text

Ϟδϡʔϧߏ੒ 3FQPTJUPSZ 6TF$BTF 6TF$BTF*OUFSGBDF 6*-PHJD*OUFSGBDF 6*$PNQPOFOU %PNBJO 6*-PHJD "QQ w ϓϥοτϑΥʔϜʹґଘ͠ͳ͍ 
 ڞ௨Խ͞ΕͨυϝΠϯϞσϧ w 3FQPTJUPSZͷΠϯλʔϑΣʔε

Slide 30

Slide 30 text

Ϟδϡʔϧߏ੒ 3FQPTJUPSZ 6TF$BTF 6TF$BTF*OUFSGBDF 6*-PHJD*OUFSGBDF 6*$PNQPOFOU %PNBJO 6*-PHJD "QQ w ϓϥοτϑΥʔϜຖʹҟͳΔΞϓϦέʔγϣϯ ϩδοΫ w υϝΠϯϞσϧΛ༻͍ͯɺΞϓϦͷ࢓༷Λ࣮૷ ͢Δ w Ϣʔεέʔε͸ଞͷϢʔεέʔεΛݺ͹ͳ͍

Slide 31

Slide 31 text

Ϟδϡʔϧߏ੒ 3FQPTJUPSZ 6TF$BTF 6TF$BTF*OUFSGBDF 6*-PHJD*OUFSGBDF 6*$PNQPOFOU %PNBJO 6*-PHJD "QQ w 6TF$BTFͷΠϯλʔϑΣʔε w 6*-PHJDͱ΍ΓͱΓ͢ΔͨΊͷ%50 w ϓϥοτϑΥʔϜຖʹҟͳΔΞϓϦέʔγϣϯ ϩδοΫ w υϝΠϯϞσϧΛ༻͍ͯɺΞϓϦͷ࢓༷Λ࣮૷ ͢Δ w Ϣʔεέʔε͸ଞͷϢʔεέʔεΛݺ͹ͳ͍

Slide 32

Slide 32 text

Ϟδϡʔϧߏ੒ 3FQPTJUPSZ 6TF$BTF 6TF$BTF*OUFSGBDF 6*-PHJD*OUFSGBDF 6*$PNQPOFOU %PNBJO 6*-PHJD "QQ w 7JFX4USFBN w ԿΛը໘ʹදࣔ͢Δ͔ɺΛႊΊΔ

Slide 33

Slide 33 text

Ϟδϡʔϧߏ੒ 3FQPTJUPSZ 6TF$BTF 6TF$BTF*OUFSGBDF 6*-PHJD*OUFSGBDF 6*$PNQPOFOU %PNBJO 6*-PHJD "QQ w 7JFX4USFBNͷΠϯλʔϑΣʔε w *OQVUʢ7JFX͔ΒͷΠϕϯτʣ w 0VUQVUʢ7JFX΁൓ө͢Δσʔλʣ w 6*$PNQPOFOUͱ΍ΓͱΓ͢ΔͨΊͷ%50 w 7JFX4USFBN w ԿΛը໘ʹදࣔ͢Δ͔ɺΛႊΊΔ

Slide 34

Slide 34 text

Ϟδϡʔϧߏ੒ 3FQPTJUPSZ 6TF$BTF 6TF$BTF*OUFSGBDF 6*-PHJD*OUFSGBDF 6*$PNQPOFOU %PNBJO 6*-PHJD "QQ w ϢʔβΠϯλʔϑΣʔε w 6*7JFX$POUSPMMFS 6*7JFXͳͲ

Slide 35

Slide 35 text

Ϟδϡʔϧߏ੒ 3FQPTJUPSZ 6TF$BTF 6TF$BTF*OUFSGBDF 6*-PHJD*OUFSGBDF 6*$PNQPOFOU %PNBJO 6*-PHJD "QQ w υϝΠϯϞσϧͷӬଓԽ w αʔό΍ϩʔΧϧετϨʔδ͔ΒσʔλΛऔಘ͠ɺ υϝΠϯϞσϧ΁ม׵

Slide 36

Slide 36 text

Ϟδϡʔϧߏ੒ 3FQPTJUPSZ 6TF$BTF 6TF$BTF*OUFSGBDF 6*-PHJD*OUFSGBDF 6*$PNQPOFOU %PNBJO 6*-PHJD "QQ w "QQ5BSHFU w ͢΂ͯͷίϯϙʔωϯτʹґଘ͠ɺ֤ίϯϙʔωϯτͷ Πϯελϯεੜ੒΍%FQFOEFODZ*OKFDUJPOΛߦ͏ɻ

Slide 37

Slide 37 text

࣮૷ྫΛݟ͍͖ͯ·͠ΐ͏

Slide 38

Slide 38 text

w 570%ͷϨϯλϧ֬ೝը໘

Slide 39

Slide 39 text

w 570%ͷϨϯλϧ֬ೝը໘ w Ϣʔεέʔε w ʮϨϯλϧ঎඼ΛҰཡදࣔ͢Δʯ

Slide 40

Slide 40 text

w 570%ͷϨϯλϧ֬ೝը໘ w Ϣʔεέʔε w ʮϨϯλϧ঎඼ΛҰཡදࣔ͢Δʯ

Slide 41

Slide 41 text

%PNBJO struct RentalSalesItem { let id: ID let title: String let startAt: Date let endAt: Date let price: Int func isOnSale(date: Date) -> Bool { startAt..

Slide 42

Slide 42 text

%PNBJO struct RentalSalesItem { let id: ID let title: String let startAt: Date let endAt: Date let price: Int func isOnSale(date: Date) -> Bool { startAt..

Slide 43

Slide 43 text

3FQPTJUPSZ*OUFSGBDF protocol RentalSalesItemRepositoryType: AnyObject { func fetchRentalSalesItems(programID: Program.ID) -> RxSwift.Single<[RentalSalesItem]> }

Slide 44

Slide 44 text

3FQPTJUPSZ*OUFSGBDF protocol RentalSalesItemRepositoryType: AnyObject { func fetchRentalSalesItems(programID: Program.ID) -> RxSwift.Single<[RentalSalesItem]> } w 3FQPTJUPSZ͸υϝΠϯϞσϧͷӬଓԽΛߦ͏ w QSPHSBN*%Λड͚औΓɺ3FOUBM4BMFT*UFNͷ഑ྻΛฦ͢ w σʔλͷऔಘ͕ͲͷΑ͏ʹߦΘΕΔ͔͸෼͔Βͳ͍

Slide 45

Slide 45 text

3FQPTJUPSZ class RentalSalesItemRepository: RentalSalesItemRepositoryType { func fetchRentalSalesItems(programID: Program.ID) -> RxSwift.Single<[RentalSalesItem]> { let request = ApiSession.Rental_SalesItemsRequest(programID: programID.rawValue) return apiSession.send(request) .map { response in response.items.map(RentalSalesItem.init) } } }

Slide 46

Slide 46 text

3FQPTJUPSZ class RentalSalesItemRepository: RentalSalesItemRepositoryType { func fetchRentalSalesItems(programID: Program.ID) -> RxSwift.Single<[RentalSalesItem]> { let request = ApiSession.Rental_SalesItemsRequest(programID: programID.rawValue) return apiSession.send(request) .map { response in response.items.map(RentalSalesItem.init) } } } w ϦΫΤετͷ࡞੒ w "1*4FTTJPOΛར༻ͨ͠σʔλͷऔಘ

Slide 47

Slide 47 text

3FQPTJUPSZ class RentalSalesItemRepository: RentalSalesItemRepositoryType { func fetchRentalSalesItems(programID: Program.ID) -> RxSwift.Single<[RentalSalesItem]> { let request = ApiSession.Rental_SalesItemsRequest(programID: programID.rawValue) return apiSession.send(request) .map { response in response.items.map(RentalSalesItem.init) } } } w औಘͨ͠σʔλΛυϝΠϯϞσϧ΁ม׵

Slide 48

Slide 48 text

3FQPTJUPSZ extension RentalSalesItem { init(response: Rental_SalesItem) { let startAt = Date(timeIntervalSince1970: TimeInterval(response.startAt)) let endAt = Date(timeIntervalSince1970: TimeInterval(response.endAt)) return RentalSalesItem( id: response.id, title: response.title, startAt: startAt, endAt: endAt, price: response.price ) } } w Ϩεϙϯε͔ΒυϝΠϯϞσϧΛੜ੒͢Δॲཧ͸ɺ3FQPTJUPSZ಺Ͱߦ͏ w %PNBJO͸֎෦ʹґଘ͠ͳ͍ͨΊ

Slide 49

Slide 49 text

6TF$BTF*OUFSGBDF protocol RentalConfirmUseCaseType: AnyObject { typealias UseCaseModel = RentalConfirmUseCaseModel func listSalesItems(programID: String, date: Date) -> RxSwift.Single }

Slide 50

Slide 50 text

6TF$BTF*OUFSGBDF protocol RentalConfirmUseCaseType: AnyObject { typealias UseCaseModel = RentalConfirmUseCaseModel func listSalesItems(programID: String, date: Date) -> RxSwift.Single } w ʮϨϯλϧ঎඼ΛҰཡදࣔ͢ΔʯϢʔεέʔε w ϢʔεέʔεΛදݱ͢Δϝιου໊

Slide 51

Slide 51 text

6TF$BTF*OUFSGBDF protocol RentalConfirmUseCaseType: AnyObject { typealias UseCaseModel = RentalConfirmUseCaseModel func listSalesItems(programID: String, date: Date) -> RxSwift.Single } w 6*-PHJDͱ΍ΓͱΓ͢ΔͨΊͷ%50 w %PNBJOʹґଘͤ͞ͳ͍ͨΊ%PNBJO3FOUBM4BMFT*UFN͸௚઀ฦ͞ͳ͍

Slide 52

Slide 52 text

6TF$BTF*OUFSGBDF enum RentalConfirmUseCaseModel { enum SalesItems { case items([SalesItem]) case empty } struct SalesItem { let id: String let title: String let price: Int } }

Slide 53

Slide 53 text

6TF$BTF*OUFSGBDF enum RentalConfirmUseCaseModel { enum SalesItems { case items([SalesItem]) case empty } struct SalesItem { let id: String let title: String let price: Int } } w ఆٛ͸࢓༷ʹΑͬͯมԽ͢Δ

Slide 54

Slide 54 text

6TF$BTF*OUFSGBDF enum RentalConfirmUseCaseModel { enum SalesItems { case items([SalesItem]) case empty } struct SalesItem { let id: String let title: String let price: Int } } w ఆٛ͸࢓༷ʹΑͬͯมԽ͢Δ w ࢓༷ w ൢചதͷϨϯλϧ঎඼ͷΈΛදࣔ͢Δ w 6TF$BTFʹͯϑΟϧλϦϯά w TUBSU"UͱFOE"U͸ෆཁ

Slide 55

Slide 55 text

6TF$BTF*OUFSGBDF enum RentalConfirmUseCaseModel { enum SalesItems { case items([SalesItem]) case empty } struct SalesItem { let id: String let title: String let price: Int } } w ఆٛ͸࢓༷ʹΑͬͯมԽ͢Δ w ࢓༷ w ൢചதͷϨϯλϧ঎඼ͷΈΛදࣔ͢Δ w 6TF$BTFʹͯϑΟϧλϦϯά w TUBSU"UͱFOE"U͸ෆཁ w දࣔͰ͖ΔϨϯλϧ঎඼͕ͳ͍৔߹͸Τϥʔ Λදࣔ͢Δ

Slide 56

Slide 56 text

class RentalConfirmUseCase: RentalConfirmUseCaseType { func listSalesItems(programID: String, date: Date) -> RxSwift.Single { rentalSalesItemRepository.fetchRentalSalesItems(programID: programID) .map { items in let availableItems = items.compactMap { item -> UseCaseModel.SalesItem in guard item.isOnSale(date: date) else { return nil } return UseCaseModel.SalesItem( id: item.id, title: item.title, price: item.price ) } guard !availableItems.isEmpty else { return .empty } return .items(availableItems) } .catchErrorJustReturn(.empty) } } 6TF$BTF

Slide 57

Slide 57 text

class RentalConfirmUseCase: RentalConfirmUseCaseType { func listSalesItems(programID: String, date: Date) -> RxSwift.Single { rentalSalesItemRepository.fetchRentalSalesItems(programID: programID) .map { items in let availableItems = items.compactMap { item -> UseCaseModel.SalesItem in guard item.isOnSale(date: date) else { return nil } return UseCaseModel.SalesItem( id: item.id, title: item.title, price: item.price ) } guard !availableItems.isEmpty else { return .empty } return .items(availableItems) } .catchErrorJustReturn(.empty) } } 6TF$BTF w 3FQPTJUPSZ͔ΒϨϯλϧ঎඼ҰཡΛऔಘ w ฦΓ஋͸<%PNBJO3FOUBM4BMFT*UFN>

Slide 58

Slide 58 text

class RentalConfirmUseCase: RentalConfirmUseCaseType { func listSalesItems(programID: String, date: Date) -> RxSwift.Single { rentalSalesItemRepository.fetchRentalSalesItems(programID: programID) .map { items in let availableItems = items.compactMap { item -> UseCaseModel.SalesItem in guard item.isOnSale(date: date) else { return nil } return UseCaseModel.SalesItem( id: item.id, title: item.title, price: item.price ) } guard !availableItems.isEmpty else { return .empty } return .items(availableItems) } .catchErrorJustReturn(.empty) } } 6TF$BTF w ࢓༷ w ൢചதͷϨϯλϧ঎඼ͷΈΛදࣔ͢Δ w υϝΠϯϩδοΫΛར༻

Slide 59

Slide 59 text

class RentalConfirmUseCase: RentalConfirmUseCaseType { func listSalesItems(programID: String, date: Date) -> RxSwift.Single { rentalSalesItemRepository.fetchRentalSalesItems(programID: programID) .map { items in let availableItems = items.compactMap { item -> UseCaseModel.SalesItem in guard item.isOnSale(date: date) else { return nil } return UseCaseModel.SalesItem( id: item.id, title: item.title, price: item.price ) } guard !availableItems.isEmpty else { return .empty } return .items(availableItems) } .catchErrorJustReturn(.empty) } } 6TF$BTF w %50΁ͷม׵

Slide 60

Slide 60 text

class RentalConfirmUseCase: RentalConfirmUseCaseType { func listSalesItems(programID: String, date: Date) -> RxSwift.Single { rentalSalesItemRepository.fetchRentalSalesItems(programID: programID) .map { items in let availableItems = items.compactMap { item -> UseCaseModel.SalesItem in guard item.isOnSale(date: date) else { return nil } return UseCaseModel.SalesItem( id: item.id, title: item.title, price: item.price ) } guard !availableItems.isEmpty else { return .empty } return .items(availableItems) } .catchErrorJustReturn(.empty) } } 6TF$BTF w ࢓༷ w දࣔͰ͖ΔϨϯλϧ঎඼͕ͳ͍৔߹͸Τ ϥʔΛදࣔ͢Δ w 4BMFT*UFNTFNQUZͱͯ͠දݱ

Slide 61

Slide 61 text

class RentalConfirmUseCase: RentalConfirmUseCaseType { func listSalesItems(programID: String, date: Date) -> RxSwift.Single { rentalSalesItemRepository.fetchRentalSalesItems(programID: programID) .map { items in let availableItems = items.compactMap { item -> UseCaseModel.SalesItem in guard item.isOnSale(date: date) else { return nil } return UseCaseModel.SalesItem( id: item.id, title: item.title, price: item.price ) } guard !availableItems.isEmpty else { return .empty } return .items(availableItems) } .catchErrorJustReturn(.empty) } } 6TF$BTF w λΠϜΞ΢τΤϥʔͳͲͷϋϯυϦϯά

Slide 62

Slide 62 text

6*-PHJD*OUFSGBDF protocol RentalConfirmViewStreamType: AnyObject { var input: InputWrapper { get } var output: OutputWrapper { get } } struct RentalConfirmViewStreamInput: InputType { let viewDidAppear = RxRelay.PublishRelay() } struct RentalConfirmViewStreamOutput: OutputType { let sectionModels: RxSwift.Observable<[RentalConfirmSectionModel]> let showAlert: RxSwift.Observable }

Slide 63

Slide 63 text

6*-PHJD*OUFSGBDF w *OQVUͷఆٛ w 7JFX͔Β7JFX4USFBN΁ͷΠϕϯτ w WJFX%JE-PBE΍WJFX%JE"QQFBSɺϢʔβʹΑΔϘλϯͷԡԼͳͲ protocol RentalConfirmViewStreamType: AnyObject { var input: InputWrapper { get } var output: OutputWrapper { get } } struct RentalConfirmViewStreamInput: InputType { let viewDidAppear = RxRelay.PublishRelay() } struct RentalConfirmViewStreamOutput: OutputType { let sectionModels: RxSwift.Observable<[RentalConfirmSectionModel]> let showAlert: RxSwift.Observable }

Slide 64

Slide 64 text

6*-PHJD*OUFSGBDF w 0VUQVUͷఆٛ w 7JFX΁൓ө͢Δσʔλ w Ϙλϯͷঢ়ଶɺΞϥʔτͷදࣔλΠϛϯάͷ௨஌ͳͲ protocol RentalConfirmViewStreamType: AnyObject { var input: InputWrapper { get } var output: OutputWrapper { get } } struct RentalConfirmViewStreamInput: InputType { let viewDidAppear = RxRelay.PublishRelay() } struct RentalConfirmViewStreamOutput: OutputType { let sectionModels: RxSwift.Observable<[RentalConfirmSectionModel]> let showAlert: RxSwift.Observable }

Slide 65

Slide 65 text

6*-PHJD let salesItems = useCase.listSalesItems(programID: programID, date: getCurrentDate()) salesItems .flatMap { salesItems -> Observable<[RentalConfirmSectionItem]> in guard case let .items(_items) = salesItems else { return .empty() } let sectionModels = _items.map { ... } return .just(items) } .bind(to: state.sectionModels) dependency.inputObservables.viewDidAppear .flatMap { _ -> Observable in salesItems .flatMap { items -> Observable in guard items == .empty else { return .empty() } return .just(()) } } .bind(to: state.showAlert) .disposed(by: disposeBag)

Slide 66

Slide 66 text

6*-PHJD let salesItems = useCase.listSalesItems(programID: programID, date: getCurrentDate()) salesItems .flatMap { salesItems -> Observable<[RentalConfirmSectionItem]> in guard case let .items(_items) = salesItems else { return .empty() } let sectionModels = _items.map { ... } return .just(items) } .bind(to: state.sectionModels) dependency.inputObservables.viewDidAppear .flatMap { _ -> Observable in salesItems .flatMap { items -> Observable in guard items == .empty else { return .empty() } return .just(()) } } .bind(to: state.showAlert) .disposed(by: disposeBag) w 6TF$BTF͔ΒϨϯλϧ঎඼ҰཡΛऔಘ

Slide 67

Slide 67 text

6*-PHJD let salesItems = useCase.listSalesItems(programID: programID, date: getCurrentDate()) salesItems .flatMap { salesItems -> Observable<[RentalConfirmSectionItem]> in guard case let .items(_items) = salesItems else { return .empty() } let sectionModels = _items.map { ... } return .just(items) } .bind(to: state.sectionModels) dependency.inputObservables.viewDidAppear .flatMap { _ -> Observable in salesItems .flatMap { items -> Observable in guard items == .empty else { return .empty() } return .just(()) } } .bind(to: state.showAlert) .disposed(by: disposeBag) w Ϩϯλϧ঎඼͕͋Δ৔߹ w 4FDUJPO.PEFMʢ7JFXͱ΍ΓͱΓ͢Δ %50ʣ΁ม׵

Slide 68

Slide 68 text

6*-PHJD let salesItems = useCase.listSalesItems(programID: programID, date: getCurrentDate()) salesItems .flatMap { salesItems -> Observable<[RentalConfirmSectionItem]> in guard case let .items(_items) = salesItems else { return .empty() } let sectionModels = _items.map { ... } return .just(items) } .bind(to: state.sectionModels) dependency.inputObservables.viewDidAppear .flatMap { _ -> Observable in salesItems .flatMap { items -> Observable in guard items == .empty else { return .empty() } return .just(()) } } .bind(to: state.showAlert) .disposed(by: disposeBag) w Ϩϯλϧ঎඼͕ͳ͍৔߹ w ΞϥʔτΛදࣔ͢ΔͨΊͷΠϕϯτ ΛൃՐ

Slide 69

Slide 69 text

6*$PNQPOFOU override func viewDidLoad() { super.viewDidLoad() viewStream.output.sectionModels .bind(to: tableView.rx.items(dataSource: dataSource)) .disposed(by: disposeBag) viewStream.output.showAlert .observeOn(ConcurrentMainScheduler.instance) .subscribe(onNext: { [weak self] in guard let me = self else { return } let alert = UIAlertController(title: "💀", message: nil, preferredStyle: .alert) me.present(alert, animated: true) }) .disposed(by: disposeBag) } override func viewDidAppear(_ animated: Bool) { super.viewDidAppear() viewStream.input.viewDidAppear(()) }

Slide 70

Slide 70 text

6*$PNQPOFOU override func viewDidLoad() { super.viewDidLoad() viewStream.output.sectionModels .bind(to: tableView.rx.items(dataSource: dataSource)) .disposed(by: disposeBag) viewStream.output.showAlert .observeOn(ConcurrentMainScheduler.instance) .subscribe(onNext: { [weak self] in guard let me = self else { return } let alert = UIAlertController(title: "💀", message: nil, preferredStyle: .alert) me.present(alert, animated: true) }) .disposed(by: disposeBag) } override func viewDidAppear(_ animated: Bool) { super.viewDidAppear() viewStream.input.viewDidAppear(()) } w 7JFX4USFBN΁ͷ*OQVU

Slide 71

Slide 71 text

override func viewDidLoad() { super.viewDidLoad() viewStream.output.sectionModels .bind(to: tableView.rx.items(dataSource: dataSource)) .disposed(by: disposeBag) viewStream.output.showAlert .observeOn(ConcurrentMainScheduler.instance) .subscribe(onNext: { [weak self] in guard let me = self else { return } let alert = UIAlertController(title: "💀", message: nil, preferredStyle: .alert) me.present(alert, animated: true) }) .disposed(by: disposeBag) } override func viewDidAppear(_ animated: Bool) { super.viewDidAppear() viewStream.input.viewDidAppear(()) } 6*$PNQPOFOU w 4FDUJPO.PEFMTΛ6*5BCMF7JFX΁CJOE

Slide 72

Slide 72 text

override func viewDidLoad() { super.viewDidLoad() viewStream.output.sectionModels .bind(to: tableView.rx.items(dataSource: dataSource)) .disposed(by: disposeBag) viewStream.output.showAlert .observeOn(ConcurrentMainScheduler.instance) .subscribe(onNext: { [weak self] in guard let me = self else { return } let alert = UIAlertController(title: "💀", message: nil, preferredStyle: .alert) me.present(alert, animated: true) }) .disposed(by: disposeBag) } override func viewDidAppear(_ animated: Bool) { super.viewDidAppear() viewStream.input.viewDidAppear(()) } 6*$PNQPOFOU w Ξϥʔτͷදࣔ

Slide 73

Slide 73 text

"QQ let rentalSalesItemRepository = RentalConfirmRepository(apiSession: ApiSession.shared) let useCase = RentalConfirmUseCase(rentalSalesItemRepository: rentalSalesItemRepository) let viewStream = RentalConfirmViewStream( programID: programID, useCase: useCase, getCurrentDate: { Date() } ) let viewController = RentalConfirmViewController(viewStream: viewStream) present(viewController)

Slide 74

Slide 74 text

ΞδΣϯμ ·ͱΊ എܠ ߏ੒ͱ࣮૷

Slide 75

Slide 75 text

·ͱΊ w /BUJWFνʔϜ΁ͷ౷߹Λ͖͔͚ͬʹɺ"OESPJEͱJ04Ͱڞ௨͢Δ࢓༷Λ໌֬ʹ͢ ΔϞνϕʔγϣϯ͕ੜ·Εͨ w $MFBO"SDIJUFDUVSFΛϕʔεʹΞϓϦͷ࠶ઃܭΛ͸͡Ίͨ w ·ͩ·ͩ՝୊͸ଟ͍͕ɺ౎౓νʔϜͰཧ૝ͷઃܭΛٞ࿦͠ͳ͕ΒϦΞʔΩςΫ νϟΛਐΊ͍ͯΔ

Slide 76

Slide 76 text

4FF"MTP IUUQTTQFBLFSEFDLDPNUPJLJBCFNBJPTBSDIJUFDUVSF IUUQTTQFBLFSEFDLDPNNBSUZTV[VLJJPTOJLNNXPEBPSVTVSVUJQT IUUQTTQFBLFSEFDLDPNUBLBIJSPNBCFNBGBMTFLPUMJONVMUJQMBUGPSN

Slide 77

Slide 77 text

4FF"MTP dIUUQTXXXZPVUVCFDPNXBUDI W-N'I@Y2NL