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

iOS エンジニアが考える Webアプリ開発

Ca8210ff0ece2bb6f9fff5fd0770ea64?s=47 Muukii
April 25, 2018

iOS エンジニアが考える Webアプリ開発

Ca8210ff0ece2bb6f9fff5fd0770ea64?s=128

Muukii

April 25, 2018
Tweet

Transcript

  1. iOS ΤϯδχΞ͕ߟ͑Δ WebΞϓϦ։ൃ muukii

  2. About Me ‣ muukii <Hiroshi Kimura> ‣ iOS Engineer at

    eureka, Inc. ‣ Pairs Global Team ‣ GitHub : @muukii ‣ https://muukii.me ☕ ⌚
  3. None
  4. 1BJSTʹ͍ͭͯ !4

  5. 4PVUI,PSFB Japan Taiwan No.1 2017 release No.1 !5 1BJSTʹ͍ͭͯ ల։ࠃ

    ̐ͭͷϓϥοτϑΥʔϜ CONFIDENTIAL INFORMATION: Not for Public Distribution - Do Not Copy
  6. None
  7. Agenda › ࠷ۙͪΐͬͱͨ͠WebΞϓϦΛ࡞ΔҊ͕݅΍͖ͬͯ·ͨ͠ › ͔ͤͬ͘ͳͷͰେن໛ͳΞϓϦΛ࡞ΔέʔεΛ૝ఆͯ͠΍ͬͯΈ͍ͨ › ΄ͱΜͲ஌͕ࣝͳ͍ঢ়ଶͳͷͰɺ৭ʑௐ΂ͨ͜ͱ › iOSΞϓϦͷUIΛ࡞Γଓ͚͖ͯͨܦݧΛݩʹɺ࠷ۙΠϯϓοτͯ͠ ͍ΔWebΞϓϦ։ൃͷ஌ࣝͰɺେن໛ͳΞϓϦΛ࡞ΔͳΒʮ͜Μͳ

    ײ͡ʹ࡞͍͖͍ͬͯͨͳʔʯͱࢥ͏·ͱΊɻ
  8. ݱঢ়ͷ๻ › Gatsby + Netlify Ͱ੩తαΠτΛ࡞͍ͬͯΔ › React › styled-components

    ͳͲ › TypeScript › VSCode
  9. WebΞϓϦ։ൃΛ࢝ΊΔલͷঢ়ଶ › ࠓ·ͰͣͬͱSwiftΛॻ͍͖ͯͨ › Webͷۀ຿ܦݧͳ͠

  10. WebΞϓϦ։ൃΛ࢝ΊΔલͷঢ়ଶ › ஌ࣝͱͯ͠͸ͦΕͳΓʹΩϟονΞοϓ͍ͯͨ͠ › Ϗϧυπʔϧͷಈ޲ͱ͔ › ΞʔΩςΫνϟͱ͔ › ωΠςΟϒΞϓϦ։ൃ͸WebΞϓϦͷςΫϊϩδʔʹΠϯεύ ΠΞ͞ΕΔ͜ͱ͕ଟ͍ͨΊ

  11. WebΞϓϦ։ൃΛ࢝ΊΔલͷঢ়ଶ › JS΋͋·Γৄ͘͠ͳ͍ › SwiftͰfunctional-programmingͷงғؾʹ৮Ε͍ͯͨ͜ͱͰॿ ͔Δ෦෼͸ଟ͔ͬͨ

  12. WebΞϓϦ։ൃΛ࢝ΊΔલͷঢ়ଶ › CSS͸ཧղ͍ͯ͠Δͭ΋Γʹͳ͍ͬͯΔ › ʮiOSΞϓϦ։ൃͰFlexboxϨΠΞ΢τ৮͍ͬͯΔ͠େৎ෉Ͱ͠ΐ ͏ʯ

  13. ࠷ॳʹ໎ͬͨ͜ͱ › ViewϨΠϠʔͷϑϨʔϜϫʔΫ͸Ͳ͏͢Δ? › Vue? React? › Angular͸Ұ୴͓͍͓ͯ͘ɻ

  14. ࠷ॳʹ໎ͬͨ͜ͱ › ViewपลͷΞʔΩςΫνϟ͸? › PairsͷGlobal൛iOSΞϓϦͰ΋Fluxʹ͍ۙ͜ͱ΍͍ͬͯΔ › ʮ։ൃ͍ͯ͠Δ͏ͪʹFlux, Reduxͱ͔Λߟ͑࢝ΊΔͩΖ͏ ͳʔʯͱߟ͑Δͷ͸ޙճ͠ʹ

  15. ࠷ॳʹ໎ͬͨ͜ͱ › Ͱ͖Ε͹JSͰ΋ʮ੩తܕ෇͚ʯ͸ཉ͍͚͠Ͳ › TypeScript? › Flow?

  16. ࣗ෼ͳΓͷཧղͷਐΊํ › iOSΞϓϦ։ൃͷ஌ࣝʹ౰ͯ͸Ίͯࣗ෼ͳΓʹೲಘ͍ͯ͘͠ελΠϧ

  17. › JSͷڍಈͷཧղ › runkit.com͕Α͔ͬͨ › ૉ੖Β͍͠Playground ✨ › JSͷΦϒδΣΫτͷಈ͖Λ࣮ࡍʹίʔυΛಈ͔࣮ͯ͠ݧ͍ͯ͘͠ ›

    ʮObjective-C΍SwiftͰ͍͏ɺ͜͏͍͏ಈ͖ํʯΈ͍ͨͳΠϯϓοτ ࣗ෼ͳΓͷཧղͷਐΊํ
  18. › Ϗϧυπʔϧͷ΍͍ͬͯΔ͜ͱ͕ຐ๏ʹݟ͑Δ › ͍ΖΜͳϏϧυπʔϧ͋Δ͠ɺ͍ΖΜͳ͜ͱ͕࣮ߦ͞Ε͗ͯ͢ཧղͰ͖Δؾ͕͠ͳ͍... › ͦ΋ͦ΋͜Μͳෳࡶͳ͜ͱ͠ͳ͍ͱWebΞϓϦͬͯ࡞Εͳ͍ͷʁͭΒ͍ͳɻͱࢥͬͨ ͜ͱ΋ɻ › ͔͠͠ɺiOSΞϓϦͰ΋Ϗϧυπʔϧ͸ෳ਺ଘࡏ͢Δ͠ɺϏϧυͷෳࡶ౓͸΍͹͍ ›

    Xcode͕Θ͔Γ΍͘͢ݟ͍ͤͯΔ͚ͩ › ͦΕͳΒWebͰ΋౰વى͖Δࣄ৅ͳΜͩɻͱཧղ ࣗ෼ͳΓͷཧղͷਐΊํ
  19. › developϏϧυͩͱେৎ෉͚ͩͲreleaseϏϧυͩͱڍಈ͕ҧ͏ › SwiftͰ΋࠷దԽίϯύΠϧͰى͜ΓಘΔ ࣗ෼ͳΓͷཧղͷਐΊํ

  20. › τϨϯυͷҠΓมΘΓ͕ૣ͗͢Δ!? › ·͊ɺୀ۶͠ͳͯ͘ྑ͍͔ʂ › ΑΓྑ͍Ξϓϩʔν͕ϘϯϘϯొ৔͢Δ؀ڥ͸ຊ౰ʹ͍͢͜͝ͱͩͱ ࢥ͏ › ΈΜͳͷΞΠσΞ͕٧Ίࠐ·Εຏ͔Ε͍ͯ͘εϐʔυ͕͍͢͝ɻ ›

    ίϛϡχςΟͷڊେ͞ʹײಈ ࣗ෼ͳΓͷཧղͷਐΊํ
  21. › HTMLͷ૊Έํ΍CSS FlexboxͷϨΠΞ΢τ › iOSΞϓϦ։ൃͰYoga, Textureʹ৮Ε͍ͯͨͷͰɺͦͦ͜͜Πϝʔδ௨ΓʹϨΠ Ξ΢τ͕૊Ίͨɻ › ͔͠͠ɺத਎ͷElement͕͏·͍͜ͱ๲ΒΜͰ͘Εͳ͍ͱ͔ࠔΔ͜ͱ͸࣌ʑ ͋ͬͨɻ

    › Instagram΍Pinterestͷߏ଄ΛಡΉ͜ͱ͕Ͱ͖Δ͔Βࢀߟʹͳͬͨɻ › Webͷͱͯ΋ྑ͍ͱ͜ΖɻωΠςΟϒΞϓϦͰ͸͜Ε͸೉͍͠ ࣗ෼ͳΓͷཧղͷਐΊํ
  22. Vue? React? › ࠷ॳ͸Vue.jsΛ࢖ͬͨ › ͔͠͠ɺࣗ෼ʹ͸ͲͷΑ͏ʹಈ͍͍ͯΔͷ͔Α͘Θ͔Βͳ͔ͬͨ

  23. ͱΓ͋͑ͣReactΛબ୒ › ࠓͳΒVue΋ཧղͰ͖Δ͔΋͠Εͳ͍

  24. ͱΓ͋͑ͣReactΛબ୒ › ίϯϙʔωϯτΫϥεͷఆ͕ٛࣗ෼తʹಡΈ΍͔ͬͨ͢ɻ › ཧղ͕ਐΊ΍͔ͬͨ͢ɻComponentΫϥε͸iOSΞϓϦͷUIViewͩͱࢥ͏ͱָʹͳͬͨ › Component಺ʹશ͕ͯଘࡏ͢Δ › iOSͰ͸ΧελϜϏϡʔ͸UIViewΫϥεͷαϒΫϥεΛ࡞Γɺͦ͜ʹϓϩύςΟ(ঢ়ଶ)ɾϨΠΞ΢τɾελΠϧΛ ఆ͍ٛͯ͘͠

    › React => DOM-tree ͸ iOS => UIView-tree ʹ૬౰͢Δ › iOSͱҟͳΔͷ͕ɺrender › renderͰฦ٫͢ΔJSX͸View࣮ମͰ͸ͳ͘DOM-NodeΛ࡞Γ্͛ΔͨΊͷઃܭॻɻ(͋ͬͯΔʁ ʣ › UIViewͰ͸ৗʹ࣮ମΛѻ͏ɻ ௚઀DOMΛૢ࡞͢Δײ͡ʹ͍ۙͱࢥ͏
  25. JavaScript? TypeScript? Flow? › ʮ੩తܕ෇͚ʯ͸ཉ͔ͬͨ͠ › ੩తܕ෇͚ݴޠͷಛ௃͸ɺʮؒҧͬͨίʔυΛίϯύΠϧ࣌ʹ։ ൃऀ΁ڭ͑Δ͜ͱ͕Ͱ͖Δ࢓૊ΈΛ։ൃऀ͕࡞Δ͜ͱ͕Ͱ͖Δʯ ͜ͱ ›

    ίϯύΠϧΤϥʔʹͰ͖Δ
  26. JavaScript? TypeScript? Flow? › Flow΋࢖ͬͯΈ͚ͨͲɺTypeScriptʹ໭Γ·ͨ͠ɻ › VSCodeͷαϙʔτ͸TypeScriptͷํ͕ڧྗͩͬͨͷ͕େ͖͍ › ·ͨɺαϙʔτ͞Ε͍ͯΔϥΠϒϥϦ΋ଟ͍ ›

    ࠷ॳ͸ؾʹͳΒͳ͔͚ͬͨͲɺ΍ͬͺΓ͋Δͱॿ͔Γ·͢ɻ › υΩϡϝϯτಡ·ͳͯ͘΋ɺఆٛϑΝΠϧΛݟΔ͚ͩͰͳΜͱͳ ͘࢖͍ํ͕෼͔Δ (ϔομϑΝΠϧΛಡΉײ֮)
  27. Scoped CSS (CSS in JS) › ݁࿦ styled-componentsͱReactඪ४ͷinline-styleΛར༻

  28. Scoped CSS (CSS in JS) › ࣗ෼ͷܦݧ্Ͱ͕͢ɺࣗࣾαʔϏε౳ͷϓϩμΫτʹ͓͍ͯStyleΛ ʮ૊Έ੾Δʯ͜ͱ͸ݱ࣮తͰ͸ͳ͍ › ελΠϧͷྫ֎͕͍ͬͺ͍ଘࡏ͢Δ͠ɺͲΜͲΜվળ΋ߦΘΕͯ

    ͍͘ › ͦͷதͰ͏·͘ߏ଄Խ͞ΕͨCSSΛ࡞Γ্͛Δͷ͸೉͍͠
  29. Scoped CSS (CSS in JS) › ී௨ʹCSSΛ૊Ήͱେྔͷid΍class͕ొ৔ › मਖ਼࣌ʹӨڹൣғΛؾʹͯ͠ɺ৽͍͠id,classΛ௥Ճ͢Δѱ॥؀ʹɻ ›

    ͦΕͳΒDRYΛڐ༰͠ScopedͳCSSΛॻ͍ͨํ͕ྑ͍ › ๻ͱͯ͠͸ɺUIͷ࣮૷ʹ͓͍ͯDRY͸ؾʹ͗ͯ͢͠͸ͳΒͳ͍ɻͲ͏ͤॻ ͖׵ΘΔ͔ΒDRYͷͨΊͷઃܭΛߟ͑Δ࣌ؒͷํ͕ແବʹͳΓ͔Ͷͳ͍ɻ › ·ͱΊΔ΂͖ͱ֬৴͕࣋ͯͨ࣌ʹίʔυΛ࠷దԽ͢Δ
  30. σεΫτοϓ & ϞόΠϧରԠ › iOSͰ͍͏ͱ͜ΖͷɺiPhone ͱ iPadͷUniversalͳରԠ › ࣗ෼ʹͱͬͯ͸CSSͰDesktop ->

    Mobile·ͰͷϨΠΞ΢τΛ૊Έ੾Δͷ͸ແཧ ήʔͩͱײͨ͡ › ࠓͷ݁࿦ͱͯ͠͸ɺrenderͷ࣌ʹσΟεϓϨΠαΠζΛݟͯฦ٫͢ΔJSXΛ੍ޚ ͢Δख๏Λͱͬͨ › ଟ෼͜ΕΛΞμϓςΟϒϨΠΞ΢τͱݺͿ…? › contra/react-responsive
  31. import * as React from 'react' const MediaQuery = require('react-responsive').default

    export namespace Lazy { export interface Props { children?: () => JSX.Element | string | number } const Query = (props: any) => { return ( <MediaQuery {...props}> {(isMatching: boolean) => { if (isMatching) { return props.children() } else { return null } }} </MediaQuery> ) } }
  32. export namespace Lazy { export const Desktop = (props: Props)

    => { return <Query {...props} minWidth={769} /> } export const TabletMobile = (props: Props) => { return <Query {...props} maxWidth={769} /> } }
  33. import * as Layout from 'src/layout' export default class Top

    extends React.Component<Props, {}> { render() { return ( <> <Layout.Lazy.Desktop> {() => <……/>} </Layout.Lazy.Desktop> <Layout.Lazy.TabletMobile> {() => <……/>} </Layout.Lazy.TabletMobile> </> ) } } αΠζ͝ͱͷJSXఆٛΛClosureʹแΜͰ͓͖ɺϚο νͨ͠λΠϛϯάͰ࣮ߦͯ͠JSXΛฦ٫ (஗Ԇॲཧ) Desktop࣌ͷJSX Tablet & Mobile࣌ͷJSX
  34. ωΠςΟϒΞϓϦͷ஌ݟ΋׆͔ͤΔ › CSSͷ૊Έํ › ݴ͏͜ͱ͕ޮ͔ͳ͍ϨΠΞ΢τ͸֊૚Λ૿΍͢ͳͲͷ޻෉Ͱ៉ྷ ʹ࣮ݱͰ͖Δ › HTMLͰ͍͏จॻߏ଄͸ཚΕΔ͚Ͳɺ΋͸΍࢓ํͷͳ͍͜ͱͳͷ Ͱ͸ʁͱɺͻͱ·ͣఘΊͨ

  35. ωΠςΟϒΞϓϦͷ஌ݟ΋׆͔ͤΔ › ύϑΥʔϚϯε΁ͷߟྀ › ϦετͰແݶʹεΫϩʔϧ͍ͯ͘͠UIͷ৔߹ɺPinterestͷΑ͏ʹDOMͷNode਺͸૿΍ͣ͞ දࣔΛߦ͏΂͖ › NodeΛ૿΍͞ͳ͍͜ͱͰϝϞϦͷফඅྔ͕཈͑ΒΕΔ › ࣮࣭ɺऔಘͨ͠σʔλྔͷΈ

    › Ϣʔβʔ͸ύϑΥʔϚϯεΛΩʔϓͨ͠··ͣͬͱӾཡͰ͖Δ › ͜ͷΑ͏ͳ࣮૷͸ωΠςΟϒΞϓϦʹ͸ඪ४ίϯϙʔωϯτͱͯ͠ఏڙ͞Ε͍ͯΔ
  36. None
  37. WebΞϓϦ։ൃ໘ന͍ › WebΞϓϦ͔ΒiOSΞϓϦ։ൃʹ׆͔ͤΔ͜ͱ͸ͨ͘͞Μ͋Δͱײͨ͡ɻ › ReactͷStatelessͳComponentͳͲ (HOC) › ͦͯͦ͠ͷٯ΋ͨ͘͞Μ͋Γͦ͏ʂ › ΋ͬͱWebΤϯδχΞͱωΠςΟϒΤϯδχΞͰ৘ใަ׵Λ͍ͯ͘͠

    ͜ͱͰɺࠓ·Ͱʹͳ͍৽͍͠Ξϓϩʔν͕ݟ͚ͭΒΕΔͷͰ͸ʁͱࢥͬ ͨ
  38. Thank you