Upgrade to PRO for Only $50/YearâLimited-Time Offer! ð¥
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Unlocking new capabilities for PWA
Search
Takepepe
February 01, 2020
Technology
2
2.8k
Unlocking new capabilities for PWA
PWA Night CONFERENCE 2020
https://conf2020.pwanight.jp/speaker/takepepe/
Takepepe
February 01, 2020
Tweet
Share
More Decks by Takepepe
See All by Takepepe
ã©ã®æ§ã«AIãšãŒãžã§ã³ããš åæ¥ãã¹ãã ã£ãã®ãïŒ
takefumiyoshii
2
820
ServerAction ã§ Progressive Enhancement ã¯ã©ããŸã§é 匵ãããïŒ / progressive-enhancement-with-server-action
takefumiyoshii
7
1.2k
App Router ãžã®ç§»è¡ã¯ãæ¹åããšãªãåŸãã®ãïŒ/ Can migration to App Router be an improvement
takefumiyoshii
8
3.7k
ããã³ããšã³ããã®æžããžããããã£ããã¹ããæžããªããŠããã£ããã¹ã
takefumiyoshii
40
17k
Webããã³ããšã³ãã®ããã®å®è·µããã¹ããææ³ CodeZine Night #1
takefumiyoshii
24
9.2k
Next.js ã§ãªã¢ãŒããã¯ããã話 / story-of-re-architect-with-nextjs
takefumiyoshii
12
9k
ããéã WEB ãç®æã Next.js / nextjs-make-the-web-faster
takefumiyoshii
54
20k
ããã³ããšã³ããã®è€éãã«èããããå®è·µããããš / readyfor-nextjs-first
takefumiyoshii
25
11k
Redux ã®å©ç¹ãæ¯ãè¿ã
takefumiyoshii
26
8.9k
Other Decks in Technology
See All in Technology
AIã«ãããèªç±ã®è¿œæ±
shujisado
2
440
åœåããå§ããSpec Driven
kuruwic
3
790
Docker, Infraestructuras seguras y Hardening
josejuansanchez
0
140
éœåžã¹ã±ãŒã«ARå¶äœã§æ°ãã€ããããš
segur
0
220
ããªãã®ç¥ããªãDateã®ã²ã¿ã€ / The Secret of "Date" You Haven't known #tqrk16
expajp
0
110
TypeScriptÃCASLã§ã€ããSaaSã®èªå¯ / Authz with CASL
saka2jp
2
180
ECMAScript仿§ã®ææ°åå: ããã»ã¹ã®å€åãšä»æ§ã®ãã¬ã³ã
uhyo
1
310
Bill One éçºãšã³ãžã㢠玹ä»è³æ
sansan33
PRO
4
16k
ã€ã³ãã©å®€äºäŸé
mixi_engineers
PRO
2
180
ãªãããã³ããšã³ãæè¡ã远ãã®ãïŒãªãã«ã³ãã¡ã¬ã³ã¹ã«åå ããã®ãïŒ
sakito
8
1.9k
段éçã«é²ããã æ«æããªãèªå® ãµãŒãå ¥é
yu_kod
5
2.1k
MS Ignite 2025ã§çºè¡šãããFoundry IQãRecap
satodayo
3
220
Featured
See All Featured
Site-Speed That Sticks
csswizardry
13
980
Rails Girls ZÃŒrich Keynote
gr2m
95
14k
How STYLIGHT went responsive
nonsquared
100
5.9k
Connecting the Dots Between Site Speed, User Experience & Your Business [WebExpo 2025]
tammyeverts
10
700
Building Applications with DynamoDB
mza
96
6.8k
jQuery: Nuts, Bolts and Bling
dougneiner
65
8k
Designing Dashboards & Data Visualisations in Web Apps
destraynor
231
54k
Writing Fast Ruby
sferik
630
62k
Thoughts on Productivity
jonyablonski
73
4.9k
å人éçºã®å€±æãé¿ããã€ã±ãŠãèãæ¹ / tips for indie hackers
panda_program
119
20k
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
31
3k
How to Ace a Technical Interview
jacobian
280
24k
Transcript
Unlocking new capabilities for PWA PWA Night CONFERENCE 2020 @Takepepe
About Me ⪠Takefumi Yoshii / @Takepepe ⪠DeNA /
DeSC Healthcare ⪠Frontend Developer ⪠TypeScript Meetup JP member 2
Agenda ⪠1. PWA ã Web App ã§å©çšå¯èœãªãå®éšçæ©èœã«ã€ã㊠⪠2.
ãšããå®éšçæ©èœ ãå©çšããŠã¢ããªãäœã£ã話 ⪠3. ãšããå®éšçæ©èœ ã® API æŠèŠ âª 4. API åãæ±ããã€ã³ãã»React Redux ã«çµ±åãã話 3
1. Web Experimental Features
1-1. Bridging the NativeApp Gap ServiceWorker ã®ãã£ãã·ã¥æŠç¥ã«ããã PWA ã®ã¿ãªãããWebãã©ãŠãžã³ã°ã« å¿«é©ãª
UX ãããããããŠããŸãã 1. Web Experimental Features
1-1. Bridging the NativeApp Gap 1. Web Experimental Features ãã®å¿«é©ãªã¬ã¹ãã³ã¹ããã
Web ã¢ããªã±ãŒã·ã§ã³éçºæè¡ã§ã Native ã¢ããªãšåçæ©èœãæäŸããããšã«ã å€ãã®æåŸ ãå¯ããããŠããŸãã
1-1. Bridging the NativeApp Gap 1. Web Experimental Features ããããWeb
ãã©ãŠã¶ã«èš±å®¹ãããŠãã æ©èœã¯éå®çã§ãã端æ«åºæã®æ©èœã« ã¢ã¯ã»ã¹ãã Low-Level API ã®å€ãã¯ã JavaScript ã«ã¯è§£æŸãããŠããŸããã
1-1. Bridging the NativeApp Gap 1. Web Experimental Features ãã®ç¶æ³ãåé²ããã¹ãã
Google Chrome ã§ã¯ Low-Level API ãžã®æ©æž¡ãã ç©æ¥µçã«è¡ãªã£ãŠããŸãã Experimental FeaturesïŒå®éšçæ©èœïŒ ã«ã¯ããããªæ©èœã倿°æ§ããŠããŸãã
1-2. Origin Trial 1. Web Experimental Features chrome://flags ã§å®éšçæ©èœãæå¹ã«ããã°ã ãã®æ©èœã詊ãããšãã§ããŸãã
ãããŠãå®éšçæ©èœãæéä»ãã»ãã¡ã€ã³å¶éã§ æäŸãããOrigin TrialãããããŸãã https://developers.chrome.com/origintrials
1-2. Origin Trial 1. Web Experimental Features æšå¹Ž 5æã«éå¬ããããGoogle I/Oã
æšå¹Ž 11æã«éå¬ããããChrome Dev Summitãã§ã ãã®ãOrigin Trialãã«ã€ããŠç޹ä»ããããŸããã å¯èœæ§ã®åºããã«ãæåŸ ãé«ãŸããŸããïŒ
1-2. Origin Trial 1. Web Experimental Features 仿¥ã玹ä»ããã®ã¯ã çŸåšã®ç§ãã¡ã®ç掻ã«ã¯æ¬ ããããšã®ã§ããªã ãã®æè¡ã«ã€ããŠã§ãã
æãçŽè¿ã«è§£æŸããã API ã§ããããŸãã
Web NFC
2. Devlop Trial
2-1. Web NFC Media MEMO Web NFC ã®ãã©ã€ã¢ã«ãšããŠã ãã¢ã¢ããªãäœæããŸããã æ¬¡ã®æ€èšŒç°å¢ã§åäœç¢ºèªãããŠããŸãã
⪠Pixel 3aã⪠Android 9 ⪠Google Chrome Canary v81 2. Devlop Trial https://vimeo.com/388157513
2-1. Web NFC Media MEMO ãã¢ã¢ããªã¯é ä¿¡ãããŠããŸãã®ã§ã NFC æ©èœä»ã Android ããæã¡ã®æ¹ã¯
詊ããŠããã ãããšå¬ããã§ãã github ã«ã³ãŒããå ¬éããŠããŸãã https://webnfc-media-memo.netlify.com/ https://github.com/takefumi-yoshii/webnfc-media-memo 2. Devlop Trial
2-1. Web NFC Media MEMO ãã®ã¢ããªãèµ·åããŠããæã 端æ«ã§æ€åºããã NFC Tag ã®åŠçã¯
ãã©ã¢ã°ã©ãŠã³ãã®ãã©ãŠã¶ã«å§ããããŸãã 2. Devlop Trial
2-1. Web NFC Media MEMO 2. Devlop Trial ããã¹ãã¡ã¢æ©èœãå©çšã㊠NFC
Tag ã«æžã蟌ãã ããã¹ãã¯ã NFC Tag ã«æ°žç¶åãããŸãã
2-1. Web NFC Media MEMO 2. Devlop Trial ããã¹ããªãŒããŒç»é¢ã§ã¿ãããããšã æžã蟌ãã æååã衚瀺ãããŸãã
2byte æåãå¯èœã§ãã
2-1. Web NFC Media MEMO 2. Devlop Trial é³å£°ã¡ã¢æ©èœã¯ã é²é³ããåŸã«
NFC Tag ã«ã¿ãããããšã ä¿åããããšãã§ããŸãã
2-1. Web NFC Media MEMO ãããŠãä¿åæžã¿ã® NFC Tag ã«ã¿ãããããšã ã¢ããªäžã§é³å£°ã¡ã¢ãèªååçããŸãã
2. Devlop Trial
2-1. Web NFC Media MEMO åç»ããŒã¿ãé²ç»ã»åçãå¯èœã§ãã ä»ã®ãšãããé²ç»ã®å°ºã¯èšããŠããŸããã 2. Devlop Trial
2-1. Web NFC Media MEMO NFC Tag ã«ã¯ãã®ä»ã«ãã æ§ã ãªããŒã¿ã®ä¿åãå¯èœã§ãã ïŒãŠãœã§ãïŒçš®æããã¯æåŸã«ïŒ
2. Devlop Trial
2-2. Prepare
2-2. Prepare 2. Devlop Trial äžçªæ©ã API ã詊ãããšãåºæ¥ãæ¹æ³ã玹ä»ããŸãã NFC æ©èœãæèŒããã
Android端æ«ã«ã Google Chrome Canary ãã€ã³ã¹ããŒã«ã chrome://flags ã URL ããŒã«å ¥åãã Web-NFC ãæå¹ã«ããŸãã ïŒç«¯æ«ã® NFCæ©èœãæå¹ã«ããããšãå¿ããã«ïŒ
2-2. Prepare 2. Devlop Trial localhost ã§æåã確èªããããã ãã® Android 端æ«ã
PC ã«æ¥ç¶ããŸãã PC ã® Google Chrome ãèµ·åãã More tools > Remote devices ããã æ¥ç¶ããŠãã該åœç«¯æ«ãéžæã
2-2. Prepare 2. Devlop Trial Port forwarding ã«ãéçºãµãŒããŒã® localhost ãæå®ã
ã¢ãã€ã«ç«¯æ«ã® Developer Console ã«ã¢ã¯ã»ã¹ããŸãã
2-2. Prepare Developer Console ãããWeb NFC ãå©çšå¯èœãã確èªããŸãã å®çŸ©ãååšããã°ãWeb NFC ã詊ãç°å¢ãæŽããŸããã
2. Devlop Trial if ('NDEFReader' in window) { /* ... Scan NDEF Tags */ } if ('NDEFWriter' in window) { /* ... Write NDEF Tags */ }
3. API Overview
3-1. About NFC Tag
3-1. About NFC Tag API 詳现ã®è©±ã®åã«ã NFC Tag ã«ã€ããŠå°ã玹ä»ããŸãã NFC
Tag ã«ã¯æ§ã ãªçš®é¡ããããŸãã 3. API Overview
3-1. About NFC Tag Suica / Edy ãªã©ã«å°é ããé»åãããŒã¯ã NFC-FïŒType-FïŒã«ããããŸãã ããŒã¿ç®¡çãã»ãã¥ãªãã£æ©èœã
匷åãããŠãããã®ã§ãã 3. API Overview
3-1. About NFC Tag NFC-F ã«ã€ããŠã¯ãä»å調ã¹ããªãã§ã¯ã Web NFC ã§èªã¿æžãã¯ã§ããŸããã§ããã ïŒãã ã
æ€åºã¯å¯èœïŒ 3. API Overview
3-1. About NFC Tag Origin Trials ã® description ãåŒçšããŸãã Low-level
I/O operation ãªã©ã¯ãå¯Ÿå¿æªå®ãšã®ããšã 3. API Overview Low-level I/O operations (e.g. ISO-DEP, NFC-A/B, NFC-F) and Host-based Card Emulation (HCE) are not supported within the current scope.
3-1. About NFC Tag çŸç¶è©Šãããšãã§ãã API ã¯éå®çã§ããã NFC Tag ãéžã¹ã°ããã¢ã¢ããªã®æ§ãªããšãå¯èœã§ãã
3. API Overview Low-level I/O operations (e.g. ISO-DEP, NFC-A/B, NFC-F) and Host-based Card Emulation (HCE) are not supported within the current scope.
3-1. About NFC Tag ãã¢ã¢ããªã§å©çšæ³å®ããŠããã®ã¯ã NFC-AïŒType-AïŒã®ãã®ã§ãã ããã§ããã°ãWeb NFCãã§ã èªã¿æžããããããšãå¯èœã§ãã ã«ãŒãã¿ã€ãã»ã·ãŒã«ã¿ã€ããªã©ããããŸãã
3. API Overview äŸïŒã«ãŒãã¿ã€ã / Â¥600 / 12æãã·ãŒã«ã¿ã€ã / Â¥790 / 11æïŒ
3-1. About NFC Tag NPX 瀟ã®ãNTAG 215 ãããïŒNFC-A ïŒã ãæ¡çšããã
NFC Tag ã¯å€ãæµéããŠããã å®äŸ¡ã«å ¥æããããšãã§ããŸãã 3. API Overview äŸïŒã«ãŒãã¿ã€ã / Â¥600 / 12æãã·ãŒã«ã¿ã€ã / Â¥790 / 11æïŒ
3-1. About NFC Tag 圢ã ãã§ãªãã容éãæ§ã ãªãã®ããããŸãã ãããªã«å€§å®¹éã§ã¯ãããŸããã NTAG 213: 144Byte NTAG
215: 504Byte NTAG 216: 888Byte 3. API Overview äŸïŒã«ãŒãã¿ã€ã / Â¥600 / 12æãã·ãŒã«ã¿ã€ã / Â¥790 / 11æïŒ
3-1. About NFC Tag èªã¿èŸŒã¿å¯èœãª NFC Tag ã®ä»æ§ã«ã€ããŠã ããè©³çŽ°ãªæ å ±ã¯ä»¥äžãåç §ããŸãããã https://w3c.github.io/web-nfc/#x4-1-ndef-compatible-tag-types
3. API Overview
3-2. NDEFReader
3-2. NDEFReader ç°¡åãªèªã¿èŸŒã¿äŸã確èªããŠãããŸãããã 3. API Overview const reader = new
NDEFReader() reader.scan().then(() => { console.log("Scan started successfully.") reader.onreading = event => { console.log(`NDEF message read.${event.serialNumber}`) } }).catch(error => { console.log(`Error! Scan failed to start: ${error}.`) })
NDEFReader ã NFC èªã¿èŸŒã¿ã«å¿ èŠãªã€ã³ã¹ã¿ã³ã¹ã§ãã scan 颿°ã¯ Promise ãè¿ããŸãã 3-2. NDEFReader
3. API Overview const reader = new NDEFReader() reader.scan().then(() => { console.log("Scan started successfully.") reader.onreading = event => { console.log(`NDEF message read.${event.serialNumber}`) } }).catch(error => { console.log(`Error! Scan failed to start: ${error}.`) })
3-2. NDEFReader onreading ãã³ãã©ã® callback 㯠NDEFReadingEvent ãåãåããŸãã 3. API
Overview const reader = new NDEFReader() reader.scan().then(() => { console.log("Scan started successfully.") reader.onreading = event => { console.log(`NDEF message read.${event.serialNumber}`) } }).catch(error => { console.log(`Error! Scan failed to start: ${error}.`) })
3-2. NDEFReader serialNumber ã¯ãç©çã¿ã°åºè·æã« ä»äžãããŠããäžæã® ID ã§ãã 3. API Overview
const reader = new NDEFReader() reader.scan().then(() => { console.log("Scan started successfully.") reader.onreading = event => { console.log(`NDEF message read.${event.serialNumber}`) } }).catch(error => { console.log(`Error! Scan failed to start: ${error}.`) })
3-2. NDEFReader serialNumber ãå€å¥ããããšã§ ãäžæã® NFC Tag ãèªã¿èŸŒãã ãããšãå€å¥ããããšãã§ããŸãã 3. API
Overview const reader = new NDEFReader() reader.scan().then(() => { console.log("Scan started successfully.") reader.onreading = event => { console.log(`NDEF message read.${event.serialNumber}`) } }).catch(error => { console.log(`Error! Scan failed to start: ${error}.`) })
3-3. NDEFWriter
3-3. NDEFWriter æžã蟌ã¿ãããã£ãŠç°¡åã§ãã æååã NFC Tag ã«æžã蟌ãã§ã¿ãŸãã 3. API Overview
const writer = new NDEFWriter() writer.write("Hello World").then(() => { console.log("Message written.") }).catch(error => { console.log(`Write failed :-( try again: ${error}.`) })
3-3. NDEFWriter æžã蟌ã¿ã«ã¯ã æååãæž¡ãã ãã®æ¹æ³ããããŸãã 3. API Overview const writer =
new NDEFWriter() writer.write("Hello World").then(() => { console.log("Message written.") }).catch(error => { console.log(`Write failed :-( try again: ${error}.`) })
3-3. NDEFWriter ãã¡ãã®æ»ãå€ã Promise ã§ãã NFC Tag ãæ€åºãããã¿ã€ãã³ã°ã§ãæžã蟌ã¿ã詊ã¿ãŸãã 3. API
Overview const writer = new NDEFWriter() writer.write("Hello World").then(() => { console.log("Message written.") }).catch(error => { console.log(`Write failed :-( try again: ${error}.`) })
3-3. NDEFWriter æžã蟌ãã®ã¯æååã®ä»ã«ã NDEFMessage ãªããžã§ã¯ããæå®ããæ¹æ³ããããŸãã 3. API Overview const message:
NDEFMessage = { records: [{ recordType: "url", data: "https://w3c.github.io/web-nfc/" }] } const writer = new NDEFWriter() writer.write(message).then(() => { console.log("Message written.") }).catch(_ => { console.log("Write failed :-( try again.") })
3-3. NDEFWriter æžã蟌ãã®ã¯æååã®ä»ã«ã NDEFMessage ãªããžã§ã¯ããæå®ããæ¹æ³ããããŸãã 3. API Overview const message:
NDEFMessage = { records: [{ recordType: "url", data: "https://w3c.github.io/web-nfc/" }] } const writer = new NDEFWriter() writer.write(message).then(() => { console.log("Message written.") }).catch(_ => { console.log("Write failed :-( try again.") })
3-4. NDEFMessage
3-4. NDEFMessage NFC Tag ã®èªã¿èŸŒã¿æã«ããNDEFMessage ãåãåããŸãã ãã®å 容ãèªã¿åã£ãŠã¿ãŸãã 3. API Overview
function consoleNDEFRecords(message: NDEFMEssage) { if (message.records.length === 0) return message.records.map(record => { const decoder = new TextDecoder() console.log(`Text: ${decoder.decode(record.data)}`) }) }
3-4. NDEFMessage NFC Tag ã«æžã蟌ãŸããæååã¯ãçŽæ¥èªã¿åãããšãã§ããŸããã TextDecoder ã€ã³ã¹ã¿ã³ã¹ãå©çšãããã³ãŒããããå¿ èŠããããŸãã 3. API Overview
function consoleNDEFRecords(message: NDEFMEssage) { if (message.records.length === 0) return message.records.map(record => { const decoder = new TextDecoder() console.log(`Text: ${decoder.decode(record.data)}`) }) }
3-4. NDEFMessage 1byteæååã§ããã°ããã®ãŸãŸã§ãåé¡ãããŸãããã 2byteæåãå«ãæååã®å Žåãencoding ã®æå®ãå¿ èŠã§ãã 3. API Overview function consoleNDEFRecords(message:
NDEFMEssage) { if (message.records.length === 0) return message.records.map(record => { const decoder = new TextDecoder(record.encoding) console.log(`Text: ${decoder.decode(record.data)}`) }) }
3-4. NDEFMessage ãã®æ§ã«ãNFC-A ã® NFC Tag ã§ããã°ã ç°¡åã«èªã¿æžãå¯èœã§ããããšãããããŸãã 3. API
Overview function consoleNDEFRecords(message: NDEFMEssage) { if (message.records.length === 0) return message.records.map(record => { const decoder = new TextDecoder(record.encoding) console.log(`Text: ${decoder.decode(record.data)}`) }) }
3-5. NDEFRecord
3-5. NDEFRecord NDEFRecord ã«ã€ããŠãããå°ã詳ããã¿ãŠãããŸãããã Web IDL interface ã¯ã€ãã®æ§ã«å®çŸ©ãããŠããŸãã 3. API
Overview interface NDEFRecord { constructor(NDEFRecordInit recordInit) readonly attribute USVString recordType readonly attribute USVString? mediaType readonly attribute USVString? id readonly attribute DataView? data readonly attribute USVString? encoding readonly attribute USVString? lang sequence<NDEFRecord>? toRecords() }
3-5. NDEFRecord NDEFRecord ã®ãªãã§å¿ é ããããã£ã§ããã®ã¯ãrecordType ã§ãã NDEFRecord ã®è§£æã¯ããã確èªãããšããããå§ãŸããŸãã 3. API Overview
interface NDEFRecord { constructor(NDEFRecordInit recordInit) readonly attribute USVString recordType readonly attribute USVString? mediaType readonly attribute USVString? id readonly attribute DataView? data readonly attribute USVString? encoding readonly attribute USVString? lang sequence<NDEFRecord>? toRecords() }
3-5. NDEFRecord recordType ã¯ä»»æã®æååãš ããããšãã§ããŸããã Well-known type records ãšããŠåãæ±ºããããŠãã ã®ã¯æ¬¡ã®3çš®é¡ã§ãã
⪠text ⪠url ⪠smart-poster 3. API Overview
3-5. NDEFRecord recordType: "url" ã® record ã ä¿æãã NFC Tag
ãæ€åºãã 端æ«ã¯ãäœãã¢ããªã±ãŒã·ã§ã³ ãèµ·åããŠããªãå Žåã ãã©ãŠã¶ã®èµ·åãä¿ããŸãã 3. API Overview
3-5. NDEFRecord ãã®ãããWeb NFC ãå©çšã recordType: "url" ãæå®ãã NDEFRecord ãæžã蟌ãã°ã
ä»»æã® NFC Tag ã ãã©ãŠã¶ã©ã³ãã£ãŒãš ããããšãã§ããŸãã 3. API Overview
3-5. NDEFRecord recordType ã« ã¢ããªã±ãŒã·ã§ã³ç¹æã® æ¥é èŸãä»äžããæ€åºãã ã¿ã°ã®åŠçãçµã蟌ãäŸã 玹ä»ãããŠããŸãã ⪠https://w3c.github.io/web-nfc/
3. API Overview
4. Handling APIs in App
4-1. Permission Request
4-1. Permission Request Web NFC ã䜿ãã¢ããªã¯ã äœãããã¯ããã«ããŒããã·ã§ã³ã åŸãå¿ èŠããããŸãã 4. Handling
APIs in App const reader = new NDEFReader() await reader.scan()
4-1. Permission Request 泚æããªããã°ãããªãã®ã¯ã ããŒãžããŒããšåæã« API ãã³ãŒã«ããªãããšã§ãã 4. Handling APIs
in App const reader = new NDEFReader() await reader.scan()
4-1. Permission Request ãã®ã¿ã€ãã³ã°ã§ã³ãŒã«ãããšã ããŒããã·ã§ã³ã»ããã³ããã 衚瀺ãããŸããã 4. Handling APIs in
App const reader = new NDEFReader() await reader.scan()
4-1. Permission Request ããŒããã·ã§ã³ã»ããã³ããã 衚瀺ããããããæŒäžã³ãŒã«ããã¯ã§ API ãã³ãŒã«ããèšèšã«ããŸãããã 4. Handling APIs
in App const reader = new NDEFReader() await reader.scan()
4-1. Permission Request ãããŠãNDEFReader ã€ã³ã¹ã¿ã³ã¹ã è§£æŸããªãçæãå¿ èŠã§ããscan ãå®è¡ ãããŠããªããšãå¥ã¢ããªãæ€åºã«åå¿ãã ãã©ã¢ã°ã©ãŠã³ãã奪ãããŠããŸããŸãã 4.
Handling APIs in App const reader = new NDEFReader() await reader.scan()
4-1. Permission Request ãããã端æ«èšå®ã§ãNFC æ©èœãžã® ã¢ã¯ã»ã¹ãæåŠããŠããå ŽåããããŸãã ãããã®èæ ®ãšäœµããå©çšã§ããªãã±ãŒã¹ã ãŠãŒã¶ãŒã«æç€ºããŸãããã 4. Handling
APIs in App const reader = new NDEFReader() await reader.scan()
4-2. Permission Handling
4-2. Permission Handling ãµã³ãã«ã¢ããªã§ã¯ ã«ã¡ã©ã»ãã€ã¯ãå©çšããŠããã ãã¡ããããŒããã·ã§ã³ãå¿ èŠã«ãªããŸãã äžèšé¢æ°ãå©çšããããšã§ MediaStream ãç«ã¡äžãããŸããã ãã«ã¡ã©ã»ãã€ã¯ãã®ããŒããã·ã§ã³ããã³ãããåæã«è¡šç€ºãããŸãã
4. Handling APIs in App function getUserMedia(constraints: MediaStreamConstraints) { return navigator.mediaDevices.getUserMedia(constraints) }
4-2. Permission Handling 4. Handling APIs in App ã¢ã¯ã»ã¹æš©éç¶æ ã®èå¥ã¯éèŠã§ãã äžåºŠã§ãæ©èœãžã®ã¢ã¯ã»ã¹ããããã¯ãããšã
ãã以éããã®æ©èœã«ã¢ã¯ã»ã¹ããããšãã§ããŸããã ïŒèšå®è§£é€ãžã®èªå°ãå¿ èŠïŒ function getUserMedia(constraints: MediaStreamConstraints) { return navigator.mediaDevices.getUserMedia(constraints) }
4-2. Permission Handling ãµã³ãã«ã¢ããªã§ã¯ãPermission API ãå©çšãã Origin ã®æš©éç¶æ ãååŸããŠããŸãã ãããã¯ãããŠããç¶æ³ãªã©ãææ¡ããããã«ã Permission
API ã¯æå¹ã§ãã 4. Handling APIs in App const status = await navigator.permissions.query({ name: 'nfc' }) console.log(status.state) // "granted" | "denied" | "prompt" status.onchange = () => { // dosomething ex:) re render view }
4-2. Permission Handling ãµã³ãã«ã¢ããªã§ã¯ãPermission API ãå©çšãã Origin ã®æš©éç¶æ ãååŸããŠããŸãã ãããã¯ãããŠããç¶æ³ãªã©ãææ¡ããããã«ã Permission
API ã¯æå¹ã§ãã 4. Handling APIs in App const status = await navigator.permissions.query({ name: 'nfc' }) console.log(status.state) // "granted" | "denied" | "prompt" status.onchange = () => { // dosomething ex:) re render view }
4-2. Permission Handling query 颿°ã§ç¶æ ãç¥ãæ¹æ³ãšåãæ§ã«ã request 颿°ã§ããŒããã·ã§ã³ã»ããã³ããã衚瀺ããããšãã§ããŸãã ããããããã©ãŠã¶ã«ãã£ãŠãµããŒãç¶æ³ããŸã¡ãŸã¡ãªã®ã§ å©çšããåã«ç¢ºèªããŸãããã 4.
Handling APIs in App const status = await navigator.permissions.query({ name: 'nfc' }) console.log(status.state) // "granted" | "denied" | "prompt" status.onchange = () => { // dosomething ex:) re render view }
4-2. Permission Handling æš©éç¶æ³ããŠãŒã¶ãŒã«ç¥ããã View ããããšèŠªåã§ãã æš©é倿Žãããæã«çºç«ããããã³ãã©ãæå®ã§ããŸãã Native API ã®å€ãã¯ãPermission
ãæ±ãããã®ãå€ãã§ãã å©çšããã¢ããªã±ãŒã·ã§ã³ã§ã¯ãæåããµããŒãããŠãããŸãããã 4. Handling APIs in App const status = await navigator.permissions.query({ name: 'nfc' }) console.log(status.state) // "granted" | "denied" | "prompt" status.onchange = () => { // dosomething ex:) re render view }
4-3. Media Recorder
4-3. Media Recorder 4. Handling APIs in App ã¡ãã£ã¢ã®èšé²ã¯ãMediaRecorder ãå©çšããŠããŸãã
é²é³ã»é²ç»ããšãŠãç°¡åã«å®çŸã§ããŸãã const mediaRecorder = new MediaRecorder(stream, options) mediaRecorder.onstart = () => { console.log('start rec') } mediaRecorder.onstop = () => { console.log('stop rec') } mediaRecorder.ondataavailable = event => { console.log('data available') }
4-3. Media Recorder ã¡ãã£ã¢ã®èšé²ã«å¿ èŠãª MediaStream ãç«ã¡äžããåŸã«ã MediaRecorder ã€ã³ã¹ã¿ã³ã¹ãçæããŸãã 4. Handling
APIs in App const mediaRecorder = new MediaRecorder(stream, options) mediaRecorder.onstart = () => { console.log('start rec') } mediaRecorder.onstop = () => { console.log('stop rec') } mediaRecorder.ondataavailable = event => { console.log('data available') }
4-3. Media Recorder ãondataavailableããã³ãã©ã§ã¯ãé²ç»ããŒã¿ãåãåãããšãã§ããŸãã ãã®é²ç»ããŒã¿ããä»»æã®æ¹æ³ã§ä¿åããŸãã 4. Handling APIs in App
const mediaRecorder = new MediaRecorder(stream, options) mediaRecorder.onstart = () => { console.log('start rec') } mediaRecorder.onstop = () => { console.log('stop rec') } mediaRecorder.ondataavailable = event => { console.log('data available') }
4-4. SerialNumber & IndexedDB
4-4. SerialNumber & IndexedDB ãã¢ã¢ããªã§ã¯ãNFC Tag ã«ã¡ãã£ã¢ã®èšé²ãããŠãããã®æ§ã«ã æŒåºãæœããŠããŸããã ããã¯çš®æããããããšãNFC Tag
ã®ãserialNumberãã«çŽä»ãã ããŒã¿ãæ°žç¶åããŠããã ãã§ãã 4. Handling APIs in App localforageStore.getItem(id) localforageStore.setItem(id, blob)
4-4. SerialNumber & IndexedDB 4. Handling APIs in App ãã®äžæã®
ID ã key ã«ãIndexedDB ã« ã¡ãã£ã¢ SRC ã§ãã Blob ãæžã蟌ãã§ããŸãã ãã¢ã¢ããªã§ã¯ãlocalforage ãå©çšããŠããŸãã IndexedDB ã®ã©ãããŒã©ã€ãã©ãªã§ãã localforageStore.getItem(id) localforageStore.setItem(id, blob)
4-4. SerialNumber & IndexedDB IndexedDB ã®åãæ±ãã¯ããç ©éã§ãã localStorage ãšåãæèŠã§äœ¿ãããã¡ãã®ã©ã€ãã©ãªã Promise ãè¿ããŠããããããèšèšã«çã蟌ã¿ãããã§ãã
ïŒä»åã¯ã¹ããŒãéèŠã§éžå®ããŸããïŒ 4. Handling APIs in App localforageStore.getItem(id).then(...) localforageStore.setItem(id, blob).then(...)
4-5. Side Eï¬ect Handling
4-5. Side Eï¬ect Handling ããŠããããŸã§ã§ç޹ä»ããè€æ°ã® APIã ã³ãŒã«ããã¯ãã³ãã©ã Promise ãã»ãšãã©ã§ã éåæåŠçã®ãµã©ãããŠã«ã§ããã
ã²ãšã€ã²ãšã€ã®äœ¿ãæ¹ãåçŽã§ããé åºãå¶åŸ¡ãªã©ã ã¢ããªã±ãŒã·ã§ã³ãžã®çµ±åã«äžå·¥å€«ãå¿ èŠã«ãªããŸãã 4. Handling APIs in App
4-5. Side Eï¬ect Handling 4. Handling APIs in App å¯äœçšãæ··åšãã
Application ã¯ã å¯äœçšã«ç¹åããã©ã€ãã©ãªã䟿å©ã§ãã ç§ãæã«éŠŽæãã§ãã React ã§ã¯ã ä»åã®æ§ãª ã¢ããªè²ãæ¿ããã®ã®å Žåã Redux ãš redux-saga ã䜿ã£ãŠããŸãã
4-5. Side Eï¬ect Handling 4. Handling APIs in App Store
æ§æã¯ãå ±ææ©èœãã¡ã€ã³ããšãåããŒãžãã¡ã€ã³ã ã«åããŠãReducer ã Action ãããããèšããŠããŸãã ãããã®ãã¡ã€ã³ãããéããã²ãšã€ã® Store ãšããŸãã åããŒãžãã¡ã€ã³ã¯ãå ±ææ©èœãã¡ã€ã³ã®å©çšè ããšããäœçœ®ä»ãã§ãã ãã®æ§æã«ãããåã ã®å®è£ ãåçŽã«ãªã£ãŠããŸãã
4-5. Side Eï¬ect Handling MediaRecorder ãäŸã«èŠãŠã¿ãŸãããã é²ç»ã»é²é³ã®è²¬åã¯ãæ©èœãã¡ã€ã³ã§äžé管çããŸãã 4. Handling APIs
in App mediaRecorder.onstart = () => { store.dispatch(creators.onStartRecording()) } mediaRecorder.onstop = () => { store.dispatch(creators.onStopRecord()) } mediaRecorder.ondataavailable = event => { const blob = new Blob([event.data], { type: 'video/webm' }) store.dispatch(creators.onDataAvailable(blob)) }
4-5. Side Eï¬ect Handling 4. Handling APIs in App JavaScript
Native API ã³ãŒã«ããã¯ãã³ãã©ã®äžã§ã Redux Store ã® dispatch ãå®è¡ããŠããŸãã mediaRecorder.onstart = () => { store.dispatch(creators.onStartRecord()) } mediaRecorder.onstop = () => { store.dispatch(creators.onStopRecord()) } mediaRecorder.ondataavailable = event => { const blob = new Blob([event.data], { type: 'video/webm' }) store.dispatch(creators.onDataAvailable(blob)) }
4-5. Side Eï¬ect Handling åããŒãžã¯ãå ±ææ©èœãã¡ã€ã³ã® Action ã賌èªãããã å ±ææ©èœãã¡ã€ã³ ã« Action
ãçºè¡ããŸãã 4. Handling APIs in App switch (action.type) { case PermanentStorageTypes.ON_SUCCESS_PUT: return handleStateByMode(state, 'ready') case MediaRecorderTypes.ON_START_RECORDING: return handleStateByMode(state, 'recording') case MediaRecorderTypes.ON_DATA_AVAILABLE: return { ...state, blob: action.payload.blob } default: return state } Page Reducer Subscribe Actions
4-5. Side Eï¬ect Handling åããŒãžã¯ãå ±ææ©èœãã¡ã€ã³ã® Action ã賌èªãããã å ±ææ©èœãã¡ã€ã³ ã« Action
ãçºè¡ããŸãã 4. Handling APIs in App const handleClickIcon = React.useCallback(() => { switch (mode) { case 'ready': dispatch(startRecording({ audio: true, video: true })) break case 'recording': dispatch(stopRecording()) } }, [mode]) Page Component Dispatch Actions
4-5. Side Eï¬ect Handling ä»åã®ãã¢ã¢ããªã§ redux-saga ãæã圹ã«ãã£ãã·ãŒã³ã¯ã ã¡ãã£ã¢ã®é²ç»éå§æã«è¡šç€ºãããã«ãŠã³ãããŠã³æ©èœã§ãã ããã¯æŒåºä»¥å€ã«ããéèŠãªåœ¹å²ãæ ã£ãŠããŸãã ã«ã¡ã©ã®èµ·åçŽåŸïŒMediaStream
éå§çŽåŸïŒæãå Žæãªã©ã§ã¯ é²åºè£æ£ã®ããæ°ç§éæããªã£ãŠããŸãç¬éããããŸãã ãã®ã¿ã€ãã³ã°ã§é²ç»ãå§ããŠããŸããšãè¯ãç»ãæ®ããŸããã 4. Handling APIs in App
4-5. Side Eï¬ect Handling ã«ãŠã³ãããŠã³ãäžçš®ã®å¯äœçšã§ãããéåæåŠçãšãããŸãã ã«ãŠã³ãããŠã³äžã«çããå¥ã®å¯äœçšïŒç»é¢é·ç§»ãªã©ïŒãåé¡ã«ãªãåŸãŸãã 4. Handling APIs in
App let count = 4 while (count) { const [normal, abnormal] = yield race([ call(countDownStep), call(countDownCancel) ]) if (abnormal !== undefined) break count -= normal yield put(creators.onCountDown(count)) }
4-5. Side Eï¬ect Handling ãã®æ§ãªåé¡ã saga-effect ã®çµã¿åããã§å æããããšãã§ããŸãã ã€ã¬ã®ã¥ã©ãŒãªã±ãŒã¹ãã«ããŒããŠããããå¿åŒ·ã峿¹ã§ãã 4. Handling
APIs in App let count = 4 while (count) { const [normal, abnormal] = yield race([ call(countDownStep), call(countDownCancel) ]) if (abnormal !== undefined) break count -= normal yield put(creators.onCountDown(count)) }
ãŸãšã
æ©èœãè€éã»è€åçã«ãªããšã éåæåŠçãå ¥ãä¹±ããããšãåãããŸããã Reduxã»redux-saga ã®äŸã玹ä»ããŸãããã éåæåŠçã«åŒ·ãã©ã€ãã©ãªã¯æ§ã ãªãã®ããããŸãã®ã§ã æã«éŠŽæããã®ãèŠã€ããŠã¿ãŠãã ããã ãŸãšã
ãŸãšã Google Chrome ã® Experimental Features ã¯ã é¢çœããã®ãçãã ãããã§ãã Native API
ã«ã©ãã©ããªãŒãã§ããæ§ã«ãªã£ãŠããŸãã ã¢ã€ãã£ã¢æ¬¡ç¬¬ã§ã䟿å©ã»ãããããã ã¢ãŠãããããã§ãããã§ãã
ãŸãšã Experimental Features ã®ãã©ã€ã¢ã«ãã æ°ãããµãŒãã¹ã®çš®ã«ãªããããããŸããã ãã²ãææŠããŠã¿ãŠãã ããã
ãéèŽããããšãããããŸãã