Upgrade to Pro — share decks privately, control downloads, hide ads and more …

React Nativeで作るiOSアプリケーションの環境構築設計 / react native env for ios

7f95c6712be7d9a89aae7b9b152dad90?s=47 Kou
March 29, 2019

React Nativeで作るiOSアプリケーションの環境構築設計 / react native env for ios

7f95c6712be7d9a89aae7b9b152dad90?s=128

Kou

March 29, 2019
Tweet

Transcript

  1. R e a c t N a t i v

    e Ͱ ࡞ Δ i O S Ξ ϓ Ϧ έ ʔ γ ϣ ϯ ͷ ؀ ڥ ߏ ங ઃ ܭ WEBΤϯδχΞษڧձ #12 Koichi Nagaoka
  2. ௕Ԭ ߒҰ (@kkoudev) ࣗݾ঺հ גࣜձࣾϛΫγΟͰΤϯδχΞ΍ͬͯ·͢ɻ

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

  4. • JavaScript / TypeScriptΛ࢖ͬͯɺReactΛ࢖ͬͨiOS /AndroidΞ ϓϦέʔγϣϯ͕࡞ΕΔɻiOSʹಛʹڧ͍ɻ (Ұ࣌ظະରԠͰ໰ ୊ʹͳͬͨAndroid 64bitରԠ΋ v0.59

    ͔ΒߦΘΕ͍ͯ·͢ʂ) • Redux΍MobXͱ͍ͬͨWebͰ΋ར༻ՄೳͳΞʔΩςΫνϟʔ΋ ͦͷ··࢖͑Δ • JSͷมߋ൓ө͕΄΅ҰॠɻϗοτϦϩʔυʹ΋ରԠ͍ͯ͠Δɻ ౎౓Ϗϧυ͠ͳ͍ͱ൓өͰ͖ͳ͍ωΠςΟϒʹൺ΂Δͱૉૣ͘ मਖ਼֬ೝ͕͠΍͍͢ React Nativeʹ͍ͭͯ
  5. React Native͸্ख͘࢖͍͜ͳͤ͹ωΠςΟϒͷΈͰ։ൃ͢Δ ΑΓ͸։ൃ͠΍͘͢ͳΓ·͕͢ɺͦΕʹ͸ΞʔΩςΫνϟʔͷ ઃܭ΍؀ڥߏஙɺϥΠϒϥϦͷબఆ͕ඇৗʹॏཁʹͳ͖ͬͯ· ͢ɻ Ͱ͕͢ɺ͜ͷ఺ʹಥͬࠐΜͩղઆ͸ެؚࣜΊͯগͳ͍ͨΊɺࠓ ճ͸iOSΞϓϦέʔγϣϯΛReact NativeͰ࡞੒͢Δ্Ͱͷ؀ ڥߏஙઃܭʹ͍ͭͯղઆக͠·͢ɻ

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

  7. React NativeͷiOSΞϓϦέʔγϣϯͰωΠςΟϒϞδϡʔϧ (react-native linkΛ͢Δඞཁͷ͋Δ΋ͷ)Λ௥Ճ͢ΔࡍɺiOSଆ ͸Podfileʹґଘؔ܎Λ௥Ճ͢Δ΋ͷ͕ۙ೥ͩͱຆͲͰ͢ɻ ୠ͠ɺreact-native init Ͱ࡞੒ͨ͠ϓϩδΣΫτ͸CocoaPodsͰ ґଘؔ܎Λ؅ཧ͢ΔΑ͏ʹͳ͍ͬͯͳ͍ͨΊɺቕͬͨܦݧͷ͋ Δํ΋ଟ͍ͱࢥ͍·͢ɻରࡦ͸৭ʑ͋ΔͷͰ͕͢ɺࠓճ͸ݸਓ

    తʹҰ൪׬݁ͱࢥΘΕΔಛʹผ్ύεमਖ਼͢ΔgemͳͲΛ௥Ճ ͤͣͱ΋ରԠՄೳͳํ๏Λ঺հ͠·͢ɻ React Nativeͷґଘؔ܎ͷCocoaPodsԽʹ͍ͭͯ
  8. react-native initͰ࡞੒ͨ͠ϓϩδΣΫτʹCocoaPodsΛಋೖ͠ ·͢ɻiosσΟϨΫτϦʹXcodeͷϓϩδΣΫτ(*.xcodeproj)͕ ͋ΔͷͰɺxcworkspaceΛ৽نʹ࡞੒্ͨ͠Ͱ͜ΕΛPodsϓϩ δΣΫτͱҰॹʹ͠ɺCocoaPodsͷґଘؔ܎ΛಡΈࠐΊΔϓϩ δΣΫτͱ͠·͢ɻ (CocoaPodsࣗମͷಋೖํ๏͸ެࣜαΠτʹৄ͘͠ॻ͍ͯ͋Δ ͨΊׂѪ͠·͢) 1-1. CocoaPodsΛಋೖ͢Δ

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

  10. React.xcodeprojͷର৅Build Phases

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

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

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

    ϑΝΠϧΛPodfileʹهड़͠·͢ɻ 1-4. React Nativeґଘؔ܎ProjectΛCocoaPodsԽ
  14. React Nativeґଘؔ܎Λࢦఆͨ͠CocoaPodsͷPodfile ※Reactͷґଘؔ܎഑Լͷ subspecs͸React Native ͷόʔδϣϯʹΑͬͯมԽ ͠·͢ɻࢦఆՄೳͳ subspec͸ React.podspec ʹهࡌ͞Ε͍ͯΔͷͰ֬

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

  16. #!/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 ౳Λ഑ஔͯ͠ॳճʹ։ൃऀʹ ࣮ߦͯ͠΋Β͏Α͏ʹ͠·͢ɻ
  17. ͜͜·Ͱग़དྷͨΒɺҰ౓ ios σΟϨΫτϦ഑ԼͰ pod ίϚϯυ Λ࣮ߦ͠ɺਖ਼ৗʹίϚϯυ͕׬ྃ͢Δ͜ͱΛ֬ೝͯͩ͘͠͞ ͍ɻࣦഊ͢Δ৔߹͸Podfile಺ͷࢦఆ͕ؒҧ͍ͬͯΔͷͰ֬ೝ͠ ͯΈ͍ͯͩ͘͞ɻ(ಛʹ use_frameworks ʹ͍ͭͯ͸ඇରԠͳͷ

    Ͱࢦఆ͠ͳ͍Ͱ͍ͩ͘͞) 1-6. CocoaPodsΛ࣮ߦͯ͠ਖ਼ৗ׬ྃ͢Δ͜ͱΛ֬ೝ͢Δ
  18. 1-2ͷखॱͰ֎ग़ͨ͠͠React.xcodeprojʹ͋ͬͨBuild PhaseΛ ΞϓϦέʔγϣϯຊମͷXcodeϓϩδΣΫτͷBuild Phase΁௥ Ճ͠ɺ࡞੒ͨ͠εΫϦϓτ(*.sh)ΛͦΕͧΕݺͼग़͢Α͏ʹͯ͠ ͓͖·͢ɻ 1-7. XcodeϓϩδΣΫτ΁Build PhasesΛ௥Ճ͢Δ

  19. Build PhasesΛ௥Ճޙͷঢ়ଶ

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

  21. 2. TypeScriptͷಋೖ

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

  23. લड़ͷͱ͓ΓReact Native͸ v0.57 ͔ΒBabel7ͷTypeScriptα ϙʔτΛར༻ͯ͠TypeScriptʹରԠ͍ͯ͠·͢ɻͨͩ͜͠ͷ Babel7ͷTypeScriptαϙʔτ͸ܕνΣοΫʹ͍ͭͯ͸ tsc ʹ೚ ͤΔલఏͱͳ͍ͬͯΔͨΊɺ݁ہ tsc

    ͕ඞཁʹͳΓ·͢ɻͦͷ ͨΊɺҎԼͷϞδϡʔϧ͕ඞཁʹͳΓ·͢ɻ 2-1. TypeScriptؔ࿈ͷґଘؔ܎Λ௥Ճ͢Δ • typescript • @types/react • @types/react-native
  24. 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 Λఆ͓ٛͯ͘͠ͷ͕͓ ͢͢ΊͰ͢ɻ
  25. JavaScript / TypeScriptʹΑΔ import ͸௨ৗ͸૬ରύεͰಡΈ ࠐΉઃఆͱͳ͍ͬͯ·͢ɻͨͩ͠ɺ૬ରύεͩͱϑΝΠϧͷҐ ஔʹΑͬͯ import ύε͕௕͘ͳͬͯ͠·͏͹͔Γ͔ɺϑΝΠϧ ΛҠಈ͢Δͱ؆୯ʹΤϥʔʹͳͬͯ͠·͏ͨΊɺอकੑͷѱ͍

    ίʔυʹͳͬͯ͠·͍·͢ɻͦ͜ͰɺಛఆͷจࣈྻΛࢦఆͨ͠ ઈରύεࢦఆͰ import ͕ग़དྷΔΑ͏ʹରԠ͠·͢ɻ 2-3. ઈରύεʹΑΔimportͷઃఆ
  26. ·ͣτϥϯεύΠϧ࣌ʹઈରύεΛղऍͰ͖ΔΑ͏ʹઃఆ͠· ͢ɻ۩ମతʹ͸ babel-plugin-module-resolver Λ௥Ճ ͠ɺ.babelrcϑΝΠϧ·ͨ͸babel.config.js΁هड़Λ௥Ճ͠· ͢ɻ babel-plugin-module-resolver ʹ͍ͭͯ͸ 3.1.1 Λࢦఆͯ͠௥Ճ

    ͢ΔΑ͏ʹ͍ͯͩ͘͠͞ɻͦΕҎ߱ͷόʔδϣϯͩͱBabel7ର Ԡʹෆඋ͕͋Δͷ͔ɺ͏·͘ಈ࡞͠ͳ͍৔߹͕͋Γ·͢ɻ Babelͷઃఆͷฤू
  27. 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ଆͰσίϨʔλΛղऍ ͢ΔͨΊʹඞཁͳઃఆʹͳΓ·͢ɻ
  28. BabelଆͰઈରύεͷղऍ͸ՄೳʹͳΓ·͕ͨ͠ɺtscʹΑΔܕ νΣοΫͱ͸ผઃఆͳͷͰɺtsconfigʹ΋ઈରύεಡΈࠐΈͷ ઃఆ͕ඞཁʹͳΓ·͢ɻ͜ͷล͕৑௕ઃఆײ͕͋ͬͯগʑΠέ ͯͳ͍Ͱ͕͢ɺBabel7͕͜ͷΑ͏ͳରԠελΠϧΛऔ͍ͬͯΔ ͨΊ࢓ํͳ͘ઃఆ͠·͢ɻtsconfigʹ͸ҎԼͷઃఆΛ௥Ճ͠· ͢ɻ tsconfigͷઃఆͷฤू

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

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

  31. 3. Clean Architectureͷಋೖ

  32. Clean Architecture͸ Robert Cecil Martin ࢯʹΑͬͯఏএ͞Εͨ ΞʔΩςΫνϟʔͷҰछͰ͢ɻ؆୯ʹݴ͏ͱΫϥε෼͚Λࡉ͔ ͘ߦ͏͜ͱͰɺMVC΍MVPͰ໰୊ʹͳΓ͕ͪͩͬͨFat Controller΍Fat Presenterͱ͍ͬͨΫϥε͕ൃੜͮ͠Β͘ͳΔ

    ΑΓΫϦʔϯͳઃܭͱͳΓɺςετίʔυ͕ॻ͖΍͘͢ͳΓ· ͢ɻৄࡉͳઃܭʹ͍ͭͯ͸ωοτʹ΋Α͘঺հ͞Ε͍ͯΔͷ Ͱɺ͜͜Ͱ͸ׂѪ͍͖ͤͯͨͩ͞·͢ɻ Clean Architectureͱ͸
  33. Clean Architecture͸ઃܭ͕៉ྷʹͳΓɺ1ͭͷϑΝΠϧʹॲཧ ͕ूத͠ͳ͍ར఺Λ࣋ͪ߹Θ͍ͤͯ·͕͢ɺϑΝΠϧ਺΍Ϋϥ ε͕ඇৗʹଟ͘ͳͬͯ͠·͏ܽ఺Λ๊͍͑ͯ·͢ɻ ࣮ࡍʹClean ArchitectureΛ࠷ॳʹ࠾༻ͯ͠͠·͏ͱɺ͋·Γͷ ϑΝΠϧ਺ͷଟ͞ʹ׳Εͣʹ࠳ંͯ͠͠·͍͕ͪͰ͢ɻ ͱ͸͍͑ɺ៉ྷͳઃܭΛ࠷ॳʹߦ͓ͬͯ͘ͱޙͷػೳվम࣌ʹ ͸༗རͰ͢ɻͦͷͨΊɺ͋Δఔ౓ॲཧΛ·ͱΊΔ͜ͱΛڐ༰͠ ͨઃܭΛ࠾༻͢Δ͜ͱʹ͠·ͨ͠ɻ

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

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

  36. ೖྗσʔλͷྲྀΕʹ͍ͭͯ͸ҎԼͷ௨Γͱ͍ͯ͠·͢ɻ 1. ΠϯλʔϑΣʔε૚ (interface) 2. ΞϓϦέʔγϣϯ૚ (application) 3. υϝΠϯ૚ (domain)

    4. ΠϯϑϥετϥΫνϟ૚ (infrastructure) ·ͨɺ্هͷ૚ʹՃ͑ͯҎԼͷ۠෼ͷΫϥε(Ͳͷ૚͔Β΋ݺΜͰྑ͍)͕ఆٛ͞Ε͍ͯ ·͢ɻ ઃఆ (config) ϢʔςΟϦςΟʔ (util) ֤૚ͷσʔλͷྲྀΕʹ͍ͭͯ
  37. ͜ͷ૚͸UIʹؔ࿈͢Δ૚ʹͳΓ·͢ɻControllerͱPresenterɺ ·֤ͨը໘΍ίϯϙʔωϯτͷϏϡʔ (tsx) Λఆ͍ٛͯ͠· ͢ɻControllerͱPresenter͸interfaceͱ࣮૷ΫϥεΛఆٛ͠· ͢ɻ֤ίϯϙʔωϯτͷΠϕϯτʹ͍ͭͯ͸Controller͕ॲཧΛ ͠ɺͦͷController͕গ͠ෳࡶͳॲཧΛ͢Δࡍ͸UseCaseΛݺ ͼग़͢ͱ͍͏ϧʔϧʹ͍ͯ͠·͢ɻ ·ͨɺMobXΛ࢖͏্Ͱ observable

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

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

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

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

  42. 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 ͱ͍͏ϑΝ Πϧ໊ͱ͠·͢)
  43. Inversifyͷ࢖༻ྫ (2) interfaceͱରԠ͢Δ࣮૷Ϋϥεͷඥ ෇͚Λߦ͍·͢ɻ͜ͷͱ͖ɺ౎౓Π ϯελϯεੜ੒͢Δ͔Singleton͔Λ બͿ͜ͱ͕Ͱ͖·͢ɻجຊతʹ domain૚ͷ΋ͷ͸Singleton (ঢ়ଶΛ ࣋ͨͤͳ͍ͨΊ)ɺͦΕҎ֎͸֤ʑͰ ঢ়ଶΛ͍࣋ͪͨͷͰɺ౎౓Πϯελ

    ϯεੜ੒Λߦ͍·͢ɻ·ͨɺ࣮૷Ϋ ϥεʹ͸ @injectable ͷσίϨʔλ ʔΛ෇༩͍ͯͩ͘͠͞ɻ import { container, IOCType } from './ioc'; // ౎౓Πϯελϯεੜ੒͢Δ৔߹͸ to ·ͰΛݺͼग़ͤ͹OK container.bind<ILaunchController>(IOCType.LaunchController) .to(LaunchControllerImpl); container.bind<ILaunchPresenter>(IOCType.LaunchPresenter) .to(LaunchPresenterImpl); container.bind<ILaunchUseCase>(IOCType.LaunchUseCase) .to(LaunchUseCaseImpl); // Singletonʹ͢Δ৔߹͸ inSingletonScope Λݺͼग़͓ͯ͘͠ container.bind<IAuthRepository>(IOCType.AuthRepository) .to(AuthRepositoryImpl).inSingletonScope();
  44. 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΁ڞ༗͢Δ͜ͱ)
  45. Ҏ্ͰClean Architectureͷ؆୯ͳઆ໌͸׬ྃͰ͢ɻ ͜ͷઃܭΛ࠾༻ͨ͜͠ͱͰɺ୭͕࣮૷ͯ͠΋΄΅ϒϨͷͳ͍Ϋ ϥεઃܭΛ୲อ͠΍͘͢ͳΓ·ͨ͠ɻ ·ͨɺClean Architecture͸Ұݟૣ͘࡞Δ͜ͱʹॏ͖Λஔ͍ͨε λʔτΞοϓͷαʔϏεʹ͸ෆ޲͖Ͱ͕͢ɺ͍ΘΏΔෛͷҨ࢈ Λ૿΍֬͢཰͸֨ஈʹݮΔͷͱɺ଎౓Λ༏ઌͯ͠૿΍ͨ͠ෛͷ Ҩ࢈ͷճऩʹ࣌ؒΛऔΒΕͯ݁ہτʔλϧͰ͸ಉ͘͡Β͍࣌ؒ ͕͔͔Δͱ͍͏έʔε΋͋ΔͷͰɺέʔεʹ͸ΑΓ·͕͋͢Δ

    ఔ౓͸͔ͬ͠Γઃܭͯ͠࡞͓ͬͯ͘͜ͱΛ͓͢͢Ί͠·͢ɻ
  46. 4. ωΠςΟϒϒϦοδͷઃఆ

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

    #import ͠ ·͢ɻ 4-1. ϒϦοδϔομΛ௥Ճ͢Δ
  49. // // Use this file to import your target's public

    headers that you would like to expose to Swift. // #import <React/RCTBridgeModule.h> #import <React/RCTEventDispatcher.h> #import <React/RCTEventEmitter.h> ϒϦοδϔομʹ#importΛ௥Ճ͢Δ
  50. ࠨͷΑ͏ʹ 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) { // ... ॲཧ } }
  51. ·ͱΊΔͱɺ௥Ճͨ͠SwiftΫϥε͸ҎԼͷϧʔϧʹ४ڌ͢ Δඞཁ͕͋Γ·͢ɻ 1. NSObjectΛܧঝ͍ͯ͠Δ͜ͱ 2. Ϋϥεϔομʹ @objc(Ϋϥε໊) Λهड़͢Δ͜ͱ 3. staticͰBoolΛฦ͢requiresMainQueueSetupϝιουΛ࣮૷͢Δ͜ͱ

    4. ֤ϝιουʹ΋ @objc ΞϊςʔγϣϯΛهड़͢Δ͜ͱ ͋ͱ͸͜ΕʹՃ͑ͯɺ࢖༻Մೳͳܕ΋Ұ෦ͷܕʹ੍ݶ͞Ε ͍ͯ·͢ɻ(ಠࣗͷΫϥεܕ͸ෆՄɻৄࡉ͸ެࣜΛࢀর) 4-2. SwiftͰΫϥεϑΝΠϧΛ௥Ճ͢Δ(2)
  52. ࣍ʹɺObjective-CͷϞδϡʔϧϑΝΠϧ(*.m)Λ௥Ճ͠·͢ɻઌ ͷεϥΠυͰ঺հͨ͠SwiftͰ࡞੒ͨ͠ΫϥεʹରԠ͢ΔܗͰɺ ࣍ͷΑ͏ʹهड़͠·͢ɻ 4-3. Objective-CͷϞδϡʔϧϑΝΠϧΛ௥Ճ͢Δ

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

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

  55. import { NativeModules } from 'react-native'; export class VoiceSession {

    private readonly session = NativeModules.VoiceSession; public start(callback: () => void): void { this.session.start(callback); } } JSଆͷରԠΫϥε࡞੒ྫ
  56. Ҏ্ͰωΠςΟϒϒϦοδͷઆ໌͸׬ྃͰ͢ɻ ωΠςΟϒϒϦοδ͸ଟ༻͢ΔͱiOSͱAndroidͷΫϩεϓϥο τϑΥʔϜͰΞϓϦΛ࡞੒͢Δࡍʹ͸ͦͷ෼ωΠςΟϒίʔυ Λॻ͘ඞཁ͸ग़͖ͯͯ͠·͍·͕͢ɺReact Native͚ͩͰ͸࣮ ݱͰ͖ͳ͍ػೳΛ࣮ݱ͢Δ্Ͱ͸ඞਢʹͳΓ·͢ɻmocriͰ͸ gRPCͰϧʔϜؔ࿈ͷػೳΛ࣮ݱ͍ͯ͠Δؔ܎Ͱɺreact-native Ͱ͸࢖͑ͳ͍gRPCωΠςΟϒͷॲཧΛSwiftͰهड़͍ͯ͠· ͢ɻ͜ͷΑ͏ͳέʔεʹ΋ඞਢͱͳΔͨΊɺωΠςΟϒϒϦο δͷ࢓ํ͚ͩͰ΋͓֮͑ͯ͘͜ͱΛ͓קΊ͠·͢ɻ

  57. 5. ಋೖਪ঑ϥΠϒϥϦ

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

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

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

  61. React Native͕ඪ४Ͱ͸αϙʔτ͍ͯ͠ͳ͍ media query Λ style ʹͯαϙʔτ͢ΔͨΊͷϥΠϒϥϦͰ͢ɻϋοΩϦݴͬ ͯɺ͜ͷϥΠϒϥϦ͕ͳ͍ͱReact NativeͰσΟεϓϨΠαΠ ζ͕ҟͳΔෳ਺୺຤ରԠΛߦ͏ͷ͕ਏ͘ͳͬͯ͠·͍·͢ɻ͜

    ͷϥΠϒϥϦΛ࢖͏͜ͱͰը໘෯ʹԠͯ͡ελΠϧΛม͑ͨ Γɺ·ͨඪ४Ͱ͸Ͱ͖ͳ͍ʮ100% - 24ʯͷΑ͏ͳϒϥ΢βͰ ͍͏calcಉ౳ͷࢦఆ΋ՄೳʹͳΔͷͰɺϨΠΞ΢τͷ͠΍͢͞ ͕֨ஈʹ޲্͠·͢ɻੋඇಋೖ͠·͠ΐ͏ɻ 4-3. react-native-extended-stylesheet
  62. ؀ڥม਺ͷઃఆΛߦ͏ͨΊͷϥΠϒϥϦͰ͢ɻ React NativeͰ͸ىಈ࣌ʹ؀ڥม਺Λઃఆͨ͠ͱͯ͠΋ɺ NODE_ENVҎ֎ͷ஋Λ౉͢͜ͱ͸Ͱ͖ͳ͍ͷͱɺ͔ͭͦͷ NODE_ENV΋ development ·ͨ͸ production Ҏ֎͸ઃఆͰ͖ ͳ͍Α͏ʹͳͬͯ·͢ɻ͜ͷϥΠϒϥϦΛ࢖͏ͱଞͷ؀ڥม਺

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

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

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

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

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

  68. ·ͱΊ

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

    ͢Δ͜ͱΛ͓͢͢Ίக͠·͢ɻ
  70. T H A N K Y O U ͝ ੩

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