Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
iOS エンジニアが考える Webアプリ開発
Search
Muukii
April 25, 2018
Programming
540
3
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
iOS エンジニアが考える Webアプリ開発
Muukii
April 25, 2018
More Decks by Muukii
See All by Muukii
Problem Solving from the Abstraction Layer
muukii0803
1
75
Pairs iOSとトレンドの技術
muukii0803
0
1k
Thoughts about build flow
muukii0803
2
360
スマホアプリ開発で大切なこと
muukii0803
3
190
エンジニアとして働くために
muukii0803
0
220
Q. Textureは部分的に導入できますか?
muukii0803
3
2.6k
安定したチャットを実現するための アプリとAPI設計
muukii0803
17
8.6k
快適なUIを持つアプリを作るために できること
muukii0803
12
2.8k
AutoLayout以外の選択肢
muukii0803
13
5.5k
Other Decks in Programming
See All in Programming
Seeing Through Serverless: Observability for AWS Lambda with ADOT and CloudWatch Application Signals
seike460
PRO
1
120
【DroidKaigi 2026】「アクセシビリティを利用するとき、 アクセシビリティもまたこちらを利用している」 〜マルウェアによる攻撃と防衛について〜
halunoyo
0
410
30年振りにコンパイラの定数整数除算を改善した
herumi
9
4.4k
Claude Codeを組織的に動かして月400PRを実現した話
happy_ryo
0
260
Laravelのアプリケーションをどこにデプロイするか #ツナギメオフライン.9
akase244
0
120
業務時間外もAIに働いてもらう話
colorful12
3
10k
AWS Step Functions 大規模並列の壁を越える / jaws-sonic-2026-niigata-step-functions
kasacchiful
PRO
0
380
Snowflakeで業務アプリを作ろう。 Snowflakeのアプリ機能解説&実践ガイド
ayumu_yamaguchi
1
130
一参加者から『中の人』へ 〜全通PHPerがブースに立って学んだ、カンファレンスを100倍楽しむコツ〜
wp_daisuke
0
120
書籍「プロフェッショナルAI駆動開発」紹介スライド
juntaromatsumoto
0
990
kubernetes コンポーネント開発入門 / 新卒N年目の勉強会&交流会!〜〇〇への誘い〜 #n_study
mazrean
0
170
異なる設計思想のフレームワークを経験して得た学び
amekuhideki
2
1.5k
Featured
See All Featured
A better future with KSS
kneath
240
18k
How to Ace a Technical Interview
jacobian
281
24k
Build your cross-platform service in a week with App Engine
jlugia
234
19k
The Organizational Zoo: Understanding Human Behavior Agility Through Metaphoric Constructive Conversations (based on the works of Arthur Shelley, Ph.D)
kimpetersen
PRO
0
440
The B2B funnel & how to create a winning content strategy
katarinadahlin
PRO
1
510
Reflections from 52 weeks, 52 projects
jeffersonlam
356
21k
Building the Perfect Custom Keyboard
takai
2
860
Everyday Curiosity
cassininazir
0
310
Technical Leadership for Architectural Decision Making
baasie
3
560
Practical Orchestrator
shlominoach
191
12k
Max Prin - Stacking Signals: How International SEO Comes Together (And Falls Apart)
techseoconnect
PRO
0
450
The State of eCommerce SEO: How to Win in Today's Products SERPs - #SEOweek
aleyda
2
11k
Transcript
iOS ΤϯδχΞ͕ߟ͑Δ WebΞϓϦ։ൃ muukii
About Me ‣ muukii <Hiroshi Kimura> ‣ iOS Engineer at
eureka, Inc. ‣ Pairs Global Team ‣ GitHub : @muukii ‣ https://muukii.me ☕ ⌚
None
1BJSTʹ͍ͭͯ !4
4PVUI,PSFB Japan Taiwan No.1 2017 release No.1 !5 1BJSTʹ͍ͭͯ ల։ࠃ
̐ͭͷϓϥοτϑΥʔϜ CONFIDENTIAL INFORMATION: Not for Public Distribution - Do Not Copy
None
Agenda › ࠷ۙͪΐͬͱͨ͠WebΞϓϦΛ࡞ΔҊ͕͖݅ͬͯ·ͨ͠ › ͔ͤͬ͘ͳͷͰେنͳΞϓϦΛ࡞ΔέʔεΛఆͯͬͯ͠Έ͍ͨ › ΄ͱΜͲ͕ࣝͳ͍ঢ়ଶͳͷͰɺ৭ʑௐͨ͜ͱ › iOSΞϓϦͷUIΛ࡞Γଓ͚͖ͯͨܦݧΛݩʹɺ࠷ۙΠϯϓοτͯ͠ ͍ΔWebΞϓϦ։ൃͷࣝͰɺେنͳΞϓϦΛ࡞ΔͳΒʮ͜Μͳ
ײ͡ʹ࡞͍͖͍ͬͯͨͳʔʯͱࢥ͏·ͱΊɻ
ݱঢ়ͷ › Gatsby + Netlify Ͱ੩తαΠτΛ࡞͍ͬͯΔ › React › styled-components
ͳͲ › TypeScript › VSCode
WebΞϓϦ։ൃΛ࢝ΊΔલͷঢ়ଶ › ࠓ·ͰͣͬͱSwiftΛॻ͍͖ͯͨ › Webͷۀܦݧͳ͠
WebΞϓϦ։ൃΛ࢝ΊΔલͷঢ়ଶ › ࣝͱͯͦ͠ΕͳΓʹΩϟονΞοϓ͍ͯͨ͠ › Ϗϧυπʔϧͷಈͱ͔ › ΞʔΩςΫνϟͱ͔ › ωΠςΟϒΞϓϦ։ൃWebΞϓϦͷςΫϊϩδʔʹΠϯεύ ΠΞ͞ΕΔ͜ͱ͕ଟ͍ͨΊ
WebΞϓϦ։ൃΛ࢝ΊΔલͷঢ়ଶ › JS͋·Γৄ͘͠ͳ͍ › SwiftͰfunctional-programmingͷงғؾʹ৮Ε͍ͯͨ͜ͱͰॿ ͔Δ෦ଟ͔ͬͨ
WebΞϓϦ։ൃΛ࢝ΊΔલͷঢ়ଶ › CSSཧղ͍ͯ͠ΔͭΓʹͳ͍ͬͯΔ › ʮiOSΞϓϦ։ൃͰFlexboxϨΠΞτ৮͍ͬͯΔ͠େৎͰ͠ΐ ͏ʯ
࠷ॳʹ໎ͬͨ͜ͱ › ViewϨΠϠʔͷϑϨʔϜϫʔΫͲ͏͢Δ? › Vue? React? › AngularҰ୴͓͍͓ͯ͘ɻ
࠷ॳʹ໎ͬͨ͜ͱ › ViewपลͷΞʔΩςΫνϟ? › PairsͷGlobal൛iOSΞϓϦͰFluxʹ͍ۙ͜ͱ͍ͬͯΔ › ʮ։ൃ͍ͯ͠Δ͏ͪʹFlux, Reduxͱ͔Λߟ͑࢝ΊΔͩΖ͏ ͳʔʯͱߟ͑Δͷޙճ͠ʹ
࠷ॳʹ໎ͬͨ͜ͱ › Ͱ͖ΕJSͰʮ੩తܕ͚ʯཉ͍͚͠Ͳ › TypeScript? › Flow?
ࣗͳΓͷཧղͷਐΊํ › iOSΞϓϦ։ൃͷࣝʹͯΊͯࣗͳΓʹೲಘ͍ͯ͘͠ελΠϧ
› JSͷڍಈͷཧղ › runkit.com͕Α͔ͬͨ › ૉΒ͍͠Playground ✨ › JSͷΦϒδΣΫτͷಈ͖Λ࣮ࡍʹίʔυΛಈ͔࣮ͯ͠ݧ͍ͯ͘͠ ›
ʮObjective-CSwiftͰ͍͏ɺ͜͏͍͏ಈ͖ํʯΈ͍ͨͳΠϯϓοτ ࣗͳΓͷཧղͷਐΊํ
› Ϗϧυπʔϧͷ͍ͬͯΔ͜ͱ͕ຐ๏ʹݟ͑Δ › ͍ΖΜͳϏϧυπʔϧ͋Δ͠ɺ͍ΖΜͳ͜ͱ͕࣮ߦ͞Ε͗ͯ͢ཧղͰ͖Δؾ͕͠ͳ͍... › ͦͦ͜Μͳෳࡶͳ͜ͱ͠ͳ͍ͱWebΞϓϦͬͯ࡞Εͳ͍ͷʁͭΒ͍ͳɻͱࢥͬͨ ͜ͱɻ › ͔͠͠ɺiOSΞϓϦͰϏϧυπʔϧෳଘࡏ͢Δ͠ɺϏϧυͷෳࡶ͍ ›
Xcode͕Θ͔Γ͘͢ݟ͍ͤͯΔ͚ͩ › ͦΕͳΒWebͰવى͖ΔࣄͳΜͩɻͱཧղ ࣗͳΓͷཧղͷਐΊํ
› developϏϧυͩͱେৎ͚ͩͲreleaseϏϧυͩͱڍಈ͕ҧ͏ › SwiftͰ࠷దԽίϯύΠϧͰى͜ΓಘΔ ࣗͳΓͷཧղͷਐΊํ
› τϨϯυͷҠΓมΘΓ͕ૣ͗͢Δ!? › ·͊ɺୀ۶͠ͳͯ͘ྑ͍͔ʂ › ΑΓྑ͍Ξϓϩʔν͕ϘϯϘϯొ͢Δڥຊʹ͍͢͜͝ͱͩͱ ࢥ͏ › ΈΜͳͷΞΠσΞ͕٧Ίࠐ·Εຏ͔Ε͍ͯ͘εϐʔυ͕͍͢͝ɻ ›
ίϛϡχςΟͷڊେ͞ʹײಈ ࣗͳΓͷཧղͷਐΊํ
› HTMLͷΈํCSS FlexboxͷϨΠΞτ › iOSΞϓϦ։ൃͰYoga, Textureʹ৮Ε͍ͯͨͷͰɺͦͦ͜͜Πϝʔδ௨ΓʹϨΠ Ξτ͕Ίͨɻ › ͔͠͠ɺதͷElement͕͏·͍͜ͱΒΜͰ͘Εͳ͍ͱ͔ࠔΔ͜ͱ࣌ʑ ͋ͬͨɻ
› InstagramPinterestͷߏΛಡΉ͜ͱ͕Ͱ͖Δ͔Βࢀߟʹͳͬͨɻ › Webͷͱͯྑ͍ͱ͜ΖɻωΠςΟϒΞϓϦͰ͜Ε͍͠ ࣗͳΓͷཧղͷਐΊํ
Vue? React? › ࠷ॳVue.jsΛͬͨ › ͔͠͠ɺࣗʹͲͷΑ͏ʹಈ͍͍ͯΔͷ͔Α͘Θ͔Βͳ͔ͬͨ
ͱΓ͋͑ͣReactΛબ › ࠓͳΒVueཧղͰ͖Δ͔͠Εͳ͍
ͱΓ͋͑ͣReactΛબ › ίϯϙʔωϯτΫϥεͷఆ͕ٛࣗతʹಡΈ͔ͬͨ͢ɻ › ཧղ͕ਐΊ͔ͬͨ͢ɻComponentΫϥεiOSΞϓϦͷUIViewͩͱࢥ͏ͱָʹͳͬͨ › Componentʹશ͕ͯଘࡏ͢Δ › iOSͰΧελϜϏϡʔUIViewΫϥεͷαϒΫϥεΛ࡞Γɺͦ͜ʹϓϩύςΟ(ঢ়ଶ)ɾϨΠΞτɾελΠϧΛ ఆ͍ٛͯ͘͠
› React => DOM-tree iOS => UIView-tree ʹ૬͢Δ › iOSͱҟͳΔͷ͕ɺrender › renderͰฦ٫͢ΔJSXView࣮ମͰͳ͘DOM-NodeΛ࡞Γ্͛ΔͨΊͷઃܭॻɻ(͋ͬͯΔʁ ʣ › UIViewͰৗʹ࣮ମΛѻ͏ɻ DOMΛૢ࡞͢Δײ͡ʹ͍ۙͱࢥ͏
JavaScript? TypeScript? Flow? › ʮ੩తܕ͚ʯཉ͔ͬͨ͠ › ੩తܕ͚ݴޠͷಛɺʮؒҧͬͨίʔυΛίϯύΠϧ࣌ʹ։ ൃऀڭ͑Δ͜ͱ͕Ͱ͖ΔΈΛ։ൃऀ͕࡞Δ͜ͱ͕Ͱ͖Δʯ ͜ͱ ›
ίϯύΠϧΤϥʔʹͰ͖Δ
JavaScript? TypeScript? Flow? › FlowͬͯΈ͚ͨͲɺTypeScriptʹΓ·ͨ͠ɻ › VSCodeͷαϙʔτTypeScriptͷํ͕ڧྗͩͬͨͷ͕େ͖͍ › ·ͨɺαϙʔτ͞Ε͍ͯΔϥΠϒϥϦଟ͍ ›
࠷ॳؾʹͳΒͳ͔͚ͬͨͲɺͬͺΓ͋Δͱॿ͔Γ·͢ɻ › υΩϡϝϯτಡ·ͳͯ͘ɺఆٛϑΝΠϧΛݟΔ͚ͩͰͳΜͱͳ ͍͘ํ͕͔Δ (ϔομϑΝΠϧΛಡΉײ֮)
Scoped CSS (CSS in JS) › ݁ styled-componentsͱReactඪ४ͷinline-styleΛར༻
Scoped CSS (CSS in JS) › ࣗͷܦݧ্Ͱ͕͢ɺࣗࣾαʔϏεͷϓϩμΫτʹ͓͍ͯStyleΛ ʮΈΔʯ͜ͱݱ࣮తͰͳ͍ › ελΠϧͷྫ֎͕͍ͬͺ͍ଘࡏ͢Δ͠ɺͲΜͲΜվળߦΘΕͯ
͍͘ › ͦͷதͰ͏·͘ߏԽ͞ΕͨCSSΛ࡞Γ্͛Δͷ͍͠
Scoped CSS (CSS in JS) › ී௨ʹCSSΛΉͱେྔͷidclass͕ొ › मਖ਼࣌ʹӨڹൣғΛؾʹͯ͠ɺ৽͍͠id,classΛՃ͢Δѱ॥ʹɻ ›
ͦΕͳΒDRYΛڐ༰͠ScopedͳCSSΛॻ͍ͨํ͕ྑ͍ › ͱͯ͠ɺUIͷ࣮ʹ͓͍ͯDRYؾʹ͗ͯ͢͠ͳΒͳ͍ɻͲ͏ͤॻ ͖ΘΔ͔ΒDRYͷͨΊͷઃܭΛߟ͑Δ࣌ؒͷํ͕ແବʹͳΓ͔Ͷͳ͍ɻ › ·ͱΊΔ͖ͱ֬৴͕࣋ͯͨ࣌ʹίʔυΛ࠷దԽ͢Δ
σεΫτοϓ & ϞόΠϧରԠ › iOSͰ͍͏ͱ͜ΖͷɺiPhone ͱ iPadͷUniversalͳରԠ › ࣗʹͱͬͯCSSͰDesktop ->
Mobile·ͰͷϨΠΞτΛΈΔͷແཧ ήʔͩͱײͨ͡ › ࠓͷ݁ͱͯ͠ɺrenderͷ࣌ʹσΟεϓϨΠαΠζΛݟͯฦ٫͢ΔJSXΛ੍ޚ ͢Δख๏Λͱͬͨ › ଟ͜ΕΛΞμϓςΟϒϨΠΞτͱݺͿ…? › contra/react-responsive
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> ) } }
export namespace Lazy { export const Desktop = (props: Props)
=> { return <Query {...props} minWidth={769} /> } export const TabletMobile = (props: Props) => { return <Query {...props} maxWidth={769} /> } }
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
ωΠςΟϒΞϓϦͷݟ׆͔ͤΔ › CSSͷΈํ › ݴ͏͜ͱ͕ޮ͔ͳ͍ϨΠΞτ֊Λ૿͢ͳͲͷͰ៉ྷ ʹ࣮ݱͰ͖Δ › HTMLͰ͍͏จॻߏཚΕΔ͚Ͳɺํͷͳ͍͜ͱͳͷ Ͱʁͱɺͻͱ·ͣఘΊͨ
ωΠςΟϒΞϓϦͷݟ׆͔ͤΔ › ύϑΥʔϚϯεͷߟྀ › ϦετͰແݶʹεΫϩʔϧ͍ͯ͘͠UIͷ߹ɺPinterestͷΑ͏ʹDOMͷNode૿ͣ͞ දࣔΛߦ͏͖ › NodeΛ૿͞ͳ͍͜ͱͰϝϞϦͷফඅྔ͕͑ΒΕΔ › ࣮࣭ɺऔಘͨ͠σʔλྔͷΈ
› ϢʔβʔύϑΥʔϚϯεΛΩʔϓͨ͠··ͣͬͱӾཡͰ͖Δ › ͜ͷΑ͏ͳ࣮ωΠςΟϒΞϓϦʹඪ४ίϯϙʔωϯτͱͯ͠ఏڙ͞Ε͍ͯΔ
None
WebΞϓϦ։ൃ໘ന͍ › WebΞϓϦ͔ΒiOSΞϓϦ։ൃʹ׆͔ͤΔ͜ͱͨ͘͞Μ͋Δͱײͨ͡ɻ › ReactͷStatelessͳComponentͳͲ (HOC) › ͦͯͦ͠ͷٯͨ͘͞Μ͋Γͦ͏ʂ › ͬͱWebΤϯδχΞͱωΠςΟϒΤϯδχΞͰใަΛ͍ͯ͘͠
͜ͱͰɺࠓ·Ͱʹͳ͍৽͍͠Ξϓϩʔν͕ݟ͚ͭΒΕΔͷͰʁͱࢥͬ ͨ
Thank you