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

React Nativeで作るiOSアプリケーションの環境構築設計 / react nativ...

Kou
March 29, 2019

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

Kou

March 29, 2019
Tweet

More Decks by Kou

Other Decks in Programming

Transcript

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

    e Ͱ ࡞ Δ i O S Ξ ϓ Ϧ έ ʔ γ ϣ ϯ ͷ ؀ ڥ ߏ ங ઃ ܭ WEBΤϯδχΞษڧձ #12 Koichi Nagaoka
  2. • JavaScript / TypeScriptΛ࢖ͬͯɺReactΛ࢖ͬͨiOS /AndroidΞ ϓϦέʔγϣϯ͕࡞ΕΔɻiOSʹಛʹڧ͍ɻ (Ұ࣌ظະରԠͰ໰ ୊ʹͳͬͨAndroid 64bitରԠ΋ v0.59

    ͔ΒߦΘΕ͍ͯ·͢ʂ) • Redux΍MobXͱ͍ͬͨWebͰ΋ར༻ՄೳͳΞʔΩςΫνϟʔ΋ ͦͷ··࢖͑Δ • JSͷมߋ൓ө͕΄΅ҰॠɻϗοτϦϩʔυʹ΋ରԠ͍ͯ͠Δɻ ౎౓Ϗϧυ͠ͳ͍ͱ൓өͰ͖ͳ͍ωΠςΟϒʹൺ΂Δͱૉૣ͘ मਖ਼֬ೝ͕͠΍͍͢ React Nativeʹ͍ͭͯ
  3. #!/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 ౳Λ഑ஔͯ͠ॳճʹ։ൃऀʹ ࣮ߦͯ͠΋Β͏Α͏ʹ͠·͢ɻ
  4. લड़ͷͱ͓ΓReact Native͸ v0.57 ͔ΒBabel7ͷTypeScriptα ϙʔτΛར༻ͯ͠TypeScriptʹରԠ͍ͯ͠·͢ɻͨͩ͜͠ͷ Babel7ͷTypeScriptαϙʔτ͸ܕνΣοΫʹ͍ͭͯ͸ tsc ʹ೚ ͤΔલఏͱͳ͍ͬͯΔͨΊɺ݁ہ tsc

    ͕ඞཁʹͳΓ·͢ɻͦͷ ͨΊɺҎԼͷϞδϡʔϧ͕ඞཁʹͳΓ·͢ɻ 2-1. TypeScriptؔ࿈ͷґଘؔ܎Λ௥Ճ͢Δ • typescript • @types/react • @types/react-native
  5. 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 Λఆ͓ٛͯ͘͠ͷ͕͓ ͢͢ΊͰ͢ɻ
  6. 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ଆͰσίϨʔλΛղऍ ͢ΔͨΊʹඞཁͳઃఆʹͳΓ·͢ɻ
  7. Clean Architecture͸ Robert Cecil Martin ࢯʹΑͬͯఏএ͞Εͨ ΞʔΩςΫνϟʔͷҰछͰ͢ɻ؆୯ʹݴ͏ͱΫϥε෼͚Λࡉ͔ ͘ߦ͏͜ͱͰɺMVC΍MVPͰ໰୊ʹͳΓ͕ͪͩͬͨFat Controller΍Fat Presenterͱ͍ͬͨΫϥε͕ൃੜͮ͠Β͘ͳΔ

    ΑΓΫϦʔϯͳઃܭͱͳΓɺςετίʔυ͕ॻ͖΍͘͢ͳΓ· ͢ɻৄࡉͳઃܭʹ͍ͭͯ͸ωοτʹ΋Α͘঺հ͞Ε͍ͯΔͷ Ͱɺ͜͜Ͱ͸ׂѪ͍͖ͤͯͨͩ͞·͢ɻ Clean Architectureͱ͸
  8. ೖྗσʔλͷྲྀΕʹ͍ͭͯ͸ҎԼͷ௨Γͱ͍ͯ͠·͢ɻ 1. ΠϯλʔϑΣʔε૚ (interface) 2. ΞϓϦέʔγϣϯ૚ (application) 3. υϝΠϯ૚ (domain)

    4. ΠϯϑϥετϥΫνϟ૚ (infrastructure) ·ͨɺ্هͷ૚ʹՃ͑ͯҎԼͷ۠෼ͷΫϥε(Ͳͷ૚͔Β΋ݺΜͰྑ͍)͕ఆٛ͞Ε͍ͯ ·͢ɻ ઃఆ (config) ϢʔςΟϦςΟʔ (util) ֤૚ͷσʔλͷྲྀΕʹ͍ͭͯ
  9. 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 ͱ͍͏ϑΝ Πϧ໊ͱ͠·͢)
  10. 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();
  11. 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΁ڞ༗͢Δ͜ͱ)
  12. 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 ωΠςΟϒϒϦοδͱ͸
  13. // // 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Λ௥Ճ͢Δ
  14. ࠨͷΑ͏ʹ 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) { // ... ॲཧ } }
  15. ·ͱΊΔͱɺ௥Ճͨ͠SwiftΫϥε͸ҎԼͷϧʔϧʹ४ڌ͢ Δඞཁ͕͋Γ·͢ɻ 1. NSObjectΛܧঝ͍ͯ͠Δ͜ͱ 2. Ϋϥεϔομʹ @objc(Ϋϥε໊) Λهड़͢Δ͜ͱ 3. staticͰBoolΛฦ͢requiresMainQueueSetupϝιουΛ࣮૷͢Δ͜ͱ

    4. ֤ϝιουʹ΋ @objc ΞϊςʔγϣϯΛهड़͢Δ͜ͱ ͋ͱ͸͜ΕʹՃ͑ͯɺ࢖༻Մೳͳܕ΋Ұ෦ͷܕʹ੍ݶ͞Ε ͍ͯ·͢ɻ(ಠࣗͷΫϥεܕ͸ෆՄɻৄࡉ͸ެࣜΛࢀর) 4-2. SwiftͰΫϥεϑΝΠϧΛ௥Ճ͢Δ(2)
  16. import { NativeModules } from 'react-native'; export class VoiceSession {

    private readonly session = NativeModules.VoiceSession; public start(callback: () => void): void { this.session.start(callback); } } JSଆͷରԠΫϥε࡞੒ྫ
  17. React Native͕ඪ४Ͱ͸αϙʔτ͍ͯ͠ͳ͍ media query Λ style ʹͯαϙʔτ͢ΔͨΊͷϥΠϒϥϦͰ͢ɻϋοΩϦݴͬ ͯɺ͜ͷϥΠϒϥϦ͕ͳ͍ͱReact NativeͰσΟεϓϨΠαΠ ζ͕ҟͳΔෳ਺୺຤ରԠΛߦ͏ͷ͕ਏ͘ͳͬͯ͠·͍·͢ɻ͜

    ͷϥΠϒϥϦΛ࢖͏͜ͱͰը໘෯ʹԠͯ͡ελΠϧΛม͑ͨ Γɺ·ͨඪ४Ͱ͸Ͱ͖ͳ͍ʮ100% - 24ʯͷΑ͏ͳϒϥ΢βͰ ͍͏calcಉ౳ͷࢦఆ΋ՄೳʹͳΔͷͰɺϨΠΞ΢τͷ͠΍͢͞ ͕֨ஈʹ޲্͠·͢ɻੋඇಋೖ͠·͠ΐ͏ɻ 4-3. react-native-extended-stylesheet
  18. T H A N K Y O U ͝ ੩

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