Slide 1

Slide 1 text

R e a c t N a t i v e Ͱ ࡞ Δ i O S Ξ ϓ Ϧ έ ʔ γ ϣ ϯ ͷ ؀ ڥ ߏ ங ઃ ܭ WEBΤϯδχΞษڧձ #12 Koichi Nagaoka

Slide 2

Slide 2 text

௕Ԭ ߒҰ (@kkoudev) ࣗݾ঺հ גࣜձࣾϛΫγΟͰΤϯδχΞ΍ͬͯ·͢ɻ

Slide 3

Slide 3 text

mocriʢ΋͘Γʣͱ͍͏Ի੠௨࿩ΞϓϦͷiOSϕʔλ൛ΛTestFlightܦ༝ͰϦϦʔε͠·ͨ͠ʂ ͜ͷΞϓϦέʔγϣϯ΋React NativeͰ࡞ΒΕ͍ͯ·͢ʂ ʢৄࡉ͸ https://mocri.jp ͔ Twitterͷ @mocri_jp ΁ʂ) ϕʔλ൛ΛϦϦʔε͠·ͨ͠ʂʂ

Slide 4

Slide 4 text

• JavaScript / TypeScriptΛ࢖ͬͯɺReactΛ࢖ͬͨiOS /AndroidΞ ϓϦέʔγϣϯ͕࡞ΕΔɻiOSʹಛʹڧ͍ɻ (Ұ࣌ظະରԠͰ໰ ୊ʹͳͬͨAndroid 64bitରԠ΋ v0.59 ͔ΒߦΘΕ͍ͯ·͢ʂ) • Redux΍MobXͱ͍ͬͨWebͰ΋ར༻ՄೳͳΞʔΩςΫνϟʔ΋ ͦͷ··࢖͑Δ • JSͷมߋ൓ө͕΄΅ҰॠɻϗοτϦϩʔυʹ΋ରԠ͍ͯ͠Δɻ ౎౓Ϗϧυ͠ͳ͍ͱ൓өͰ͖ͳ͍ωΠςΟϒʹൺ΂Δͱૉૣ͘ मਖ਼֬ೝ͕͠΍͍͢ React Nativeʹ͍ͭͯ

Slide 5

Slide 5 text

React Native͸্ख͘࢖͍͜ͳͤ͹ωΠςΟϒͷΈͰ։ൃ͢Δ ΑΓ͸։ൃ͠΍͘͢ͳΓ·͕͢ɺͦΕʹ͸ΞʔΩςΫνϟʔͷ ઃܭ΍؀ڥߏஙɺϥΠϒϥϦͷબఆ͕ඇৗʹॏཁʹͳ͖ͬͯ· ͢ɻ Ͱ͕͢ɺ͜ͷ఺ʹಥͬࠐΜͩղઆ͸ެؚࣜΊͯগͳ͍ͨΊɺࠓ ճ͸iOSΞϓϦέʔγϣϯΛReact NativeͰ࡞੒͢Δ্Ͱͷ؀ ڥߏஙઃܭʹ͍ͭͯղઆக͠·͢ɻ

Slide 6

Slide 6 text

1. ϓϩδΣΫτઃఆͷ CocoaPodsԽ

Slide 7

Slide 7 text

React NativeͷiOSΞϓϦέʔγϣϯͰωΠςΟϒϞδϡʔϧ (react-native linkΛ͢Δඞཁͷ͋Δ΋ͷ)Λ௥Ճ͢ΔࡍɺiOSଆ ͸Podfileʹґଘؔ܎Λ௥Ճ͢Δ΋ͷ͕ۙ೥ͩͱຆͲͰ͢ɻ ୠ͠ɺreact-native init Ͱ࡞੒ͨ͠ϓϩδΣΫτ͸CocoaPodsͰ ґଘؔ܎Λ؅ཧ͢ΔΑ͏ʹͳ͍ͬͯͳ͍ͨΊɺቕͬͨܦݧͷ͋ Δํ΋ଟ͍ͱࢥ͍·͢ɻରࡦ͸৭ʑ͋ΔͷͰ͕͢ɺࠓճ͸ݸਓ తʹҰ൪׬݁ͱࢥΘΕΔಛʹผ్ύεमਖ਼͢ΔgemͳͲΛ௥Ճ ͤͣͱ΋ରԠՄೳͳํ๏Λ঺հ͠·͢ɻ React Nativeͷґଘؔ܎ͷCocoaPodsԽʹ͍ͭͯ

Slide 8

Slide 8 text

react-native initͰ࡞੒ͨ͠ϓϩδΣΫτʹCocoaPodsΛಋೖ͠ ·͢ɻiosσΟϨΫτϦʹXcodeͷϓϩδΣΫτ(*.xcodeproj)͕ ͋ΔͷͰɺxcworkspaceΛ৽نʹ࡞੒্ͨ͠Ͱ͜ΕΛPodsϓϩ δΣΫτͱҰॹʹ͠ɺCocoaPodsͷґଘؔ܎ΛಡΈࠐΊΔϓϩ δΣΫτͱ͠·͢ɻ (CocoaPodsࣗମͷಋೖํ๏͸ެࣜαΠτʹৄ͘͠ॻ͍ͯ͋Δ ͨΊׂѪ͠·͢) 1-1. CocoaPodsΛಋೖ͢Δ

Slide 9

Slide 9 text

react-native initͰ࡞੒ͨ͠ϓϩδΣΫτ͸ҎԼͷΩϟϓνϟʹ ͋ΔΑ͏ʹෳ਺ͷXcodeϓϩδΣΫτΛґଘؔ܎ʹઃఆ͍ͯ͠ ·͢ɻ 1-2. Build Phasesʹ͋ΔεΫϦϓτΛ֎ग़͠ ͜ͷதʹ͋ΔʮReact.xcodeprojʯͷBuild Phasesʹ͋ΔεΫϦϓτΛγΣϧεΫϦϓ τͱͯ͠֎ग़͠͠·͢ɻ

Slide 10

Slide 10 text

React.xcodeprojͷର৅Build Phases

Slide 11

Slide 11 text

React.xcodeprojͷBuild Phase֎ग़͠ޙ ৔ॴ͸ϓϩδΣΫτ഑ԼͳΒͲ͜Ͱ΋ Α͍Ͱ͕͢ɺ͜ͷྫͰ͸ϓϩδΣΫτ ϧʔτʹ scripts ͱ͍͏σΟϨΫτϦΛ ࡞੒͠ɺͦͷதʹϑΝΠϧΛ഑ஔͯ͠ ͍·͢ɻ

