Slide 1

Slide 1 text

46("3ͷΞʔΩςΫνϟ ಥܸʂʂྡͷΞʔΩςΫνϟ !TVHJUBOJ " 3 $ ) * 5 & $ 5 6 3 &

Slide 2

Slide 2 text

લઆ

Slide 3

Slide 3 text

ࣗݾ঺հ • ਿ୩ͱਃ͠·͢ • ܦྺ • υϫϯΰ χίχίੜ์ૹ • ηϓςʔχɾΦϦδφϧ $50 ("/." • 46("3$50 46("3 !TVHJUBOJ

Slide 4

Slide 4 text

46("3ͱ͸ʁ • ஶ໊ਓʹಛԽͨ͠ϥΠϒ഑৴Ξ ϓϦ • ొ࿥ͯ͠ΞʔςΟετΛϑΥϩʔ͠ ͓ͯ͘ͱి࿩ $BMM,JU ͕དྷΔ • Ұఆ਺͕ϐοΫΞοϓ͞Εબ୒ΤϦ ΞʹೖΔʢ௨শ͓ण࢘Ϩʔϯʣ • ΞʔςΟετ͕௨࿩ର৅ΛબͿͱ௨ ࿩͕Ͱ͖Δ ଞͷਓ͸ͦͷ༷ࢠΛ ோΊΔ • ഑৴ऀ͕εΰ͘ͳ͚Ε͹੒Γཱ ͨͳ͍ • ഑৴ऀ͕Ϡό͍

Slide 5

Slide 5 text

ΞʔΩςΫνϟ঺հ͸͡Ί·͢ ˞͝஫ҙ˞ %%%ͳͲ͍ΖΜͳ୯ޠ͕Ͱ͖ͯ·͕͢ ຊϓϨθϯςʔγϣϯ͸ฐࣾͷݱঢ়ͷ঺հʹա͗ͣ Կ͔͠Βͷํ๏࿦ͷਖ਼͍࣮͠ફํ๏Λࣔ͢΋ͷͰ͸͋Γ·ͤΜ

Slide 6

Slide 6 text

࠾༻ΞʔΩςΫνϟͱ঺հൣғ 4DBMBαʔό 4XJGUJ04 ,PUMJO"OESPJE ͥΜͿ΍Δ γεςϜΞʔΩςΫνϟ %*1Λ׆༻͢ΔҰ೿ʁ γεςϜΞʔΩςΫνϟ %*1Λ׆༻͢ΔҰ೿ʁ γεςϜΞʔΩςΫνϟ %*1Λ׆༻͢ΔҰ೿ʁ (6*ΞʔΩςΫνϟ ແ͠ +40/ग़͚ͩ͢ (6*ΞʔΩςΫνϟ .7$͔ͳ͊ʜʁ (6*ΞʔΩςΫνϟ .77.ͩͱࢥͬͯΔ

Slide 7

Slide 7 text

ͲΕ΋جຊతʹߏ଄͸Ұॹ TSD EPNBJO BQQMJDBUJPO BEBQUFS WJFX *OGSBTUSVDUVSF

Slide 8

Slide 8 text

Πϝʔδ͸͓ͳ͡Έͷԁܗ %PNBJO "QQMJDBUJPO "EBQUFS 7JFX ͦͷଞ *OGSBTUSVDUVSF

Slide 9

Slide 9 text

%PNBJO %PNBJO "QQMJDBUJPO "EBQUFS 7JFX ͦͷଞ *OGSBTUSVDUVSF %%%Ͱੜ੒͞ΕΔ֓೦ͷॅ·͏৔ॴ &OUJUZ7BMVF0CKFDU4FSWJDF 3FQPTJUPSZ౳ͷఆٛ USBJUJOUFSGBDFQSPUPDPM Λஔ͘

Slide 10

Slide 10 text

"QQMJDBUJPO %PNBJO "QQMJDBUJPO "EBQUFS 7JFX ͦͷଞ *OGSBTUSVDUVSF υϝΠϯ૚ͷొ৔ਓ෺Λ ҙຯͷ͋Δॲཧʹ·ͱΊΔΫϥεͷॅ·͏৔ॴ *OKFDU͞Εͨ%PNBJOΠϯελϯεΛ࢖ͬͯͻͱ·ͱ·Γ ͷॲཧʢྫσʔλΛ3FQPTJUPSZ͔ΒݺΜͰ4FSWJDFʹ௨ ͢ͳͲՃ޻͔ͯ͠Βอଘ͢Δ Λߦ͏࣮૷͔ఆٛΛஔ͘

Slide 11

Slide 11 text

"EBQUFS %PNBJO "QQMJDBUJPO "EBQUFS 7JFX ͦͷଞ *OGSBTUSVDUVSF υϝΠϯ૚ͷ࣮૷ͷॅ·͏৔ॴ υϝΠϯ૚ͷఆٛΛܧঝ࣮ͨ͠૷ʢ%#ʹ ΞΫηε͢Δ3FQPTJUPSZ౳ʣΛஔ͘

Slide 12

Slide 12 text

7JFX ͦͷଞʣ %PNBJO "QQMJDBUJPO "EBQUFS 7JFX ͦͷଞ *OGSBTUSVDUVSF 6*ͱίϯτϩʔϥ 6*7JFX$POUSPMMFS6*7JFX"DUJWJUZ'SB HNFOU QMBZͷ $POUSPMMFSͳͲݟͨ໨ ͱૢ࡞ͷ࢝·Γ͔ΒऴΘΓ·Ͱͷ੍ޚʹ ؔΘΔ࣮૷Λஔ͖·͢ɻ

Slide 13

Slide 13 text

*OGSBTUSVDUVSF %PNBJO "QQMJDBUJPO "EBQUFS 7JFX ͦͷଞ *OGSBTUSVDUVSF ൚༻తͳ΋ͷஔ͖৔ จࣈྻ΍࣌ࠁૢ࡞ϢʔςΟϦςΟɺ"84 ͷԿ͔͠ΒΛ࢖͍΍͘͢ϥοϓͨ͠΋ͷ ౳ͷͲ͜Ͱ΋࢖͑ͦ͏ͳ࣮૷Λஔ͘ɻ

Slide 14

Slide 14 text

಺ଆ͚ͩར༻Ͱ͖Δ %PNBJO "QQMJDBUJPO "EBQUFS 7JFX ͦͷଞ *OGSBTUSVDUVSF ґଘੑٯసͷݪଇΛ׆༻ %PNBJOr 7JFXɺ"EBQUFSɺ"QQMJDBUJPOΛར༻ JNQPSU Ͱ͖ͳ͍ "QQMJDBUJPOr %PNBJOΛར༻Ͱ͖Δɻ 7JFXɺ"EBQUFSΛར༻Ͱ͖ͳ͍ "EBQUFSr"QQMJDBUJPOɺ%PNBJOΛར༻Ͱ͖Δɻ7JFXΛར༻Ͱ͖ͳ͍ 7JFXr "EBQUFSɺ"QQMJDBUJPOɺ%PNBJOΛར༻Ͱ͖Δ *OGSBTUSVDUVSFr ଞΛར༻Ͱ͖ͳ͍ɻଞ͔Βར༻͞ΕΔ

Slide 15

Slide 15 text

%PNBJO૚ͷਂ۷Γ

Slide 16

Slide 16 text

%PNBJO૚ͷํ਑ • υϝΠϯۦಈઃܭͰϞσϦϯάΛߦ͏ • &SJDຊʹͰ͖Δ͚ͩ४ڌͯ͠ݕ౼͢Δ • ੠ʹग़ͯٞ͠࿦͢Δ • ݪଇఆٛ USBJUJOUFSGBDFQSPUPDPM Λஔ͘ • γϯϓϧͳ7BMVF0CKFDUʹ͸ྫ֎΋͋Δ • ط੒ͷ೔෇Ϋϥε΍63-ΫϥεΛ͔ͭͬͨΓ • UZQFBMJBT'PP4USJOH TXJGULPUMJO ΍"OZ7BM TDBMB Ͱදݱͨ͠Γ • &OVN࢖ͬͨΓ • ಉ͡ଘࡏʹରͯ͠αʔόͱΫϥΠΞϯτͰಉ͡ݴ༿΍ݟ͑ํʹ ͳΔͱ͸ݶΒͳ͍͜ͱʹؾΛ͚ͭΔ

Slide 17

Slide 17 text

ʮΞΧ΢ϯτΛ࣋ͬͨར༻ऀʯͷ ఆٛΠϝʔδ 4DBMB trait EntityId { /* … */ } trait Entity[T <: EntityId] { val id: T } trait UserId extends EntityId trait ImageResource { /* … */ } case class UserName(value: String) extends AnyVal trait RegisteredUser extends Entity[UserId]{ val name: UserName val icon: ImageResource val registeredDate: LocalDateTime }

Slide 18

Slide 18 text

ʮΞΧ΢ϯτΛ࣋ͬͨར༻ऀʯͷ ఆٛΠϝʔδ 4DBMB trait EntityId { /* … */ } trait Entity[T <: EntityId] { val id: T } trait UserId extends EntityId trait ImageResource { /* … */ } case class UserName(value: String) extends AnyVal trait RegisteredUser extends Entity[UserId]{ val name: UserName val icon: ImageResource val registeredDate: LocalDateTime } ొ࿥ࡁΈͰͳ͍Ϣʔβʔ͍ͩͬͯΔͷҙ

Slide 19

Slide 19 text

trait Entity { type ID <: EntityId; val id: ID } case class User(id: UserId, …) extends Entity { type ID = UserId } 5JQTɿ&OUJUZͱ*% ར༻ྫ ͕ͧ͘͞Μᐌ͘ ҙຯ ৽نͰ࡞Δ৔߹͸ͪ͜Βʹ͓͖ͯ͠·͠ΐ͏ʂ https://twitter.com/gakuzzzz/status/1103240324120403968

Slide 20

Slide 20 text

ʮΞΧ΢ϯτΛ࣋ͬͨར༻ऀʯͷ ఆٛΠϝʔδ 4XJGU protocol EntityId { /* … */ } protocol Entity { var entityId: EntityId { get } } protocol UserId: EntityId { } typealias UserName = String protocol Profile: Entity { var userId: UserId { get } var name: UserName { get } var icon: URL? { get } } extension Profile { var entityId: EntityId { return userId } }

Slide 21

Slide 21 text

ʮΞΧ΢ϯτΛ࣋ͬͨར༻ऀʯͷ ఆٛΠϝʔδ 4XJGU protocol EntityId { /* … */ } protocol Entity { var entityId: EntityId { get } } protocol UserId: EntityId { } typealias UserName = String protocol Profile: Entity { var userId: UserId { get } var name: UserName { get } var icon: URL? { get } } extension Profile { var entityId: EntityId { return userId } } ΫϥΠΞϯτ͔Β͢Ε͹ਓ͡Όͳͯ͘ ϓϩϑΟʔϧ͔͠ڵຯͳ͍ΑͶɺ ͷҙΛࠐΊ໋໊ͨ

Slide 22

Slide 22 text

ʮΞΧ΢ϯτΛ࣋ͬͨར༻ऀʯͷ ఆٛΠϝʔδ 4XJGU protocol EntityId { /* … */ } protocol Entity { var entityId: EntityId { get } } protocol UserId: EntityId { } typealias UserName = String protocol Profile: Entity { var userId: UserId { get } var name: UserName { get } var icon: URL? { get } } extension Profile { var entityId: EntityId { return userId } } (FOFSJD1SPUPDPM͸໘౗͕ଟ͍ͷͰ খࡉ޻Ͱར༻Λආ͚Δ

Slide 23

Slide 23 text

ʮΞΧ΢ϯτΛ࣋ͬͨར༻ऀʯͷ ఆٛΠϝʔδ ,PUMJO interface EntityId { /* ... */ } interface Entity { val id: ID } interface UserId: EntityId typealias UserName = String interface Profile: Entity { val name:UserName val icon: URI? }

Slide 24

Slide 24 text

%%%తʹ͋΍͍͠Ϋϥεୡ΋ډΔ • ΫϥΠΞϯτଆʹ͍Δ • 8FC3UD˞ • 8FC3UD%FWJDF8FC3UD4JHOBMJOH8FC3UD4FUUJOHʜ • )UUQ-JWF4USFBNJOH˞ • "VEJP4PVSDF • 7JEFP4PVSDF • $BNFSB7JEFP4PVSDF4UJMM*NBHF7*EFP4PVSDF • %%%ͬΆ͘͸ͳ͍ʜ • ͔ͱ͍ͬͯݴ༿ͱͯ͠͸ઈର֎ͤͳ͍ʜ • Ͱ΋ศར ˞͜ΕΒ͸ࣗ෼ୡͷఆٛͨ͠΋ͷͰ ϥΠϒϥϦ౳ͷੜ0CKFDUΛࢦ͢΋ͷͰ͸͋Γ·ͤΜ

Slide 25

Slide 25 text

উखʹ૿΍ͨ͠ఆٛୡ ΫϥΠΞϯτଆͰͷΈ%PNBJO૚ʹஔ͚ΔఆٛΛ૿΍͍ͯ͠Δ • -PDBM3FQPTJUPSZ • ϩʔΧϧͰ͔͠อଘ͠ͳ͍͔ΒͶʁ͍͍ͶʁΛڧௐͨ͠3FQPTJUPSZ • ओʹ$BDIF༻్Ͱ࢖͏ͷͰ$MFBS$MFBS"MMΛ͍࣋ͬͯΔ • %BUB4PVSDF • 3FQPTJUPSZͷѥछɻϩʔΧϧݶఆͷҰ࣌σʔλΛऔΓѻ͏ɻ • ߋ৽ݕग़ͷ EFMFHBUF FWFOU-JTUFS ΛηοτͰ͖Δ • 7JFXʹηοτ͢Δ༻ • %BUB4UPSF • %BUB4PVSDFͷ্Ґ൛ɻ • σʔλͷ௥Ճߋ৽͕Ͱ͖Δɻ

Slide 26

Slide 26 text

"QQMJDBUJPO૚ͷਂ۷Γ

Slide 27

Slide 27 text

"QQMJDBUJPO૚ͷΠϝʔδ 'PP3FQPTJUPSZ ࠩ͠ࠐΈޱ #BS3FQPTJUPSZ ࠩ͠ࠐΈޱ #B['BDUPSZ ࠩ͠ࠐΈޱ "4QFDJBM"QQMJDBUJPO 'PP3FQPTJUPSZ *NQMFNFOU #BS3FQPTJUPSZ *NQMFNFOU #B['BDUPSZ *NQMFNFOU ͜ΕΛ ϝιου" ϝιου# ʜ

Slide 28

Slide 28 text

"QQMJDBUJPO૚ͷΠϝʔδ 'PP3FQPTJUPSZ ࠩ͠ࠐΈޱ #BB3FQPTJUPSZ ࠩ͠ࠐΈޱ #B['BDUPSZ ࠩ͠ࠐΈޱ "4QFDJBM"QQMJDBUJPO 'PP3FQPTJUPSZ *NQMFNFOU #BS3FQPTJUPSZ *NQMFNFOU #B['BDUPSZ *NQMFNFOU ͜͏͢Δͱ ϝιου" ϝιου# ʜ

Slide 29

Slide 29 text

"QQMJDBUJPO૚ͷΠϝʔδ 'PP3FQPTJUPSZ ࠩ͠ࠐΈޱ #BB3FQPTJUPSZ ࠩ͠ࠐΈޱ #B['BDUPSZ ࠩ͠ࠐΈޱ "4QFDJBM"QQMJDBUJPO 'PP3FQPTJUPSZ *NQMFNFOU #BS3FQPTJUPSZ *NQMFNFOU #B['BDUPSZ *NQMFNFOU ར༻Մೳʂ ར༻Մೳʂ ͜͏ͳΔʂ ϝιου" ϝιου# ʜ

Slide 30

Slide 30 text

"QQMJDBUJPO૚ͷํ਑ • %*͞Εͨ%PNBJO૚ͷ࣮૷Λ૊Έ߹ΘͤͯԿ͔͠Βͷҙຯͷ͋ Δॲཧʹ͢Δ࣮૷Λஔ͘ • ଞͷ"QQMJDBUJPOΛड͚औΔࣄ΋͋ΔͷͰ࣮͸ଟ૚ • ෭࡞༻ͷ͋ΔॲཧΛ௚઀ߦ͏͜ͱ͸ͳ͘ɺ%*͞ΕͨΠϯελϯ ε΁ͷࢦࣔΛ௨ͯ͠ߦ͏ • λΠϚʔॲཧΛߦͬͨΓ"DUPSͰಈ͍ͯͨΓ͢Δ͜ͱ΋͋Γ݁ ߏࣗ༝

Slide 31

Slide 31 text

۩ମྫ r ܝࣔ൘ॻ͖ࠐΈΞϓϦ class CommentPoster(commentsRepository: CommentsRepository, commentFactory: CommentFactory){ def post(userId:UserId, body:String, timestamp:LocalDateTime): Future[Done] ={ val comment = commentFactory.build(userId, body, timestamp) commentsRepository.store(comment) } } ˞ͿͬͪΌ͚͜Ε͘Β͍ͷॲཧͳΒ"QQMJDBUJPOΛ࡞Βͣ $POUSPMMFSʹॻ͍ͯ͠·͏͜ͱ͕ଟ͍

Slide 32

Slide 32 text

۩ମྫ r $BDIF෇͖3FQPTJUPSZ protocol FooRepository { func get(id: FooId) -> Promise func store(foo: Foo) -> Promise } protocol FooLocalRepository { func get(id: FooId) -> Promise func store(foo: Foo) -> Promise func clear(id: FooId) func clearAll() } class CachedFooRepository: FooRepository { ʜ init(fooRepository: FooRepository, fooLocalRepository: FooLocalRepository) { ʜ } func get(id: FooId) -> Promise { MPDBM3FQPTJUPSZ͔Βऔಘˠͳ͚Ε͹SFQPTJUPSZ͔Βऔಘ } func store(foo: Foo) -> Promise { SFQPTJUPSZʹอଘ͔ͯ͠Β MPDBM3FQPTJUPSZDMFBS } } ˞1SPNJTFϥΠϒϥϦ͸ )ZESB Λ޷ΜͰ࢖͍ͬͯ·͢

Slide 33

Slide 33 text

۩ମྫ r $BDIF෇͖3FQPTJUPSZ interface FooRepository { suspend fun get(id: FooId): Foo suspend fun store(foo: Foo) } interface FooLocalRepository { suspend fun get(id: FooId): Foo suspend fun store(foo: Foo) fun clear(id:FooId) fun clearAll() } class CachedFooRepository( private val fooRepository: FooRepository, private val fooLocalRepository: FooLocalRepository ) : FooRepository { override suspend fun get(id: FooId): Foo { /* localRepositoryから取得→なければrepositoryから取得 */ } override suspend fun store(foo: Foo) { /* repositoryに保存してから localRepository.clear() */ } }

Slide 34

Slide 34 text

۩ମྫ r $BDIF$MFBOFS class CacheCleaner( private val fooLocalRepository: FooLocalRepository, private val barLocalRepository: BarLocalRepository, private val bazLocalRepository: BazLocalRepository ) { fun execute() { fooLocalRepository.clearAll() barLocalRepository.clearAll() bazLocalRepository.clearAll() } }

Slide 35

Slide 35 text

۩ମྫ r ϥΠϒ1MBZFSͷίΞ 1MBZFS6* EFMFHBUF ࠩ͠ࠐΈޱ Session ParticipantList DataStore ChatList DataStore ΍͍ͬͯΔۀ຿ • ঢ়گʹԠͯ͡)4-8FC35$ͷ઀ଓΛ࢖͍෼͚ΔΑ͏$POOFDUJPOʹࢦࣔΛग़͢ • 8FC4PDLFU&WFOU4PVSDF౳͔Βνϟοτ΍ࢀՃऀ৘ใΛड৴ͯ͠$IBU-JTU΍1BSUJDJQBOU-JTUʹ อଘ͢Δ • ϝιουΛ௨ͯ͠֎ଆʹ·ͱΊͨ৘ใΛฦͨ͠ΓɺࢦࣔΛड͚ͨΓ౳ Connection WebRtc Signaling Device WebSocket CommandFactory HLS EventSource (server sent event) QMBZFS4UBUVT DIBUૹ৴ DMPTF ʜ

Slide 36

Slide 36 text

"EBQUFS૚ͷਂ۷Γ

Slide 37

Slide 37 text

"EBQUFS૚ͷํ਑ • %PNBJO૚ͷఆٛ USBJUJOUFSGBDFQSPUPDPM Λܧঝ࣮ͯ͠૷͠ ͨΫϥεͷஔ͖৔ • &OUJUZ7BMVF 0CKFDUͰ͋Ε͹ DBTFDMBTTEBUBDMBTT TUSVDUͰ࡞ͬͨΓ౳ • +40/౳ͱͷ૬ޓม׵΋͜͜Ͱॻ͍ͯ͠·͏ • 3FQPTJUPSZͰ͋Ε͹%#΍"1*ͱ௨৴ͨ͠Γςετ༻ʹΦϯϝ ϞϦͷ࣮૷Λ࡞ͬͨΓɻ ͱ͘ʹ޻෉͸ͳ͍ͷͰ۩ମྫ͸লུ͠·͢

Slide 38

Slide 38 text

7JFX૚ͷਂ۷Γ

Slide 39

Slide 39 text

7JFX NJTD ૚ͷํ਑ • "QQMJDBUJPOΛΠϯελϯεԽͯ͠ը໘Λग़ྗߏங͢Δ • αʔόଆ͸+40/ు͚ͩ͘ͳͷͰγϯϓϧ • ΫϥΠΞϯτଆ͸ը໘ͷෳࡶ͞ʹԠͯ͡࿈ܞํ๏Λม͍͑ͯΔ • ओͳॅਓ • 6*7JFX$POUSPMMFS6*7JFX"DUJWJUZ'SBHNFOU QMBZͷ $POUSPMMFS ͳͲͷίϯτϩʔϥʔܥ • 4UPSZCPBSE9JCMBZPVUͷ9.- σΟϨΫτϦతʹ͸ผʣ "1*ͷҾ਺ ΍ฦ஋ͷ+40/ૢ࡞ • %*ίϯςφ΋͜ͷ૚

Slide 40

Slide 40 text

αʔόଆͷ7JFX࣮૷ • جຊ3&45 "1*ܗࣜͰ+40/ฦ͚ͩ͢ • &OUJUZ7BMVF0CKFDUͱ+40/ͷ૬ޓม׵͸"EBQUFS૚Ͱ࣮૷͍ͯ͠Δ͜ͱ΋͋Δ͕ɺ ग़ྗͷ౎߹ʹҾͬுΒΕͨ͘ͳ͍ͷͰɺ͜ΕΒΛૉͷ··ฦ͢͜ͱ͸গͳ͍ • جຊ"1*ຖʹฦ౴ܗࣜΛܾΊͯͦͪΒʹ٧Ίସ͑Δ import play.api.libs.json.Json case class FooGetApiResponse(id: FooId, description: String) object FooGetApiResponse { implicit val jsonWrites = Json.writes[FooResponse] }

Slide 41

Slide 41 text

J04ͷ7JFX࣮૷ ௒γϯϓϧͳը໘ • ௒؆୯ͳը໘Ͱ͋ΔͳΒͦͷ··7JFX$POUSPMMFSͱ4UPSZCPBSE͚ͬͭ͘Δ • 4UPSZCPBSE͸جຊը໘ຖʹ࡞੒ • Ұ࿈ͷը໘ʢΞϓϦىಈޙͷ͍Ζ͍Ζ঺հϑϩʔͳͲʣ͸ෳ਺ը໘Λ֨ೲ 閉じるボタン class FooViewController: UIViewController { @IBAction func onTouchUpInsideCloseBotton(_: Any) { navigationController?.popViewController(animated: true) } } 4UPSZCPBSE

Slide 42

Slide 42 text

J04ͷ7JFX࣮૷ ΍΍ෳࡶͳը໘ • ଟগෳࡶͳΒ7JFXૢ࡞͸ΧελϜ7JFXʹԡ͠ࠐΊͯ͠·͏ • 7JFX$POUSPMMFS͸ΧελϜ7JFX΁ͷσʔληοτ SFQPTJUPSZΛݺͼग़͢౳ ͱɺ 7JFX͔Βͷૢ࡞΁ͷରԠ͕ओͳ࢓ࣄɻ Submit TextText TextTextTextTextText TextTextText TextText TextTextText 9JC ੜૢ࡞ !*#"DUJPO protocol FooViewDelegate: class { func onSubmit(value: String) } class FooView: UIView { /* ... */ weak var delegate: FooViewDelegate? var foo: Foo? { didSet { setNeedsLayout() } } override func layoutSubviews() { super.layoutSubviews() /* fooを描画 */ } } 'PP7JFX class FooViewController: UIViewController { @IBOutlet weak var fooView: FooView? { didSet { fooView?.delegate = self } } /* ... */ } extension FooViewController: FooViewDelegate { func onSubmit(value: String) { /* … */ } } 'PP7JFX$POUSPMMFS ᖤա͞Εͨ ૢ࡞ EFMFHBUF σʔλ ࢦࣔ QSPQFSUZTFU NFUIPEDBMM ඳը QSPQFSUZTFU

Slide 43

Slide 43 text

J04ͷ7JFX࣮૷ ௒ෳࡶͳը໘ • 7JFX$POUSPMMFSͷ࢓ࣄ͕ଟ͍ͳΒ"QQMJDBUJPO૚ͷΫϥεʹ೚ ͤͯ͠·͏ Submit TextText TextTextTextTextText TextTextText TextText TextTextText 9JC ඳը QSPQFSUZTFU ੜૢ࡞ !*#"DUJPO σʔλ ࢦࣔ QSPQFSUZTFU NFUIPEDBMM ᖤա͞Εͨ ૢ࡞ EFMFHBUF class FooView: UIView { /* ... */ } 'PP7JFX class FooViewController : UIViewController, PlayerUI { /* ... */ } 'PP7JFX$POUSPMMFS 1MBZFS6* ΋ͬͱ ᖤա͞Εͨ ૢ࡞ NFUIPEDBMM Πϕϯτ EFMFHBUF 1MBZFS$PSF

Slide 44

Slide 44 text

"OESPJEͷ7JFX࣮૷ ௒γϯϓϧͳը໘ • ௒؆୯ͳը໘Ͱ͋ΔͳΒ,PUMJO"OESPJE&YUFOTJPOTͰ"DUJWJUZ ͔Β6*ύʔπΛͦͷ··ૢ࡞ YNM 閉じるボタン import kotlinx.android.synthetic.main.fooview.* class FooActivity : FragmentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.fooview) buttonView.setOnClickListener { /* … */ } } }

Slide 45

Slide 45 text

"OESPJEͷ7JFX࣮૷ ΍΍ෳࡶͳը໘ • ෳࡶͳը໘ͳΒͰ"OESPJE"SDIJUFDUVSF$PNQPOFOUTͷ 7JFX.PEFM-JWF%BUBͱ%BUB#JOEJOHΛ׆༻ • J04ͱൺֱ͢Δͱɺߏ଄͸ಉ͡Ͱ΋ΧελϜ7JFXΛ࡞Βͳͯ͘ྑ͍৔໘͕ ຆͲʹͳΔΠϝʔδ YNM Submit TextText TextTextTextTextText TextTextText TextText TextTextText class FooViewModel : ViewModel() { interface Listener { fun onSubmit() } var listener: Listener? by weakVar() val foo = MutableLiveData() fun onClickSubmitButton() { listener?.onSubmit() } } ૒ํ޲ #JOEJOH class FooActivity : FragmentActivity() { override fun onCreate( savedInstanceState: Bundle?) { /* BindingとViewModelの⽤意 */ model.listener = this } } } σʔλ QSPQFSUZTFU ᖤա͞Εͨ ૢ࡞ EFMFHBUF

Slide 46

Slide 46 text

"OESPJEͷ7JFX࣮૷ ௒ෳࡶͳը໘ • "DUJWJUZ'SBHNFOUͷ࢓ࣄ͕ଟ͍ͳΒ"QQMJDBUJPO૚ͷΫϥεʹ ೚ͤͯ͠·͏ Submit TextText TextTextTextTextText TextTextText TextText TextTextText 9JC σʔλ ࢦࣔ QSPQFSUZTFU NFUIPEDBMM ᖤա͞Εͨ ૢ࡞ EFMFHBUF class FooViewModel: ViewModel() { /* ... */ } 'PP7JFX.PEFM 'PP"DUJWJUZ 1MBZFS6* ΋ͬͱ ᖤա͞Εͨ ૢ࡞ NFUIPEDBMM Πϕϯτ EFMFHBUF 1MBZFS$PSF class FooActivity : FragmentActivity(), PlayerUI { override fun onCreate() { /* … */ } } ૒ํ޲ #JOEJOH

Slide 47

Slide 47 text

঺հ͸Ҏ্Ͱ͢ ೗ԿͰͨ͠Ͱ͠ΐ͏͔ʁ

Slide 48

Slide 48 text

8FBSFIJSJOH IUUQTTVHBSDPSQKQ

Slide 49

Slide 49 text

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