Slide 12

Slide 12 text

Build PhasesΛ֎ग़ͨ͠͠ΒɺLibraries഑Լ ͷϓϩδΣΫτΛશͯΞϓϦέʔγϣϯͷґ ଘؔ܎͔Β࡟আ͠·͢ɻ(ࢀরͷΈ࡟আ͠ɺ ݩϑΝΠϧࣗମ͸࡟আ͠ͳ͍Ͱ࢒͓͍ͯͯ͠ ͍ͩ͘͞) 1-3. React Nativeґଘؔ܎ProjectΛ࡟আ͢Δ

Slide 13

Slide 13 text

࣮͸React Nativeͷxcodeproj܈͸શͯ podspec ϑΝΠϧ͕༻ ҙ͞Ε͍ͯΔͨΊɺCocoaPodsͰґଘؔ܎ͱͯ͠ࢦఆ͢Δ͜ͱ ͕ՄೳͰ͢ɻ۩ମతʹ͸ node_modules/react-native ഑Լʹ͍ ͋ΔҎԼͷ podspec ϑΝΠϧΛPodfileʹهड़͠·͢ɻ 1-4. React Nativeґଘؔ܎ProjectΛCocoaPodsԽ

Slide 14

Slide 14 text

React Nativeґଘؔ܎Λࢦఆͨ͠CocoaPodsͷPodfile ※Reactͷґଘؔ܎഑Լͷ subspecs͸React Native ͷόʔδϣϯʹΑͬͯมԽ ͠·͢ɻࢦఆՄೳͳ subspec͸ React.podspec ʹهࡌ͞Ε͍ͯΔͷͰ֬ ೝͯ͠Έ͍ͯͩ͘͞ɻ ※use_frameworksʹ͸ඇ ରԠͳͷͰ஫ҙʂʂ

Slide 15

Slide 15 text

React Nativeຊମ͕࢖͍ͬͯΔthird-party੡ϥΠϒϥϦͰ͋Δɺ yogaɺFollyɺDoubleConversionɺglog͸ຊདྷͰ͋Ε͹react- native run-iosΛ࣮ߦͨ͠ࡍʹࣗಈతʹϑΝΠϧ͕ల։͞ΕΔΑ ͏ʹͳ͍ͬͯΔ͕ɺCocoaPodsԽ͢Δʹ͋ͨͬͯ͸༧ΊϑΝΠ ϧΛల։͓ͯ͘͠ඞཁ͕͋ΔͨΊɺखಈ࣮ߦ͢ΔεΫϦϓτΛ ࡞੒͓͖ͯ͠·͢ɻ 1-5. third-party੡ϥΠϒϥϦͷల։εΫϦϓτ࡞੒

Slide 16

Slide 16 text

#!/bin/bash readonly PROJECT_DIR="$(cd ${0%/*}/.. && pwd)" readonly GLOG_VERSION="0.3.5" cd ${PROJECT_DIR}/node_modules/react-native && ./scripts/ios-install-third-party.sh cd ${PROJECT_DIR}/node_modules/react-native/third-party/glog-${GLOG_VERSION} && ${PROJECT_DIR}/node_modules/react- native/scripts/ios-configure-glog.sh ࡞੒ͨ͠third-party੡ϥΠϒϥϦల։εΫϦϓτྫ ※React NativeͷnpmϞδϡʔϧ಺ʹల։༻ͷεΫϦϓτ͕͋Δ͕ɺ ͦͷεΫϦϓτ͕ΠϚΠνͳ࡞ΓͷͨΊɺ্هͷΑ͏ʹσΟϨΫτ ϦҠಈ͔ͯ͠Β࣮ߦ͠ͳ͍ͱਖ਼ৗʹల։ͯ͘͠Εͳ͍ɻ ͜ΕΛϓϩδΣΫτϧʔτʹ setup.sh ౳Λ഑ஔͯ͠ॳճʹ։ൃऀʹ ࣮ߦͯ͠΋Β͏Α͏ʹ͠·͢ɻ

Slide 17

Slide 17 text

͜͜·Ͱग़དྷͨΒɺҰ౓ ios σΟϨΫτϦ഑ԼͰ pod ίϚϯυ Λ࣮ߦ͠ɺਖ਼ৗʹίϚϯυ͕׬ྃ͢Δ͜ͱΛ֬ೝͯͩ͘͠͞ ͍ɻࣦഊ͢Δ৔߹͸Podfile಺ͷࢦఆ͕ؒҧ͍ͬͯΔͷͰ֬ೝ͠ ͯΈ͍ͯͩ͘͞ɻ(ಛʹ use_frameworks ʹ͍ͭͯ͸ඇରԠͳͷ Ͱࢦఆ͠ͳ͍Ͱ͍ͩ͘͞) 1-6. CocoaPodsΛ࣮ߦͯ͠ਖ਼ৗ׬ྃ͢Δ͜ͱΛ֬ೝ͢Δ

Slide 18

Slide 18 text

1-2ͷखॱͰ֎ग़ͨ͠͠React.xcodeprojʹ͋ͬͨBuild PhaseΛ ΞϓϦέʔγϣϯຊମͷXcodeϓϩδΣΫτͷBuild Phase΁௥ Ճ͠ɺ࡞੒ͨ͠εΫϦϓτ(*.sh)ΛͦΕͧΕݺͼग़͢Α͏ʹͯ͠ ͓͖·͢ɻ 1-7. XcodeϓϩδΣΫτ΁Build PhasesΛ௥Ճ͢Δ

Slide 19

Slide 19 text

Build PhasesΛ௥Ճޙͷঢ়ଶ

Slide 20

Slide 20 text

Ҏ্ͰCocoaPodsԽ͸׬ྃͰ͢ɻ react-native linkͨ͠ࡍʹ௥ՃՄೳͳωΠςΟϒϞδϡʔϧ͸͜ ͷํ๏ΛऔΒͳ͍ͱReact Nativeؔ࿈ͷϔομϑΝΠϧ౳͕Π ϯΫϧʔυͰ͖ͳͯ͘ϏϧυΤϥʔʹͳΔ΋ͷ΋͋Γ·͢ɻ React Native΋ؚΊͯCocoaPodsͷґଘؔ܎ͱͯ͠ࢦఆ͢Δ͜ ͱͰωΠςΟϒϏϧυؔ࿈ͷ໰୊͸΄΅ͳ͘ͳΔͷͰɺੋඇͱ ΋͜ͷํ๏ΛऔΔ͜ͱΛਪ঑͍ͨ͠·͢ɻ

Slide 21

Slide 21 text

2. TypeScriptͷಋೖ

Slide 22

Slide 22 text

react-native initͰ࡞੒ͨ͠React NativeϓϩδΣΫτ͸v0.57͔ ΒTypeScriptΛਖ਼ࣜʹαϙʔτ͢ΔΑ͏ʹͳΓ·ͨ͠ɻ TypeScriptΛ࢖Θͳͯ͘΋։ൃ͸ՄೳͰ͕͢ɺܕ͕ͳ͍ͱΤσ Ολͷิ׬ػೳͷԸܙΛड͚ΒΕͳ͔ͬͨΓɺϦϑΝΫλϦϯ ά͕ͮ͠Β͘ͳΔͱ͍ͬͨσϝϦοτ͕ଟ͘ൃੜ͢ΔͨΊɺن ໛͕େ͖͘ͳΕ͹ͳΔ΄Ͳਏ͘ͳΓ·͢ɻ ͦͷͨΊɺTypeScriptΛಋೖ͠·͢ɻ TypeScriptͷඞཁੑ

Slide 23

Slide 23 text

લड़ͷͱ͓ΓReact Native͸ v0.57 ͔ΒBabel7ͷTypeScriptα ϙʔτΛར༻ͯ͠TypeScriptʹରԠ͍ͯ͠·͢ɻͨͩ͜͠ͷ Babel7ͷTypeScriptαϙʔτ͸ܕνΣοΫʹ͍ͭͯ͸ tsc ʹ೚ ͤΔલఏͱͳ͍ͬͯΔͨΊɺ݁ہ tsc ͕ඞཁʹͳΓ·͢ɻͦͷ ͨΊɺҎԼͷϞδϡʔϧ͕ඞཁʹͳΓ·͢ɻ 2-1. TypeScriptؔ࿈ͷґଘؔ܎Λ௥Ճ͢Δ • typescript • @types/react • @types/react-native

Slide 24

Slide 24 text

tsconfigʹ͍ͭͯ͸ҎԼͷ఺Λ࠷௿ݶઃఆ͍ͯͩ͘͠͞ɻ 2-2. tsconfigͷઃఆΛߦ͏ • jsxΛ react-native ʹ͢Δ • noEmit Λ true ʹ͢Δ (ܕνΣοΫ͚͕ͩ໨తͷͨΊ) • allowSyntheticDefaultImports Λ true ʹ͢Δ • experimentalDecorators Λ true ʹ͢Δ (MobXΛ࢖͏ͳΒඞਢ) ͋ͱ͸ package.json ͷ scripts ʹ tsc Λ࣮ߦ͢ΔλεΫΛ௥Ճ͠·͢ɻྫͱ͠ ͯreact-native run-ios ͱ tsc -w Λฒྻ࣮ߦ͢Δ scripts Λఆ͓ٛͯ͘͠ͷ͕͓ ͢͢ΊͰ͢ɻ

Slide 25

Slide 25 text

JavaScript / TypeScriptʹΑΔ import ͸௨ৗ͸૬ରύεͰಡΈ ࠐΉઃఆͱͳ͍ͬͯ·͢ɻͨͩ͠ɺ૬ରύεͩͱϑΝΠϧͷҐ ஔʹΑͬͯ import ύε͕௕͘ͳͬͯ͠·͏͹͔Γ͔ɺϑΝΠϧ ΛҠಈ͢Δͱ؆୯ʹΤϥʔʹͳͬͯ͠·͏ͨΊɺอकੑͷѱ͍ ίʔυʹͳͬͯ͠·͍·͢ɻͦ͜ͰɺಛఆͷจࣈྻΛࢦఆͨ͠ ઈରύεࢦఆͰ import ͕ग़དྷΔΑ͏ʹରԠ͠·͢ɻ 2-3. ઈରύεʹΑΔimportͷઃఆ

Slide 26

Slide 26 text

·ͣτϥϯεύΠϧ࣌ʹઈରύεΛղऍͰ͖ΔΑ͏ʹઃఆ͠· ͢ɻ۩ମతʹ͸ babel-plugin-module-resolver Λ௥Ճ ͠ɺ.babelrcϑΝΠϧ·ͨ͸babel.config.js΁هड़Λ௥Ճ͠· ͢ɻ babel-plugin-module-resolver ʹ͍ͭͯ͸ 3.1.1 Λࢦఆͯ͠௥Ճ ͢ΔΑ͏ʹ͍ͯͩ͘͠͞ɻͦΕҎ߱ͷόʔδϣϯͩͱBabel7ର Ԡʹෆඋ͕͋Δͷ͔ɺ͏·͘ಈ࡞͠ͳ͍৔߹͕͋Γ·͢ɻ Babelͷઃఆͷฤू

Slide 27

Slide 27 text

module.exports = { presets: [ 'module:metro-react-native-babel-preset', ], plugins: [ [ '@babel/plugin-proposal-decorators', { legacy: true } ], [ 'module-resolver', { root: ['./src'], extensions: ['.js', '.ios.js', '.android.js'], alias: { '@/*': './src/', } } ] ] }; babel.config.jsͷઃఆྫ ͜ͷઃఆΛߦ͏͜ͱͰɺsrcσΟϨΫτ Ϧ഑ԼͷϑΝΠϧΛʮ@/ʯͰࢦఆͰ͖ ΔΑ͏ʹͳΓ·͢ɻ ͪͳΈʹ͜ͷྫʹ͞Γ͛ͳ͋͘Δ @babel/plugin-proposal-decorators ʹ ͍ͭͯ͸BabelଆͰσίϨʔλΛղऍ ͢ΔͨΊʹඞཁͳઃఆʹͳΓ·͢ɻ

Slide 28

Slide 28 text

BabelଆͰઈରύεͷղऍ͸ՄೳʹͳΓ·͕ͨ͠ɺtscʹΑΔܕ νΣοΫͱ͸ผઃఆͳͷͰɺtsconfigʹ΋ઈରύεಡΈࠐΈͷ ઃఆ͕ඞཁʹͳΓ·͢ɻ͜ͷล͕৑௕ઃఆײ͕͋ͬͯগʑΠέ ͯͳ͍Ͱ͕͢ɺBabel7͕͜ͷΑ͏ͳରԠελΠϧΛऔ͍ͬͯΔ ͨΊ࢓ํͳ͘ઃఆ͠·͢ɻtsconfigʹ͸ҎԼͷઃఆΛ௥Ճ͠· ͢ɻ tsconfigͷઃఆͷฤू

Slide 29

Slide 29 text

ίʔυνΣοΫͷͨΊʹESLintΛಋೖ͠·͢ɻҰੲલ·Ͱ͸ TSLintͱ͍͏Linter͕TypeScriptͰ͸ओྲྀͰ͕ͨ͠ɺ2019೥ʹ ͳͬͯTypeScriptνʔϜ͕ ESLint΁Ҡߦ͢Δ͜ͱΛൃද͍ͯ͠ ·͢ɻ۩ମతʹ͸ɺҎԼͷϞδϡʔϧΛಋೖͯ͠ઃఆ͠·͢ɻ (ઃఆํ๏ʹ͍ͭͯ͸ެࣜΛࢀরͷ͜ͱ) ESLintͷઃఆ • @typescript-eslint/eslint-plugin • eslint • eslint-plugin-node • eslint-plugin-react

Slide 30

Slide 30 text

Ҏ্ͰTypeScriptԽ͸׬ྃͰ͢ɻ TypeScript͸௥Ճ͢ΔϞδϡʔϧ͕ύοέʔδ಺ʹఆٛϑΝΠ ϧΛಉ͍ࠝͯ͠Δ΋ͷ΋͋Ε͹ɺreact-nativeຊମͷΑ͏ʹ @types/react-native ͱ͍ͬͨΑ͏ʹDefinitelyTypedʹΞοϓϩ ʔυ͞Ε͍ͯΔϑΝΠϧΛΠϯετʔϧ͢Δ৔߹΋͋Γ·͢ɻ ͨͩதʹ͸ͲͪΒʹ΋ఆٛϑΝΠϧ͕ଘࡏ͠ͳ͍έʔε΋͋Δ ͨΊɺͦͷ৔߹͸ࣗ෼ͰఆٛϑΝΠϧΛࣗ෼Ͱॻ͔͘ɺimport Ͱ͸ͳ͘requireͰಡΈࠐΜͰ࢖͏Α͏ʹ͍ͯͩ͘͠͞ɻ

Slide 31

Slide 31 text

3. Clean Architectureͷಋೖ

Slide 32

Slide 32 text

Clean Architecture͸ Robert Cecil Martin ࢯʹΑͬͯఏএ͞Εͨ ΞʔΩςΫνϟʔͷҰछͰ͢ɻ؆୯ʹݴ͏ͱΫϥε෼͚Λࡉ͔ ͘ߦ͏͜ͱͰɺMVC΍MVPͰ໰୊ʹͳΓ͕ͪͩͬͨFat Controller΍Fat Presenterͱ͍ͬͨΫϥε͕ൃੜͮ͠Β͘ͳΔ ΑΓΫϦʔϯͳઃܭͱͳΓɺςετίʔυ͕ॻ͖΍͘͢ͳΓ· ͢ɻৄࡉͳઃܭʹ͍ͭͯ͸ωοτʹ΋Α͘঺հ͞Ε͍ͯΔͷ Ͱɺ͜͜Ͱ͸ׂѪ͍͖ͤͯͨͩ͞·͢ɻ Clean Architectureͱ͸

Slide 33

Slide 33 text

Clean Architecture͸ઃܭ͕៉ྷʹͳΓɺ1ͭͷϑΝΠϧʹॲཧ ͕ूத͠ͳ͍ར఺Λ࣋ͪ߹Θ͍ͤͯ·͕͢ɺϑΝΠϧ਺΍Ϋϥ ε͕ඇৗʹଟ͘ͳͬͯ͠·͏ܽ఺Λ๊͍͑ͯ·͢ɻ ࣮ࡍʹClean ArchitectureΛ࠷ॳʹ࠾༻ͯ͠͠·͏ͱɺ͋·Γͷ ϑΝΠϧ਺ͷଟ͞ʹ׳Εͣʹ࠳ંͯ͠͠·͍͕ͪͰ͢ɻ ͱ͸͍͑ɺ៉ྷͳઃܭΛ࠷ॳʹߦ͓ͬͯ͘ͱޙͷػೳվम࣌ʹ ͸༗རͰ͢ɻͦͷͨΊɺ͋Δఔ౓ॲཧΛ·ͱΊΔ͜ͱΛڐ༰͠ ͨઃܭΛ࠾༻͢Δ͜ͱʹ͠·ͨ͠ɻ Clean Architectureͷར఺ͱܽ఺

Slide 34

Slide 34 text

mocriͰ͸Layered ArchitectureɺOnion ArchitectureΛϕʔεʹ Clean ArchitectureΛҰ෦ΞϨϯδ͠ɺ͔ͭMobXͱͷ૬ੑΛߟ ͑ͨઃܭΛ࠾༻͠·ͨ͠ɻ Clean ArchitectureΛҰ෦ΞϨϯδ͢Δ

Slide 35

Slide 35 text

Clean ArchitectureΛ࠾༻ͨ͠σΟϨΫτϦߏ଄

Slide 36

Slide 36 text

ೖྗσʔλͷྲྀΕʹ͍ͭͯ͸ҎԼͷ௨Γͱ͍ͯ͠·͢ɻ 1. ΠϯλʔϑΣʔε૚ (interface) 2. ΞϓϦέʔγϣϯ૚ (application) 3. υϝΠϯ૚ (domain) 4. ΠϯϑϥετϥΫνϟ૚ (infrastructure) ·ͨɺ্هͷ૚ʹՃ͑ͯҎԼͷ۠෼ͷΫϥε(Ͳͷ૚͔Β΋ݺΜͰྑ͍)͕ఆٛ͞Ε͍ͯ ·͢ɻ ઃఆ (config) ϢʔςΟϦςΟʔ (util) ֤૚ͷσʔλͷྲྀΕʹ͍ͭͯ

Slide 37

Slide 37 text

͜ͷ૚͸UIʹؔ࿈͢Δ૚ʹͳΓ·͢ɻControllerͱPresenterɺ ·֤ͨը໘΍ίϯϙʔωϯτͷϏϡʔ (tsx) Λఆ͍ٛͯ͠· ͢ɻControllerͱPresenter͸interfaceͱ࣮૷ΫϥεΛఆٛ͠· ͢ɻ֤ίϯϙʔωϯτͷΠϕϯτʹ͍ͭͯ͸Controller͕ॲཧΛ ͠ɺͦͷController͕গ͠ෳࡶͳॲཧΛ͢Δࡍ͸UseCaseΛݺ ͼग़͢ͱ͍͏ϧʔϧʹ͍ͯ͠·͢ɻ ·ͨɺMobXΛ࢖͏্Ͱ observable ͱͳΔঢ়ଶ஋ʹ͍ͭͯ͸ɺ ͜ͷ૚ʹ͋Δ Presenter ʹ࣋ͨͤΔΑ͏ʹ͍ͯ͠·͢ɻ interface૚ʹ͍ͭͯ

Slide 38

Slide 38 text

͜ͷ૚͸UseCaseΛఆ͍ٛͯ͠·͢ɻUseCase͸Ϗδωεϩδ οΫΛ࢘ΔΫϥεʹͳΓ·͢ɻ͜͜Ͱ΋interfaceͱ࣮૷Ϋϥε Λఆٛ͠·͢ɻຊདྷͷClean Architectureͩͱ̍ΞΫγϣϯʹͭ ͖̍ͭͷॲཧΛUseCaseͰఆٛ͢ΔΑ͏ʹݴΘΕ͍ͯ·͕͢ɺ ͦΕͩͱ͋·ΓʹϑΝΠϧ͕૿͑͗ͯ͢͠·͏ͷͰɺ1ίϯϙ ʔωϯτ(ը໘ؚΉ)ʹରͯ͠1ͭͷUseCaseΫϥεΛఆٛ͠ɺ֤ ίϯϙʔωϯτͷϏδωεϩδοΫΛ͜ͷUseCaseΫϥεʹه ࡌ͢Δͱ͍͏ϧʔϧͱ͠·ͨ͠ɻ application૚ʹ͍ͭͯ

Slide 39

Slide 39 text

͜ͷ૚͸model, repository, service, value, factoryΛఆٛ͠· ͢ɻapplication૚ͷUseCaseͱͷେ͖ͳҧ͍͸ɺશը໘΍ίϯ ϙʔωϯτͰڞ௨ར༻͞ΕΔϏδωεϩδοΫ΍छผΛఆٛ͢ Δͱ͍͏ϧʔϧͱ͍ͯ͠·͢ɻrepositoryͱservice͸͜͜Ͱ͸ interfaceͱͯ͠ఆٛ͠·͢ɻ domain૚ʹ͍ͭͯ

Slide 40

Slide 40 text

͜ͷ૚͸domain૚ͷrepositoryͱserviceͷ࣮૷Ϋϥε(຤ඌImpl ͷΫϥε)ͷ͏ͪɺ֎෦σʔλʹґଘ͢ΔॲཧΛఆٛ͠·͢ɻ API௨৴ͷ࣮૷΍ɺAsyncStorage΁ͷอଘʹ͍ͭͯ΋͜ͷ૚ʹ ࣮ࡍͷॲཧΛهड़͠·͢ɻ infrastructure૚ʹ͍ͭͯ

Slide 41

Slide 41 text

֤૚ͷinterfaceΫϥεͱ࣮૷Ϋϥεʹ͍ͭͯ͸ɺDIΛ͔ͭͬͯ ΠϯελϯεΛઃఆ͠·͢ɻ͜ΕΛReact NativeͰߦ͏ʹ͸ inversify ͱ͍͏ϥΠϒϥϦΛಋೖ͠·͢ɻ ґଘੑ஫ೖ(DI)ʹ͍ͭͯ

Slide 42

Slide 42 text

import 'reflect-metadata'; import { Container } from 'inversify'; // ίϯςφΛ࡞੒͢Δ export const container = new Container(); /** * ґଘؔ܎छผ */ export const IOCType = { // Launch LaunchController: Symbol('LaunchController'), LaunchPresenter: Symbol('LaunchPresenter'), LaunchUseCase: Symbol('LaunchUseCase'), }; Inversifyͷ࢖༻ྫ (1) ֤࣮૷ΫϥεʹରԠ͢ΔछผΛ SymbolͰఆٛ͠·͢ɻ͜ͷͱ ͖ɺಉ͡ϑΝΠϧʹ Container Ϋ ϥεͷΠϯελϯεΛSingletonΠ ϯελϯεͱͯ͠ఆ͓͖ٛͯ͠· ͢ɻ(ྫͱͯ͠ɺioc.ts ͱ͍͏ϑΝ Πϧ໊ͱ͠·͢)

Slide 43

Slide 43 text

Inversifyͷ࢖༻ྫ (2) interfaceͱରԠ͢Δ࣮૷Ϋϥεͷඥ ෇͚Λߦ͍·͢ɻ͜ͷͱ͖ɺ౎౓Π ϯελϯεੜ੒͢Δ͔Singleton͔Λ બͿ͜ͱ͕Ͱ͖·͢ɻجຊతʹ domain૚ͷ΋ͷ͸Singleton (ঢ়ଶΛ ࣋ͨͤͳ͍ͨΊ)ɺͦΕҎ֎͸֤ʑͰ ঢ়ଶΛ͍࣋ͪͨͷͰɺ౎౓Πϯελ ϯεੜ੒Λߦ͍·͢ɻ·ͨɺ࣮૷Ϋ ϥεʹ͸ @injectable ͷσίϨʔλ ʔΛ෇༩͍ͯͩ͘͠͞ɻ import { container, IOCType } from './ioc'; // ౎౓Πϯελϯεੜ੒͢Δ৔߹͸ to ·ͰΛݺͼग़ͤ͹OK container.bind(IOCType.LaunchController) .to(LaunchControllerImpl); container.bind(IOCType.LaunchPresenter) .to(LaunchPresenterImpl); container.bind(IOCType.LaunchUseCase) .to(LaunchUseCaseImpl); // Singletonʹ͢Δ৔߹͸ inSingletonScope Λݺͼग़͓ͯ͘͠ container.bind(IOCType.AuthRepository) .to(AuthRepositoryImpl).inSingletonScope();

Slide 44

Slide 44 text

Inversifyͷ࢖༻ྫ (3) import { IOCType, container } from './ioc'; /** * ىಈը໘ίϯτϩʔϥʔ࣮૷ */ @injectable() export class LaunchControllerImpl implements ILaunchController { /** * ىಈը໘Ϣʔεέʔε */ private readonly usecase: ILaunchUseCase = container.get(IOCType.LaunchUseCase); // .... লུ .... } ͋ͱ͸ར༻͍ͨ͠Controller΍UseCase ಺ͰϑΟʔϧυఆٛͱҰॹʹݺͼग़͠ ·͢ɻPresenterͷΠϯελϯε͸ঢ়ଶ ஋Λ͍࣋ͬͯΔؔ܎্ɺController΍ UseCaseͰผΠϯελϯεΛੜ੒͠ͳ ͍Α͏ʹɺඞཁʹԠͯ͡Πϯελϯε Λڞ༗ͭͭ͠ѻ͍·͢ɻ(Controllerͱ UseCaseͰಉPresenterΛࢀর͚ͨ͠Ε ͹ControllerͰ࡞੒ͨ͠ΠϯελϯεΛ UseCase΁ڞ༗͢Δ͜ͱ)

Slide 45

Slide 45 text

Ҏ্ͰClean Architectureͷ؆୯ͳઆ໌͸׬ྃͰ͢ɻ ͜ͷઃܭΛ࠾༻ͨ͜͠ͱͰɺ୭͕࣮૷ͯ͠΋΄΅ϒϨͷͳ͍Ϋ ϥεઃܭΛ୲อ͠΍͘͢ͳΓ·ͨ͠ɻ ·ͨɺClean Architecture͸Ұݟૣ͘࡞Δ͜ͱʹॏ͖Λஔ͍ͨε λʔτΞοϓͷαʔϏεʹ͸ෆ޲͖Ͱ͕͢ɺ͍ΘΏΔෛͷҨ࢈ Λ૿΍֬͢཰͸֨ஈʹݮΔͷͱɺ଎౓Λ༏ઌͯ͠૿΍ͨ͠ෛͷ Ҩ࢈ͷճऩʹ࣌ؒΛऔΒΕͯ݁ہτʔλϧͰ͸ಉ͘͡Β͍࣌ؒ ͕͔͔Δͱ͍͏έʔε΋͋ΔͷͰɺέʔεʹ͸ΑΓ·͕͋͢Δ ఔ౓͸͔ͬ͠Γઃܭͯ͠࡞͓ͬͯ͘͜ͱΛ͓͢͢Ί͠·͢ɻ

Slide 46

Slide 46 text

4. ωΠςΟϒϒϦοδͷઃఆ

Slide 47

Slide 47 text

React NativeͷΞϓϦέʔγϣϯ͸શͯJavaScript / TypeScript Ͱॻ͚Δ͜ͱʹӽͨ͜͠ͱ͸ͳ͍ͷͰ͕͢ɺఏڙ͞Ε͍ͯͳ͍ ػೳʹ͍ͭͯ͸Ͳ͏ͯ͠΋ωΠςΟϒͷॲཧΛॻ͘ඞཁ͕ग़ͯ ͖·͢ɻReact Native͸ඪ४ͰωΠςΟϒϒϦοδͷͨΊͷ࢓ ૊ΈΛఏڙͯ͘͠ΕΔͷͰɺϧʔϧʹԊͬͯॻ͚ͩ͘ͰOKͰ ͢ɻ ※iOS 12.2ʹ͓͍ͯSwiftར༻࣌ͷωΠςΟϒϒϦοδʹࣦഊ͢Δෆ۩߹͕͋ΔͨΊɺҎԼͷ Issue͕ղܾ͍ͯ͠ͳ͍৔߹͸ iOS 12.1 (Xcode 10.1)ͰϏϧυ͢ΔΑ͏ʹ͍ͯͩ͘͠͞ https://github.com/facebook/react-native/issues/24139 ωΠςΟϒϒϦοδͱ͸

Slide 48

Slide 48 text

React NativeͷΞϓϦέʔγϣϯ͸ react-native init Ͱ࡞੒ͨ͠ ঢ়ଶͷ··ͩͱObjective-C͔͠࢖͑·ͤΜɻͦ͜ͰɺԿ͔̍ͭ swiftϑΝΠϧΛ௥Ճ͢ΔͱɺBridge-HeaderϑΝΠϧ(*.h)Λ௥ Ճ͢ΔΑ͏ʹଅ͞ΕΔͷͰૉ௚ʹ௥Ճ͠·͢ɻ͜ΕʹΑͬͯɺ Swiftؔ࿈ͷϏϧυઃఆ΋ϓϩδΣΫτʹ௥Ճ͞Ε·͢ɻ࣍ʹɺ ࡞੒͞ΕͨBridge-HeaderϑΝΠϧʹ֤छϔομΛ #import ͠ ·͢ɻ 4-1. ϒϦοδϔομΛ௥Ճ͢Δ

Slide 49

Slide 49 text

// // Use this file to import your target's public headers that you would like to expose to Swift. // #import #import #import ϒϦοδϔομʹ#importΛ௥Ճ͢Δ

Slide 50

Slide 50 text

ࠨͷΑ͏ʹ Swift ͰΫϥεΛ࡞੒͠· ͢ɻݟͯͷ௨Γɺ@objcΞϊςʔγϣ ϯ͕هࡌ͞Ε͍ͯ·͢ɻSwift͕هड़ Ͱ͖Δͱ͍ͬͯ΋࠷ऴతʹ͸ObjCͱ ͯ͠ղऍͤ͞Δඞཁ͕͋ΔͨΊɺ͜ ͷΑ͏ʹهࡌ͢Δඞཁ͕͋Γ·͢ɻ 4-2. SwiftͰΫϥεϑΝΠϧΛ௥Ճ͢Δ(1) @objc(VoiceSession) class VoiceSession: NSObject { @objc static func requiresMainQueueSetup() -> Bool { return true } @objc func start(_ callback: RCTResponseSenderBlock) { // ... ॲཧ } }

Slide 51

Slide 51 text

·ͱΊΔͱɺ௥Ճͨ͠SwiftΫϥε͸ҎԼͷϧʔϧʹ४ڌ͢ Δඞཁ͕͋Γ·͢ɻ 1. NSObjectΛܧঝ͍ͯ͠Δ͜ͱ 2. Ϋϥεϔομʹ @objc(Ϋϥε໊) Λهड़͢Δ͜ͱ 3. staticͰBoolΛฦ͢requiresMainQueueSetupϝιουΛ࣮૷͢Δ͜ͱ 4. ֤ϝιουʹ΋ @objc ΞϊςʔγϣϯΛهड़͢Δ͜ͱ ͋ͱ͸͜ΕʹՃ͑ͯɺ࢖༻Մೳͳܕ΋Ұ෦ͷܕʹ੍ݶ͞Ε ͍ͯ·͢ɻ(ಠࣗͷΫϥεܕ͸ෆՄɻৄࡉ͸ެࣜΛࢀর) 4-2. SwiftͰΫϥεϑΝΠϧΛ௥Ճ͢Δ(2)

Slide 52

Slide 52 text

࣍ʹɺObjective-CͷϞδϡʔϧϑΝΠϧ(*.m)Λ௥Ճ͠·͢ɻઌ ͷεϥΠυͰ঺հͨ͠SwiftͰ࡞੒ͨ͠ΫϥεʹରԠ͢ΔܗͰɺ ࣍ͷΑ͏ʹهड़͠·͢ɻ 4-3. Objective-CͷϞδϡʔϧϑΝΠϧΛ௥Ճ͢Δ

Slide 53

Slide 53 text

#import @interface RCT_EXTERN_MODULE(VoiceSession, NSObject) RCT_EXTERN_METHOD(start:(RCTResponseSenderBlock)callback) @end ௥Ճ͢ΔObjective-CͷϞδϡʔϧϑΝΠϧྫ

Slide 54

Slide 54 text

4-4. JSଆͷରԠίʔυͷ࡞੒ ͋ͱ͸ରԠ͢ΔΫϥεΛJSଆͰ࡞੒͢Ε͹ݺͼग़͕͠Մೳʹͳ Γ·͢ɻωΠςΟϒϒϦοδͷ໭Γ஋ʹ͍ͭͯ͸ɺ Callback(RCTResponseSenderBlock)·ͨ͸ Promise(RCTPromiseResolveBlockͱRCTPromiseRejectBlock) ʹͯඇಉظͰड͚औΔ࢓༷ʹͳ͍ͬͯ·͢ɻ͜Ε͸JS͕ಈ࡞͢ ΔεϨουͱωΠςΟϒ͕ಈ࡞͢ΔεϨου͕ҟͳΔͨΊɺ͜ ͷΑ͏ͳ࢓༷ͱͳ͍ͬͯ·͢ɻ

Slide 55

Slide 55 text

import { NativeModules } from 'react-native'; export class VoiceSession { private readonly session = NativeModules.VoiceSession; public start(callback: () => void): void { this.session.start(callback); } } JSଆͷରԠΫϥε࡞੒ྫ

Slide 56

Slide 56 text

Ҏ্ͰωΠςΟϒϒϦοδͷઆ໌͸׬ྃͰ͢ɻ ωΠςΟϒϒϦοδ͸ଟ༻͢ΔͱiOSͱAndroidͷΫϩεϓϥο τϑΥʔϜͰΞϓϦΛ࡞੒͢Δࡍʹ͸ͦͷ෼ωΠςΟϒίʔυ Λॻ͘ඞཁ͸ग़͖ͯͯ͠·͍·͕͢ɺReact Native͚ͩͰ͸࣮ ݱͰ͖ͳ͍ػೳΛ࣮ݱ͢Δ্Ͱ͸ඞਢʹͳΓ·͢ɻmocriͰ͸ gRPCͰϧʔϜؔ࿈ͷػೳΛ࣮ݱ͍ͯ͠Δؔ܎Ͱɺreact-native Ͱ͸࢖͑ͳ͍gRPCωΠςΟϒͷॲཧΛSwiftͰهड़͍ͯ͠· ͢ɻ͜ͷΑ͏ͳέʔεʹ΋ඞਢͱͳΔͨΊɺωΠςΟϒϒϦο δͷ࢓ํ͚ͩͰ΋͓֮͑ͯ͘͜ͱΛ͓קΊ͠·͢ɻ

Slide 57

Slide 57 text

5. ಋೖਪ঑ϥΠϒϥϦ

Slide 58

Slide 58 text

ͦΕͰ͸࠷ޙʹɺiOSΞϓϦέʔγϣϯΛ࡞Δ্ͰΑ͘࢖͏ͱ ࢥΘΕΔReact NativeͰ࢖༻ՄೳͳϥΠϒϥϦΛ঺հ͍ͨ͠· ͢ɻ ಋೖਪ঑ϥΠϒϥϦʹ͍ͭͯ

Slide 59

Slide 59 text

React Native͸ΞϓϦέʔγϣϯىಈ࣌(εϓϥογϡը໘දࣔ ޙ)ʹɺJSϑΝΠϧΛϩʔυ͢ΔͨΊʹҰॠը໘͕ਅͬനʹͳ ΔλΠϛϯά͕͋Γ·͢ɻ͜ΕΛ๷ࢭ͢Δͷ͕ react-native- splash-screen Ͱ͢ɻͳΔ΂͘ωΠςΟϒΞϓϦʹ͍ۙܗΛ໨ ࢦ͢ͷͰ͋Ε͹ɺੋඇͱ΋ಋೖ͢Δ͜ͱΛ͓͢͢Ί͠·͢ɻ 4-1. react-native-splash-screen

Slide 60

Slide 60 text

React Nativeʹ͓͚Δը໘ભҠΛߦ͏ϥΠϒϥϦͰ͢ɻ ͜Ε͕ͳ͍ͱΞϓϦΛ࡞Δͷ͸೉͍͠ͱ͍͏͘Β͍ը໘ભҠʹ ͍ͭͯ͸͜ΕʹউΔ΋ͷ͕ͳ͍Ͱ͢ɻϓογϡʹΑΔը໘ભ ҠɺϞʔμϧʹΑΔը໘ભҠΛ࢝Ίɺλϒόʔͷαϙʔτ΋͠ ͍ͯ·͢ɻiOSωΠςΟϒΞϓϦͷ࡞੒ʹ׳Ε͍ͯΔͱͦͷҧ ͍͔Βएׯށ࿭͏͜ͱ͸͋Γ·͕͢ɺ׳ΕΕ͹ඇৗʹ࢖͍΍͢ ͍ϥΠϒϥϦͰ͢ɻ 4-2. react-navigation

Slide 61

Slide 61 text

React Native͕ඪ४Ͱ͸αϙʔτ͍ͯ͠ͳ͍ media query Λ style ʹͯαϙʔτ͢ΔͨΊͷϥΠϒϥϦͰ͢ɻϋοΩϦݴͬ ͯɺ͜ͷϥΠϒϥϦ͕ͳ͍ͱReact NativeͰσΟεϓϨΠαΠ ζ͕ҟͳΔෳ਺୺຤ରԠΛߦ͏ͷ͕ਏ͘ͳͬͯ͠·͍·͢ɻ͜ ͷϥΠϒϥϦΛ࢖͏͜ͱͰը໘෯ʹԠͯ͡ελΠϧΛม͑ͨ Γɺ·ͨඪ४Ͱ͸Ͱ͖ͳ͍ʮ100% - 24ʯͷΑ͏ͳϒϥ΢βͰ ͍͏calcಉ౳ͷࢦఆ΋ՄೳʹͳΔͷͰɺϨΠΞ΢τͷ͠΍͢͞ ͕֨ஈʹ޲্͠·͢ɻੋඇಋೖ͠·͠ΐ͏ɻ 4-3. react-native-extended-stylesheet

Slide 62

Slide 62 text

؀ڥม਺ͷઃఆΛߦ͏ͨΊͷϥΠϒϥϦͰ͢ɻ React NativeͰ͸ىಈ࣌ʹ؀ڥม਺Λઃఆͨ͠ͱͯ͠΋ɺ NODE_ENVҎ֎ͷ஋Λ౉͢͜ͱ͸Ͱ͖ͳ͍ͷͱɺ͔ͭͦͷ NODE_ENV΋ development ·ͨ͸ production Ҏ֎͸ઃఆͰ͖ ͳ͍Α͏ʹͳͬͯ·͢ɻ͜ͷϥΠϒϥϦΛ࢖͏ͱଞͷ؀ڥม਺ ΋౉͢͜ͱ͕ՄೳʹͳΓ·͢ɻ 4-4. react-native-config

Slide 63

Slide 63 text

ϒϥ΢βͰ௨৴Λߦ͏ࡍ΋͓ೃછΈͷ axios Ͱ͕͢ɺReact NativeͰ΋࢖͑·͢ɻ΋ͪΖΜ࢖Θͳͯ͘΋௨৴ॲཧΛॻ͘͜ ͱ͸ՄೳͰ͕͢ɺaxiosͷrequest΍responseͷinterceptorͳͲ ͷ࢓૊Έ͸ඇৗʹศརͰ࢖͍΍͍ͨ͢Ίɺ௨৴ॲཧΛ࡞੒͢Δ ࡍ͸ axios Λϥοϓͨ͠ΫϥΠΞϯτΫϥεΛ࡞Δ͜ͱΛ͓͢ ͢Ί͠·͢ɻ 4-5. axios

Slide 64

Slide 64 text

ϞʔμϧදࣔΛߦ͏ϙοϓΞοϓͷ࣮૷ʹ࢖͑ΔϥΠϒϥϦͰ ͢ɻReact Native͸ඪ४Ͱ΋ModalίϯϙʔωϯτΛ΋͍ͬͯ ·͕͢ɺͪ͜Β͸ඪ४ΑΓ΋ߴػೳͰ͢ɻ͜ΕΛ͸͡Ίͱ͠ ͨɺGithubͷreact-native-communityͷorganizationʹͯ։ൃ͞ Ε͍ͯΔϥΠϒϥϦ͸ɺReact Nativeඪ४ػೳΛผϥΠϒϥϦ ΁෼཭ͯ͠։ൃ͓ͯ͠Γɺجຊతʹ͸ react-native-community ͷํ͕ػೳ͕๛෋ͱͳ͍ͬͯ·͢ɻ 4-6. react-native-modal

Slide 65

Slide 65 text

iOSͷSafe AreaΛ࣮ݱ͢ΔͨΊͷϥΠϒϥϦͱͳΓ·͢ɻ react-navigationΛ࢖͍ͬͯΔը໘Ͱ͸ࣗಈతʹ͜ͷϥΠϒϥϦ Λ࢖ͬͯSafe AreaΛ࣮ݱ͍ͯ͠·͕͢ɺϙοϓΞοϓ(Modal) ͷΑ͏ʹreact-navigationΛܦ༝͠ͳ͍έʔεͰඞཁʹͳ͖ͬͯ ·͢ɻiOSʹ͓͍ͯ͸ඞਢͱͳΔϥΠϒϥϦͳͷͰੋඇಋೖ͠ ·͠ΐ͏ɻ 4-7. react-native-safe-area-view

Slide 66

Slide 66 text

άϥσʔγϣϯΛ࣮ݱ͢ΔϥΠϒϥϦͰ͢ɻ React Native͸ඪ४Ͱ͸άϥσʔγϣϯΛαϙʔτ͍ͯ͠ͳ͍ ͨΊɺ͜ͷϥΠϒϥϦΛ࢖ͬͯάϥσʔγϣϯΛ࣮ݱ͢Δඞཁ ͕͋Γ·͢ɻ 4-8. react-native-linear-gradient

Slide 67

Slide 67 text

SVGλάΛReact NativeͰ࢖͑ΔΑ͏ʹ͢ΔϥΠϒϥϦͰ͢ɻ mocriͰ͸ԁܗͷΦϒδΣΫτ΍Ξχϝʔγϣϯ͕ొ৔͢Δͨ Ίɺ͜ͷreact-native-svgΛ࢖͏͜ͱͰ࣮ݱ͍ͯ͠·͢ɻ 4-9. react-native-svg

Slide 68

Slide 68 text

·ͱΊ

Slide 69

Slide 69 text

React Native͸iOSωΠςΟϒͰΞϓϦέʔγϣϯΛ࡞੒͢Δ ͷʹ׳ΕͨํͷதͰ΋ɺAutoLayout΍௕͍Ϗϧυ࣌ؒʹۤ͠Ί ΒΕͨํʹ͸ಛʹΦεεϝͷπʔϧͰ͢ɻ ωΠςΟϒΞϓϦΛ࡞ͬͨܦݧͷͳ͍WebͰReact͔͠΍ͬͨ ͜ͱͳ͍ํͰ΋࡞ΕΔͷ͔ɺͱݴΘΕΔͱͦ͏͍͏Θ͚Ͱ͸ͳ ͍Ͱ͕͢ɺͦ͏͍͏ํʹ΋͋Δఔ౓͸ͱ͖ͬͭ΍͍͢఺΋ϙΠ ϯτͱͯ͠͸ߴ͍͔ͱࢥ͍·͢ɻಛʹΫϩεϓϥοτϑΥʔϜ ͰͱΓ͋͑ͣΞϓϦΛग़͍ͨ͠ͱ͍͏ελʔτΞοϓʹ͓͍ͯ ͸༗ӹͳπʔϧͳͷͰɺͦͷΑ͏ͳέʔεͰ͸ੋඇಋೖΛݕ౼ ͢Δ͜ͱΛ͓͢͢Ίக͠·͢ɻ

Slide 70

Slide 70 text

T H A N K Y O U ͝ ੩ ௌ ͋ Γ ͕ ͱ ͏ ͝ ͟ ͍ · ͠ ͨ