ã¯ããã« ããã«ã¡ã¯ãæè¡åºå ±ã»ãšã³ãžãã¢ã®å¹³æšã§ããæè¿äœ¿ã£ãŠãã Emacs ã Spacemacs ãã Doom Emacs ã«å€æŽãããšããæ°åãæ°ãã«ããã¹ã掻åãæãããã«ãªããŸããã ããŠã2022/05/11 ã«è¡ãªããã ã QA Night ãçµç¹å
ã§ QA ãšã³ãžãã¢ãããªã¥ãŒãçºæ®ãããã£ãªã¢ã¢ããããã«ã¯ã ã ãšãã QA ãšã³ãžãã¢åãã€ãã³ãã§åŒç€Ÿ QA ãšã³ãžãã¢ç±³å±±ããããªã¹ããšããŠç»å£ããŸããã®ã§ããã®æ§åãã€ãã³ãã¬ããŒããšããŠãå±ãããããšæããŸãã QA Night ãšã¯ ãã¡ãã®ã€ãã³ã㯠Showcase Gig ãããäž»å¬ããŠããã€ãã³ãã§ãã Geek Gig ãšãããšã³ãžãã¢ãªã³ã°ã«ã€ããŠã®å®æã€ãã³ãããããŸããŠããã®ã·ãªãŒãºã® 1 ã€ãšããŠéå¶ããããã®ã§ãã ä»å㯠Showcase Gig ãããåŒç€Ÿããã¹ãèªååããŒã«ã® MagicPod ã䜿ã£ãŠãããšãããçžããã声ããããã ãã€ãã³ãéå¬ã®éã³ãšãªããŸããã ã€ãã³ãã«ã€ã㊠ä»åã®ã€ãã³ãã¯ãããã«ãã£ã¹ã«ãã·ã§ã³ãšã㊠2 瀟㮠QA ã«ã€ããŠããããèªã圢åŒã«ãªããŸããã ã¢ãã¬ãŒã¿ãŒã Showcase Gig ãœãããŠã§ã¢ãšã³ãžãã¢ã§ VP of Technology ã§ãã èæ± ãã ãè¡ãªãããããªã¹ããšã㊠Showcase Gig QA ãšã³ãžã㢠暪ç°ãã ãšãåŒç€Ÿ QA ãšã³ãžãã¢ç±³å±±ãšã§ãã£ãã°ããã«ã€ãã³ããé²è¡ããŠãããŸããã QA ãšã³ãžãã¢ã®æ¹ã ãã§ã¯ãªããã¢ãã¬ãŒã¿ãŒã«ãšã³ãžãã¢ã®æ¹ãå
¥ã£ãããšã«ãããã©ã³ã¹ãè¯ãããã«ãã£ã¹ã«ãã·ã§ã³ã«ãªã£ãŠãããšããææ³ã§ããã ãã¡ãã®ã€ãã³ã㯠connpass ã§å
¬éåŸããããããããš 140 人ãŸã§ç³ã蟌ã¿ããããæ³šç®åºŠã®é«ãã䌺ããŸããã åœæ¥ã®ã€ãã³ãã®æ§åã¯äžèšããã芧ããã ããŸãã®ã§ããèå³ã®ããæ¹ã¯ãã²ã ããã«ãã£ã¹ã«ãã·ã§ã³ ããã«ãã£ã¹ã«ãã·ã§ã³ã¯å€§ãŸãã«ä»¥äžã®ãããªã»ã¯ã·ã§ã³ã«åãããŠå®æœãããŸããã ãããªã¹ãã»ã¢ãã¬ãŒã¿ãŒèªå·±çŽ¹ä» å瀟ã®éçº/QA ããã»ã¹ã®çæ³ãšçŸå® QA ãšã³ãžãã¢ãããªãã£ããã©ããªã? QA ãšã³ãžãã¢ã®ãã£ãªã¢ ãããã®ã»ã¯ã·ã§ã³ã«åãããŠããããªã¹ãããããã®ç«å Žã§åçãããŠãããŸããããéäžã§èŠèŽãããŠããæ¹ã®è³ªåãªã©ã¯ãã¢ãã¬ãŒã¿ãŒã®èæ± ãããã»ãŒãªã¢ã«ã¿ã€ã ã§æŸã£ãŠãããªããã®é²è¡ã ã£ãã®ã§ãã€ãã³ãã®äžäœæãéåžžã«æããããŠé¢çœãã£ãã§ãã èªå·±çŽ¹ä» æšªç°ããã米山ãçŸè·ã«è³ããŸã§ã®çµæŽãããªã䌌ãŠããŸããã第äžè
æ€èšŒäŒç€Ÿã§æ§ã
ãªæ¥æ
ã®äŒç€Ÿã顧客ãšããŠãæ§ã
ãªçµéšãç©ã¿éããŠãããäºæ¥äŒç€Ÿã§ã® QA ãšã³ãžãã¢ãšããŠç¹å®ã®ãããã¯ãã®å質ãé«ããä»äºãããŠããã£ããããšããç¹ã§ãã 第äžè
æ€èšŒäŒç€Ÿã§æ§ã
ãªããŒãºã«å¯Ÿå¿ããããšãããããã¯ããžã®è²¢ç®ã«æŽ»ããŠãããã ãšæããŸããã å瀟ã®éçº/QA ããã»ã¹ã®çæ³ãšçŸå® QA ãå«ããéçºäœå¶ã«ã€ããŠã¯ã䞡瀟ã§éãããã¡ãããããŸãã倧ããéãã§ãããšãçŸåšã®ã¡ãã¬ãŒã§ã¯ãããã¯ãéçºããŒã ã®äžå¡ãšã㊠QA ãšã³ãžãã¢ãæå±ããŠããŸãã仿¹ãShowcase Gig ããã§ã¯è€æ°ã®éçºããŒã ãæšªæã㊠QA ããŒã ãååšããŠãããšããéšåã§ããããã ã¡ãã¬ãŒã®çŸåšã®éçºäœå¶ã§ã¯ãããŒã å
ã§éçºã¡ã³ããŒãšå¯æ¥ã«ããåããããªããå質ãé«ããŠãããšããããã»ã¹ãåãããŠãããå¥ã®éçºããŒã ã®ãã«ããªã©ãããã¡ãããããŸããã¢ããã€ã¶ãŒçãªæãã§ãå®éã«ã¯ãã®ããŒã å
ã§å質ãé«ããããã«åããŠããŸãã äžæ¹ã§ Showcase Gig ããã§ã¯æšªæããŒã ãšããŠåãããã¯ãã俯ç°ããŠèŠãããããªäœå¶ã«ããŠããå°è±¡ã§ãããããããã®éçºããŒã ãšã¯èŠæã§ã·ã³ã¯ã¢ããããããšã«ããäŒç€Ÿå
šäœã§ã® QA ããã»ã¹ãçµ±äžããªããåããŒã ã«å±éã§ããã®ãè¯ãããã ãªãšæããŸããã çæ³ãšçŸå®ã«ã€ã㊠ãããªäž¡ç€Ÿã§ãããå
±éããéšåãšããŠäºæ¥é åã®é£ããããããŸããã ã¡ãã¬ãŒã¯å»çé åãšããé£ãããShowcase Gig ããã§ã¯ãªã³ã©ã€ã³ãšãªãã©ã€ã³ã®äž¡ç«ãããªããã°ãªããªãéšåãç¹ã«é£ãããšã®ããšã ãããã話㯠QA ã®çæ³ãšçŸå®ã«ç§»ã£ãŠãããŸããã¡ãã¬ãŒã§ã¯ãããã¯ãã®ããäžæµéšåã§ãã仿§çå®éšåãããã°ã朰ããããã«ããŠããã®ãç®æãã€ã€ããã¬ãã¬ããªæ¹æ³ãäœå¶ã«ãªããªãããã«æ¥ã
QA ãè¡ãªã£ãŠããŸãããŸã E2E ãã¹ãã®å€±æãéåžžäºæ
ã ãšã¡ã³ããŒãçŠããããã«æåçãé«ããŠãããããšããçæ³ããããŸãããã©ãããŠãããã¥ã¢ã«ã§ã®ãã¹ããå¿
èŠã«ãªã£ãŠãããããã¯ããªã®ã§ãE2E ãã¹ãã ãã«é Œããªãããã«è©Šè¡é¯èª€ããŠããŸãã Showcase Gig ããã§ã¯åè³ªã¯æ
ä¿ãã€ã€ãä»ä»¥äžã«ãªãªãŒã¹é »åºŠãäžããããã«ã©ããããè¯ãããšããç¹ãéçºããŒã ãšåæ¥ã§æ¹åããããšãããŠããããã§ããMagicPod ã䜿ã£ã E2E ãã¹ãã ãã§ãªãªãŒã¹ãŸã§ã§ããããã«ããã®ãçæ³ã§ã¯ãããŸããããã®åã«ããã»ã¹ã®å¶å®ãªã©å段éã®æºåãçã
ãšããŠããããã§ãã QA ãšã³ãžãã¢ãããªãã£ããã©ããªã? QA ãšã³ãžãã¢ã®ã€ãã³ãã§äžã
åºãŠããªããããªèšåããã倧å€é¢çœãã£ãã®ã§ãããããããã®ãQA ãšã³ãžãã¢ãããªãã£ããã©ããªã?ããšããèšåã§ããã è峿·±ãã£ãã®ã¯ãäºäººãšãåããããªè¿çã ã£ãããšã§ãã䞡瀟ãšãããªãªãŒã¹ã¯éåžžéãè¡ãªãããã ãããããªãªãŒã¹åŸã®äžå
·å察å¿ãªã©ãå¢ãããããããªãããšããããšã§ããããŸããããå
±éããŠãQA ãšã³ãžãã¢ãããªããŠãå質ä¿èšŒããããããšãçæ³ããšããã話ã§ããã å®éã« QA ãšã³ãžãã¢ã¯ããªããŠããã¡ããšé«ãå質ã®ãããã¯ããäžã«åºããŠãããä»çµã¿ãäœå¶ãçæ³ãšããã®ã¯ãé¢ä¿è
ã«å質ã«ã€ããŠã®æèãæ ¹å·®ããŠãããããã«ãããšããææ°èŸŒã¿ã®ããã«èããæéãåããŸããã QA ãšã³ãžãã¢ã®ãã£ãªã¢ ãŸãæ®æ®µãäºäººã¯ã©ã®ãããªæèé
åã§æ¥ã
ã®ä»äºããããŠããããšããã®ãåã°ã©ãã§è¡šãã詊ã¿ãè¯ãã£ãã§ãã æ®æ®µã©ã®ãããªäºã«æéãæèãå²ããŠããããšããã®ãåãããšèªåã®ä»äºã®æ¯çãšæ¯ã¹ãŠã¿ã¡ãããŸããã ãããããçãããæ°ã«ãªã QA ãšã³ãžãã¢ã®ãã£ãªã¢ã«ã€ããŠãäºäººã話ããããŸããã 米山㯠15 幎㮠QA çµéšãæã£ãŠããŸããããã®äžã§ã¢ãžã£ã€ã«ããã¹ãèªååãªã©ã®ãã¬ã³ãã«ã¯ãèªåã§ãã§ããããªããšæããªããå°å
¥ãããŠãã£ããšã®ããšã§ãããããããªãããèªåã®äžã®ãã©ã€ãªãªãã£ã¯ãããŸã§ãäºæ¥ã»ãããã¯ããšããéšåã ã£ãã®ã§ãããã«ã³ããããã§ããç«ã¡äœçœ®ã§ã®ä»äºããã£ãšç¶ããŠãããšèšããŸãã å
ã®ãã£ãªã¢ãšããŠã¯ãããžã·ã§ã³ã«æãããäºæ¥äŸ¡å€ãé«ããããã«åããŠãããã©ã®ãããªç¶æ³ã®ããŒã ã§ãå質ãé«ããããã®æšé²ãã§ããããã«ããŠãããããšããããšã§ããã äžæ¹ã®æšªç°ãããä»ãŸã§ã®çµéšãèžãŸã QA ã®ããžã·ã§ã³ãé«ããŠããããããªåããããŠãããããšããããšã§ããããã¹ããªã©ã«èå³ãæã€äººã®è£ŸéãåºããŠãããããšããææ¬²ãæããŸãããå人ãšããŠã¯ UI/UX ãªã©ãå«ããŠå質ãé«ãããšããããšãã§ããã°ãšã®ããšã§ããã ãäºäººãšãããèªåã®ãã£ãªã¢ãã«çãŸããåšå²ã®äººéã«ããè¯ã圱é¿ãäžããŠãããããšããããšããã£ããã£ãŠããã®ãéåžžã«å°è±¡çã§ããã æåŸã« 玹ä»ãã以å€ã«ãçŸå Žã«å³ãã QA ã«ã€ããŠããå質ã«ã€ããŠã®èãæ¹ã®äžç«¯ãåãããããªã€ãã³ãã§ãããèªåã¯ãšã³ãžãã¢ãšããç«å Žã§èŠèŽããŠããŸãããããããã人éã«ã倧å€ã«ç€ºåã«å¯ãã話ãå€ãããã£ãšããéã« 1 æéãçµéããŸãããQA ãšã³ãžãã¢ã®æ¹ã¯ãã¡ããããã®ä»ãããã¯ããäœããšããããšã«é¢ããæ¹ã¯ãã²ãã¢ãŒã«ã€ããèŠèŽããŠã¿ãŠãã ãã!
ã¯ããã« ããã«ã¡ã¯ãæè¡åºå ±ã»ãšã³ãžãã¢ã®å¹³æšã§ããæè¿äœ¿ã£ãŠãã Emacs ã Spacemacs ãã Doom Emacs ã«å€æŽãããšããæ°åãæ°ãã«ããã¹ã掻åãæãããã«ãªããŸããã ããŠã2022/05/11 ã«è¡ãªããã ã QA Night ãçµç¹å
ã§ QA ãšã³ãžãã¢ãããªã¥ãŒãçºæ®ãããã£ãªã¢ã¢ããããã«ã¯ã ã ãšãã QA ãšã³ãžãã¢åãã€ãã³ãã§åŒç€Ÿ QA ãšã³ãžãã¢ç±³å±±ããããªã¹ããšããŠç»å£ããŸããã®ã§ããã®æ§åãã€ãã³ãã¬ããŒããšããŠãå±ãããããšæããŸãã QA Night ãšã¯ ãã¡ãã®ã€ãã³ã㯠Showcase Gig ãããäž»å¬ããŠããã€ãã³ãã§ãã Geek Gig ãšãããšã³ãžãã¢ãªã³ã°ã«ã€ããŠã®å®æã€ãã³ãããããŸããŠããã®ã·ãªãŒãºã® 1 ã€ãšããŠéå¶ããããã®ã§ãã ä»å㯠Showcase Gig ãããåŒç€Ÿããã¹ãèªååããŒã«ã® MagicPod ã䜿ã£ãŠãããšãããçžããã声ããããã ãã€ãã³ãéå¬ã®éã³ãšãªããŸããã ã€ãã³ãã«ã€ã㊠ä»åã®ã€ãã³ãã¯ãããã«ãã£ã¹ã«ãã·ã§ã³ãšã㊠2 瀟㮠QA ã«ã€ããŠããããèªã圢åŒã«ãªããŸããã ã¢ãã¬ãŒã¿ãŒã Showcase Gig ãœãããŠã§ã¢ãšã³ãžãã¢ã§ VP of Technology ã§ãã èæ± ãã ãè¡ãªãããããªã¹ããšã㊠Showcase Gig QA ãšã³ãžã㢠暪ç°ãã ãšãåŒç€Ÿ QA ãšã³ãžãã¢ç±³å±±ãšã§ãã£ãã°ããã«ã€ãã³ããé²è¡ããŠãããŸããã QA ãšã³ãžãã¢ã®æ¹ã ãã§ã¯ãªããã¢ãã¬ãŒã¿ãŒã«ãšã³ãžãã¢ã®æ¹ãå
¥ã£ãããšã«ãããã©ã³ã¹ãè¯ãããã«ãã£ã¹ã«ãã·ã§ã³ã«ãªã£ãŠãããšããææ³ã§ããã ãã¡ãã®ã€ãã³ã㯠connpass ã§å
¬éåŸããããããããš 140 人ãŸã§ç³ã蟌ã¿ããããæ³šç®åºŠã®é«ãã䌺ããŸããã åœæ¥ã®ã€ãã³ãã®æ§åã¯äžèšããã芧ããã ããŸãã®ã§ããèå³ã®ããæ¹ã¯ãã²ã ããã«ãã£ã¹ã«ãã·ã§ã³ ããã«ãã£ã¹ã«ãã·ã§ã³ã¯å€§ãŸãã«ä»¥äžã®ãããªã»ã¯ã·ã§ã³ã«åãããŠå®æœãããŸããã ãããªã¹ãã»ã¢ãã¬ãŒã¿ãŒèªå·±çŽ¹ä» å瀟ã®éçº/QA ããã»ã¹ã®çæ³ãšçŸå® QA ãšã³ãžãã¢ãããªãã£ããã©ããªã? QA ãšã³ãžãã¢ã®ãã£ãªã¢ ãããã®ã»ã¯ã·ã§ã³ã«åãããŠããããªã¹ãããããã®ç«å Žã§åçãããŠãããŸããããéäžã§èŠèŽãããŠããæ¹ã®è³ªåãªã©ã¯ãã¢ãã¬ãŒã¿ãŒã®èæ± ãããã»ãŒãªã¢ã«ã¿ã€ã ã§æŸã£ãŠãããªããã®é²è¡ã ã£ãã®ã§ãã€ãã³ãã®äžäœæãéåžžã«æããããŠé¢çœãã£ãã§ãã èªå·±çŽ¹ä» æšªç°ããã米山ãçŸè·ã«è³ããŸã§ã®çµæŽãããªã䌌ãŠããŸããã第äžè
æ€èšŒäŒç€Ÿã§æ§ã
ãªæ¥æ
ã®äŒç€Ÿã顧客ãšããŠãæ§ã
ãªçµéšãç©ã¿éããŠãããäºæ¥äŒç€Ÿã§ã® QA ãšã³ãžãã¢ãšããŠç¹å®ã®ãããã¯ãã®å質ãé«ããä»äºãããŠããã£ããããšããç¹ã§ãã 第äžè
æ€èšŒäŒç€Ÿã§æ§ã
ãªããŒãºã«å¯Ÿå¿ããããšãããããã¯ããžã®è²¢ç®ã«æŽ»ããŠãããã ãšæããŸããã å瀟ã®éçº/QA ããã»ã¹ã®çæ³ãšçŸå® QA ãå«ããéçºäœå¶ã«ã€ããŠã¯ã䞡瀟ã§éãããã¡ãããããŸãã倧ããéãã§ãããšãçŸåšã®ã¡ãã¬ãŒã§ã¯ãããã¯ãéçºããŒã ã®äžå¡ãšã㊠QA ãšã³ãžãã¢ãæå±ããŠããŸãã仿¹ãShowcase Gig ããã§ã¯è€æ°ã®éçºããŒã ãæšªæã㊠QA ããŒã ãååšããŠãããšããéšåã§ããããã ã¡ãã¬ãŒã®çŸåšã®éçºäœå¶ã§ã¯ãããŒã å
ã§éçºã¡ã³ããŒãšå¯æ¥ã«ããåããããªããå質ãé«ããŠãããšããããã»ã¹ãåãããŠãããå¥ã®éçºããŒã ã®ãã«ããªã©ãããã¡ãããããŸããã¢ããã€ã¶ãŒçãªæãã§ãå®éã«ã¯ãã®ããŒã å
ã§å質ãé«ããããã«åããŠããŸãã äžæ¹ã§ Showcase Gig ããã§ã¯æšªæããŒã ãšããŠåãããã¯ãã俯ç°ããŠèŠãããããªäœå¶ã«ããŠããå°è±¡ã§ãããããããã®éçºããŒã ãšã¯èŠæã§ã·ã³ã¯ã¢ããããããšã«ããäŒç€Ÿå
šäœã§ã® QA ããã»ã¹ãçµ±äžããªããåããŒã ã«å±éã§ããã®ãè¯ãããã ãªãšæããŸããã çæ³ãšçŸå®ã«ã€ã㊠ãããªäž¡ç€Ÿã§ãããå
±éããéšåãšããŠäºæ¥é åã®é£ããããããŸããã ã¡ãã¬ãŒã¯å»çé åãšããé£ãããShowcase Gig ããã§ã¯ãªã³ã©ã€ã³ãšãªãã©ã€ã³ã®äž¡ç«ãããªããã°ãªããªãéšåãç¹ã«é£ãããšã®ããšã ãããã話㯠QA ã®çæ³ãšçŸå®ã«ç§»ã£ãŠãããŸããã¡ãã¬ãŒã§ã¯ãããã¯ãã®ããäžæµéšåã§ãã仿§çå®éšåãããã°ã朰ããããã«ããŠããã®ãç®æãã€ã€ããã¬ãã¬ããªæ¹æ³ãäœå¶ã«ãªããªãããã«æ¥ã
QA ãè¡ãªã£ãŠããŸãããŸã E2E ãã¹ãã®å€±æãéåžžäºæ
ã ãšã¡ã³ããŒãçŠããããã«æåçãé«ããŠãããããšããçæ³ããããŸãããã©ãããŠãããã¥ã¢ã«ã§ã®ãã¹ããå¿
èŠã«ãªã£ãŠãããããã¯ããªã®ã§ãE2E ãã¹ãã ãã«é Œããªãããã«è©Šè¡é¯èª€ããŠããŸãã Showcase Gig ããã§ã¯åè³ªã¯æ
ä¿ãã€ã€ãä»ä»¥äžã«ãªãªãŒã¹é »åºŠãäžããããã«ã©ããããè¯ãããšããç¹ãéçºããŒã ãšåæ¥ã§æ¹åããããšãããŠããããã§ããMagicPod ã䜿ã£ã E2E ãã¹ãã ãã§ãªãªãŒã¹ãŸã§ã§ããããã«ããã®ãçæ³ã§ã¯ãããŸããããã®åã«ããã»ã¹ã®å¶å®ãªã©å段éã®æºåãçã
ãšããŠããããã§ãã QA ãšã³ãžãã¢ãããªãã£ããã©ããªã? QA ãšã³ãžãã¢ã®ã€ãã³ãã§äžã
åºãŠããªããããªèšåããã倧å€é¢çœãã£ãã®ã§ãããããããã®ãQA ãšã³ãžãã¢ãããªãã£ããã©ããªã?ããšããèšåã§ããã è峿·±ãã£ãã®ã¯ãäºäººãšãåããããªè¿çã ã£ãããšã§ãã䞡瀟ãšãããªãªãŒã¹ã¯éåžžéãè¡ãªãããã ãããããªãªãŒã¹åŸã®äžå
·å察å¿ãªã©ãå¢ãããããããªãããšããããšã§ããããŸããããå
±éããŠãQA ãšã³ãžãã¢ãããªããŠãå質ä¿èšŒããããããšãçæ³ããšããã話ã§ããã å®éã« QA ãšã³ãžãã¢ã¯ããªããŠããã¡ããšé«ãå質ã®ãããã¯ããäžã«åºããŠãããä»çµã¿ãäœå¶ãçæ³ãšããã®ã¯ãé¢ä¿è
ã«å質ã«ã€ããŠã®æèãæ ¹å·®ããŠãããããã«ãããšããææ°èŸŒã¿ã®ããã«èããæéãåããŸããã QA ãšã³ãžãã¢ã®ãã£ãªã¢ ãŸãæ®æ®µãäºäººã¯ã©ã®ãããªæèé
åã§æ¥ã
ã®ä»äºããããŠããããšããã®ãåã°ã©ãã§è¡šãã詊ã¿ãè¯ãã£ãã§ãã æ®æ®µã©ã®ãããªäºã«æéãæèãå²ããŠããããšããã®ãåãããšèªåã®ä»äºã®æ¯çãšæ¯ã¹ãŠã¿ã¡ãããŸããã ãããããçãããæ°ã«ãªã QA ãšã³ãžãã¢ã®ãã£ãªã¢ã«ã€ããŠãäºäººã話ããããŸããã 米山㯠15 幎㮠QA çµéšãæã£ãŠããŸããããã®äžã§ã¢ãžã£ã€ã«ããã¹ãèªååãªã©ã®ãã¬ã³ãã«ã¯ãèªåã§ãã§ããããªããšæããªããå°å
¥ãããŠãã£ããšã®ããšã§ãããããããªãããèªåã®äžã®ãã©ã€ãªãªãã£ã¯ãããŸã§ãäºæ¥ã»ãããã¯ããšããéšåã ã£ãã®ã§ãããã«ã³ããããã§ããç«ã¡äœçœ®ã§ã®ä»äºããã£ãšç¶ããŠãããšèšããŸãã å
ã®ãã£ãªã¢ãšããŠã¯ãããžã·ã§ã³ã«æãããäºæ¥äŸ¡å€ãé«ããããã«åããŠãããã©ã®ãããªç¶æ³ã®ããŒã ã§ãå質ãé«ããããã®æšé²ãã§ããããã«ããŠãããããšããããšã§ããã äžæ¹ã®æšªç°ãããä»ãŸã§ã®çµéšãèžãŸã QA ã®ããžã·ã§ã³ãé«ããŠããããããªåããããŠãããããšããããšã§ããããã¹ããªã©ã«èå³ãæã€äººã®è£ŸéãåºããŠãããããšããææ¬²ãæããŸãããå人ãšããŠã¯ UI/UX ãªã©ãå«ããŠå質ãé«ãããšããããšãã§ããã°ãšã®ããšã§ããã ãäºäººãšãããèªåã®ãã£ãªã¢ãã«çãŸããåšå²ã®äººéã«ããè¯ã圱é¿ãäžããŠãããããšããããšããã£ããã£ãŠããã®ãéåžžã«å°è±¡çã§ããã æåŸã« 玹ä»ãã以å€ã«ãçŸå Žã«å³ãã QA ã«ã€ããŠããå質ã«ã€ããŠã®èãæ¹ã®äžç«¯ãåãããããªã€ãã³ãã§ãããèªåã¯ãšã³ãžãã¢ãšããç«å Žã§èŠèŽããŠããŸãããããããã人éã«ã倧å€ã«ç€ºåã«å¯ãã話ãå€ãããã£ãšããéã« 1 æéãçµéããŸãããQA ãšã³ãžãã¢ã®æ¹ã¯ãã¡ããããã®ä»ãããã¯ããäœããšããããšã«é¢ããæ¹ã¯ãã²ãã¢ãŒã«ã€ããèŠèŽããŠã¿ãŠãã ãã!
ã¯ããã« ããã«ã¡ã¯ãæè¡åºå ±ã»ãšã³ãžãã¢ã®å¹³æšã§ããæè¿äœ¿ã£ãŠãã Emacs ã Spacemacs ãã Doom Emacs ã«å€æŽãããšããæ°åãæ°ãã«ããã¹ã掻åãæãããã«ãªããŸããã ããŠã2022/05/11 ã«è¡ãªããã ã QA Night ãçµç¹å
ã§ QA ãšã³ãžãã¢ãããªã¥ãŒãçºæ®ãããã£ãªã¢ã¢ããããã«ã¯ã ã ãšãã QA ãšã³ãžãã¢åãã€ãã³ãã§åŒç€Ÿ QA ãšã³ãžãã¢ç±³å±±ããããªã¹ããšããŠç»å£ããŸããã®ã§ããã®æ§åãã€ãã³ãã¬ããŒããšããŠãå±ãããããšæããŸãã QA Night ãšã¯ ãã¡ãã®ã€ãã³ã㯠Showcase Gig ãããäž»å¬ããŠããã€ãã³ãã§ãã Geek Gig ãšãããšã³ãžãã¢ãªã³ã°ã«ã€ããŠã®å®æã€ãã³ãããããŸããŠããã®ã·ãªãŒãºã® 1 ã€ãšããŠéå¶ããããã®ã§ãã ä»å㯠Showcase Gig ãããåŒç€Ÿããã¹ãèªååããŒã«ã® MagicPod ã䜿ã£ãŠãããšãããçžããã声ããããã ãã€ãã³ãéå¬ã®éã³ãšãªããŸããã ã€ãã³ãã«ã€ã㊠ä»åã®ã€ãã³ãã¯ãããã«ãã£ã¹ã«ãã·ã§ã³ãšã㊠2 瀟㮠QA ã«ã€ããŠããããèªã圢åŒã«ãªããŸããã ã¢ãã¬ãŒã¿ãŒã Showcase Gig ãœãããŠã§ã¢ãšã³ãžãã¢ã§ VP of Technology ã§ãã èæ± ãã ãè¡ãªãããããªã¹ããšã㊠Showcase Gig QA ãšã³ãžã㢠暪ç°ãã ãšãåŒç€Ÿ QA ãšã³ãžãã¢ç±³å±±ãšã§ãã£ãã°ããã«ã€ãã³ããé²è¡ããŠãããŸããã QA ãšã³ãžãã¢ã®æ¹ã ãã§ã¯ãªããã¢ãã¬ãŒã¿ãŒã«ãšã³ãžãã¢ã®æ¹ãå
¥ã£ãããšã«ãããã©ã³ã¹ãè¯ãããã«ãã£ã¹ã«ãã·ã§ã³ã«ãªã£ãŠãããšããææ³ã§ããã ãã¡ãã®ã€ãã³ã㯠connpass ã§å
¬éåŸããããããããš 140 人ãŸã§ç³ã蟌ã¿ããããæ³šç®åºŠã®é«ãã䌺ããŸããã åœæ¥ã®ã€ãã³ãã®æ§åã¯äžèšããã芧ããã ããŸãã®ã§ããèå³ã®ããæ¹ã¯ãã²ã ããã«ãã£ã¹ã«ãã·ã§ã³ ããã«ãã£ã¹ã«ãã·ã§ã³ã¯å€§ãŸãã«ä»¥äžã®ãããªã»ã¯ã·ã§ã³ã«åãããŠå®æœãããŸããã ãããªã¹ãã»ã¢ãã¬ãŒã¿ãŒèªå·±çŽ¹ä» å瀟ã®éçº/QA ããã»ã¹ã®çæ³ãšçŸå® QA ãšã³ãžãã¢ãããªãã£ããã©ããªã? QA ãšã³ãžãã¢ã®ãã£ãªã¢ ãããã®ã»ã¯ã·ã§ã³ã«åãããŠããããªã¹ãããããã®ç«å Žã§åçãããŠãããŸããããéäžã§èŠèŽãããŠããæ¹ã®è³ªåãªã©ã¯ãã¢ãã¬ãŒã¿ãŒã®èæ± ãããã»ãŒãªã¢ã«ã¿ã€ã ã§æŸã£ãŠãããªããã®é²è¡ã ã£ãã®ã§ãã€ãã³ãã®äžäœæãéåžžã«æããããŠé¢çœãã£ãã§ãã èªå·±çŽ¹ä» æšªç°ããã米山ãçŸè·ã«è³ããŸã§ã®çµæŽãããªã䌌ãŠããŸããã第äžè
æ€èšŒäŒç€Ÿã§æ§ã
ãªæ¥æ
ã®äŒç€Ÿã顧客ãšããŠãæ§ã
ãªçµéšãç©ã¿éããŠãããäºæ¥äŒç€Ÿã§ã® QA ãšã³ãžãã¢ãšããŠç¹å®ã®ãããã¯ãã®å質ãé«ããä»äºãããŠããã£ããããšããç¹ã§ãã 第äžè
æ€èšŒäŒç€Ÿã§æ§ã
ãªããŒãºã«å¯Ÿå¿ããããšãããããã¯ããžã®è²¢ç®ã«æŽ»ããŠãããã ãšæããŸããã å瀟ã®éçº/QA ããã»ã¹ã®çæ³ãšçŸå® QA ãå«ããéçºäœå¶ã«ã€ããŠã¯ã䞡瀟ã§éãããã¡ãããããŸãã倧ããéãã§ãããšãçŸåšã®ã¡ãã¬ãŒã§ã¯ãããã¯ãéçºããŒã ã®äžå¡ãšã㊠QA ãšã³ãžãã¢ãæå±ããŠããŸãã仿¹ãShowcase Gig ããã§ã¯è€æ°ã®éçºããŒã ãæšªæã㊠QA ããŒã ãååšããŠãããšããéšåã§ããããã ã¡ãã¬ãŒã®çŸåšã®éçºäœå¶ã§ã¯ãããŒã å
ã§éçºã¡ã³ããŒãšå¯æ¥ã«ããåããããªããå質ãé«ããŠãããšããããã»ã¹ãåãããŠãããå¥ã®éçºããŒã ã®ãã«ããªã©ãããã¡ãããããŸããã¢ããã€ã¶ãŒçãªæãã§ãå®éã«ã¯ãã®ããŒã å
ã§å質ãé«ããããã«åããŠããŸãã äžæ¹ã§ Showcase Gig ããã§ã¯æšªæããŒã ãšããŠåãããã¯ãã俯ç°ããŠèŠãããããªäœå¶ã«ããŠããå°è±¡ã§ãããããããã®éçºããŒã ãšã¯èŠæã§ã·ã³ã¯ã¢ããããããšã«ããäŒç€Ÿå
šäœã§ã® QA ããã»ã¹ãçµ±äžããªããåããŒã ã«å±éã§ããã®ãè¯ãããã ãªãšæããŸããã çæ³ãšçŸå®ã«ã€ã㊠ãããªäž¡ç€Ÿã§ãããå
±éããéšåãšããŠäºæ¥é åã®é£ããããããŸããã ã¡ãã¬ãŒã¯å»çé åãšããé£ãããShowcase Gig ããã§ã¯ãªã³ã©ã€ã³ãšãªãã©ã€ã³ã®äž¡ç«ãããªããã°ãªããªãéšåãç¹ã«é£ãããšã®ããšã ãããã話㯠QA ã®çæ³ãšçŸå®ã«ç§»ã£ãŠãããŸããã¡ãã¬ãŒã§ã¯ãããã¯ãã®ããäžæµéšåã§ãã仿§çå®éšåãããã°ã朰ããããã«ããŠããã®ãç®æãã€ã€ããã¬ãã¬ããªæ¹æ³ãäœå¶ã«ãªããªãããã«æ¥ã
QA ãè¡ãªã£ãŠããŸãããŸã E2E ãã¹ãã®å€±æãéåžžäºæ
ã ãšã¡ã³ããŒãçŠããããã«æåçãé«ããŠãããããšããçæ³ããããŸãããã©ãããŠãããã¥ã¢ã«ã§ã®ãã¹ããå¿
èŠã«ãªã£ãŠãããããã¯ããªã®ã§ãE2E ãã¹ãã ãã«é Œããªãããã«è©Šè¡é¯èª€ããŠããŸãã Showcase Gig ããã§ã¯åè³ªã¯æ
ä¿ãã€ã€ãä»ä»¥äžã«ãªãªãŒã¹é »åºŠãäžããããã«ã©ããããè¯ãããšããç¹ãéçºããŒã ãšåæ¥ã§æ¹åããããšãããŠããããã§ããMagicPod ã䜿ã£ã E2E ãã¹ãã ãã§ãªãªãŒã¹ãŸã§ã§ããããã«ããã®ãçæ³ã§ã¯ãããŸããããã®åã«ããã»ã¹ã®å¶å®ãªã©å段éã®æºåãçã
ãšããŠããããã§ãã QA ãšã³ãžãã¢ãããªãã£ããã©ããªã? QA ãšã³ãžãã¢ã®ã€ãã³ãã§äžã
åºãŠããªããããªèšåããã倧å€é¢çœãã£ãã®ã§ãããããããã®ãQA ãšã³ãžãã¢ãããªãã£ããã©ããªã?ããšããèšåã§ããã è峿·±ãã£ãã®ã¯ãäºäººãšãåããããªè¿çã ã£ãããšã§ãã䞡瀟ãšãããªãªãŒã¹ã¯éåžžéãè¡ãªãããã ãããããªãªãŒã¹åŸã®äžå
·å察å¿ãªã©ãå¢ãããããããªãããšããããšã§ããããŸããããå
±éããŠãQA ãšã³ãžãã¢ãããªããŠãå質ä¿èšŒããããããšãçæ³ããšããã話ã§ããã å®éã« QA ãšã³ãžãã¢ã¯ããªããŠããã¡ããšé«ãå質ã®ãããã¯ããäžã«åºããŠãããä»çµã¿ãäœå¶ãçæ³ãšããã®ã¯ãé¢ä¿è
ã«å質ã«ã€ããŠã®æèãæ ¹å·®ããŠãããããã«ãããšããææ°èŸŒã¿ã®ããã«èããæéãåããŸããã QA ãšã³ãžãã¢ã®ãã£ãªã¢ ãŸãæ®æ®µãäºäººã¯ã©ã®ãããªæèé
åã§æ¥ã
ã®ä»äºããããŠããããšããã®ãåã°ã©ãã§è¡šãã詊ã¿ãè¯ãã£ãã§ãã æ®æ®µã©ã®ãããªäºã«æéãæèãå²ããŠããããšããã®ãåãããšèªåã®ä»äºã®æ¯çãšæ¯ã¹ãŠã¿ã¡ãããŸããã ãããããçãããæ°ã«ãªã QA ãšã³ãžãã¢ã®ãã£ãªã¢ã«ã€ããŠãäºäººã話ããããŸããã 米山㯠15 幎㮠QA çµéšãæã£ãŠããŸããããã®äžã§ã¢ãžã£ã€ã«ããã¹ãèªååãªã©ã®ãã¬ã³ãã«ã¯ãèªåã§ãã§ããããªããšæããªããå°å
¥ãããŠãã£ããšã®ããšã§ãããããããªãããèªåã®äžã®ãã©ã€ãªãªãã£ã¯ãããŸã§ãäºæ¥ã»ãããã¯ããšããéšåã ã£ãã®ã§ãããã«ã³ããããã§ããç«ã¡äœçœ®ã§ã®ä»äºããã£ãšç¶ããŠãããšèšããŸãã å
ã®ãã£ãªã¢ãšããŠã¯ãããžã·ã§ã³ã«æãããäºæ¥äŸ¡å€ãé«ããããã«åããŠãããã©ã®ãããªç¶æ³ã®ããŒã ã§ãå質ãé«ããããã®æšé²ãã§ããããã«ããŠãããããšããããšã§ããã äžæ¹ã®æšªç°ãããä»ãŸã§ã®çµéšãèžãŸã QA ã®ããžã·ã§ã³ãé«ããŠããããããªåããããŠãããããšããããšã§ããããã¹ããªã©ã«èå³ãæã€äººã®è£ŸéãåºããŠãããããšããææ¬²ãæããŸãããå人ãšããŠã¯ UI/UX ãªã©ãå«ããŠå質ãé«ãããšããããšãã§ããã°ãšã®ããšã§ããã ãäºäººãšãããèªåã®ãã£ãªã¢ãã«çãŸããåšå²ã®äººéã«ããè¯ã圱é¿ãäžããŠãããããšããããšããã£ããã£ãŠããã®ãéåžžã«å°è±¡çã§ããã æåŸã« 玹ä»ãã以å€ã«ãçŸå Žã«å³ãã QA ã«ã€ããŠããå質ã«ã€ããŠã®èãæ¹ã®äžç«¯ãåãããããªã€ãã³ãã§ãããèªåã¯ãšã³ãžãã¢ãšããç«å Žã§èŠèŽããŠããŸãããããããã人éã«ã倧å€ã«ç€ºåã«å¯ãã話ãå€ãããã£ãšããéã« 1 æéãçµéããŸãããQA ãšã³ãžãã¢ã®æ¹ã¯ãã¡ããããã®ä»ãããã¯ããäœããšããããšã«é¢ããæ¹ã¯ãã²ãã¢ãŒã«ã€ããèŠèŽããŠã¿ãŠãã ãã!
ã¯ããã« ããã«ã¡ã¯ãæè¡åºå ±ã»ãšã³ãžãã¢ã®å¹³æšã§ããæè¿äœ¿ã£ãŠãã Emacs ã Spacemacs ãã Doom Emacs ã«å€æŽãããšããæ°åãæ°ãã«ããã¹ã掻åãæãããã«ãªããŸããã ããŠã2022/05/11 ã«è¡ãªããã ã QA Night ãçµç¹å
ã§ QA ãšã³ãžãã¢ãããªã¥ãŒãçºæ®ãããã£ãªã¢ã¢ããããã«ã¯ã ã ãšãã QA ãšã³ãžãã¢åãã€ãã³ãã§åŒç€Ÿ QA ãšã³ãžãã¢ç±³å±±ããããªã¹ããšããŠç»å£ããŸããã®ã§ããã®æ§åãã€ãã³ãã¬ããŒããšããŠãå±ãããããšæããŸãã QA Night ãšã¯ ãã¡ãã®ã€ãã³ã㯠Showcase Gig ãããäž»å¬ããŠããã€ãã³ãã§ãã Geek Gig ãšãããšã³ãžãã¢ãªã³ã°ã«ã€ããŠã®å®æã€ãã³ãããããŸããŠããã®ã·ãªãŒãºã® 1 ã€ãšããŠéå¶ããããã®ã§ãã ä»å㯠Showcase Gig ãããåŒç€Ÿããã¹ãèªååããŒã«ã® MagicPod ã䜿ã£ãŠãããšãããçžããã声ããããã ãã€ãã³ãéå¬ã®éã³ãšãªããŸããã ã€ãã³ãã«ã€ã㊠ä»åã®ã€ãã³ãã¯ãããã«ãã£ã¹ã«ãã·ã§ã³ãšã㊠2 瀟㮠QA ã«ã€ããŠããããèªã圢åŒã«ãªããŸããã ã¢ãã¬ãŒã¿ãŒã Showcase Gig ãœãããŠã§ã¢ãšã³ãžãã¢ã§ VP of Technology ã§ãã èæ± ãã ãè¡ãªãããããªã¹ããšã㊠Showcase Gig QA ãšã³ãžã㢠暪ç°ãã ãšãåŒç€Ÿ QA ãšã³ãžãã¢ç±³å±±ãšã§ãã£ãã°ããã«ã€ãã³ããé²è¡ããŠãããŸããã QA ãšã³ãžãã¢ã®æ¹ã ãã§ã¯ãªããã¢ãã¬ãŒã¿ãŒã«ãšã³ãžãã¢ã®æ¹ãå
¥ã£ãããšã«ãããã©ã³ã¹ãè¯ãããã«ãã£ã¹ã«ãã·ã§ã³ã«ãªã£ãŠãããšããææ³ã§ããã ãã¡ãã®ã€ãã³ã㯠connpass ã§å
¬éåŸããããããããš 140 人ãŸã§ç³ã蟌ã¿ããããæ³šç®åºŠã®é«ãã䌺ããŸããã åœæ¥ã®ã€ãã³ãã®æ§åã¯äžèšããã芧ããã ããŸãã®ã§ããèå³ã®ããæ¹ã¯ãã²ã ããã«ãã£ã¹ã«ãã·ã§ã³ ããã«ãã£ã¹ã«ãã·ã§ã³ã¯å€§ãŸãã«ä»¥äžã®ãããªã»ã¯ã·ã§ã³ã«åãããŠå®æœãããŸããã ãããªã¹ãã»ã¢ãã¬ãŒã¿ãŒèªå·±çŽ¹ä» å瀟ã®éçº/QA ããã»ã¹ã®çæ³ãšçŸå® QA ãšã³ãžãã¢ãããªãã£ããã©ããªã? QA ãšã³ãžãã¢ã®ãã£ãªã¢ ãããã®ã»ã¯ã·ã§ã³ã«åãããŠããããªã¹ãããããã®ç«å Žã§åçãããŠãããŸããããéäžã§èŠèŽãããŠããæ¹ã®è³ªåãªã©ã¯ãã¢ãã¬ãŒã¿ãŒã®èæ± ãããã»ãŒãªã¢ã«ã¿ã€ã ã§æŸã£ãŠãããªããã®é²è¡ã ã£ãã®ã§ãã€ãã³ãã®äžäœæãéåžžã«æããããŠé¢çœãã£ãã§ãã èªå·±çŽ¹ä» æšªç°ããã米山ãçŸè·ã«è³ããŸã§ã®çµæŽãããªã䌌ãŠããŸããã第äžè
æ€èšŒäŒç€Ÿã§æ§ã
ãªæ¥æ
ã®äŒç€Ÿã顧客ãšããŠãæ§ã
ãªçµéšãç©ã¿éããŠãããäºæ¥äŒç€Ÿã§ã® QA ãšã³ãžãã¢ãšããŠç¹å®ã®ãããã¯ãã®å質ãé«ããä»äºãããŠããã£ããããšããç¹ã§ãã 第äžè
æ€èšŒäŒç€Ÿã§æ§ã
ãªããŒãºã«å¯Ÿå¿ããããšãããããã¯ããžã®è²¢ç®ã«æŽ»ããŠãããã ãšæããŸããã å瀟ã®éçº/QA ããã»ã¹ã®çæ³ãšçŸå® QA ãå«ããéçºäœå¶ã«ã€ããŠã¯ã䞡瀟ã§éãããã¡ãããããŸãã倧ããéãã§ãããšãçŸåšã®ã¡ãã¬ãŒã§ã¯ãããã¯ãéçºããŒã ã®äžå¡ãšã㊠QA ãšã³ãžãã¢ãæå±ããŠããŸãã仿¹ãShowcase Gig ããã§ã¯è€æ°ã®éçºããŒã ãæšªæã㊠QA ããŒã ãååšããŠãããšããéšåã§ããããã ã¡ãã¬ãŒã®çŸåšã®éçºäœå¶ã§ã¯ãããŒã å
ã§éçºã¡ã³ããŒãšå¯æ¥ã«ããåããããªããå質ãé«ããŠãããšããããã»ã¹ãåãããŠãããå¥ã®éçºããŒã ã®ãã«ããªã©ãããã¡ãããããŸããã¢ããã€ã¶ãŒçãªæãã§ãå®éã«ã¯ãã®ããŒã å
ã§å質ãé«ããããã«åããŠããŸãã äžæ¹ã§ Showcase Gig ããã§ã¯æšªæããŒã ãšããŠåãããã¯ãã俯ç°ããŠèŠãããããªäœå¶ã«ããŠããå°è±¡ã§ãããããããã®éçºããŒã ãšã¯èŠæã§ã·ã³ã¯ã¢ããããããšã«ããäŒç€Ÿå
šäœã§ã® QA ããã»ã¹ãçµ±äžããªããåããŒã ã«å±éã§ããã®ãè¯ãããã ãªãšæããŸããã çæ³ãšçŸå®ã«ã€ã㊠ãããªäž¡ç€Ÿã§ãããå
±éããéšåãšããŠäºæ¥é åã®é£ããããããŸããã ã¡ãã¬ãŒã¯å»çé åãšããé£ãããShowcase Gig ããã§ã¯ãªã³ã©ã€ã³ãšãªãã©ã€ã³ã®äž¡ç«ãããªããã°ãªããªãéšåãç¹ã«é£ãããšã®ããšã ãããã話㯠QA ã®çæ³ãšçŸå®ã«ç§»ã£ãŠãããŸããã¡ãã¬ãŒã§ã¯ãããã¯ãã®ããäžæµéšåã§ãã仿§çå®éšåãããã°ã朰ããããã«ããŠããã®ãç®æãã€ã€ããã¬ãã¬ããªæ¹æ³ãäœå¶ã«ãªããªãããã«æ¥ã
QA ãè¡ãªã£ãŠããŸãããŸã E2E ãã¹ãã®å€±æãéåžžäºæ
ã ãšã¡ã³ããŒãçŠããããã«æåçãé«ããŠãããããšããçæ³ããããŸãããã©ãããŠãããã¥ã¢ã«ã§ã®ãã¹ããå¿
èŠã«ãªã£ãŠãããããã¯ããªã®ã§ãE2E ãã¹ãã ãã«é Œããªãããã«è©Šè¡é¯èª€ããŠããŸãã Showcase Gig ããã§ã¯åè³ªã¯æ
ä¿ãã€ã€ãä»ä»¥äžã«ãªãªãŒã¹é »åºŠãäžããããã«ã©ããããè¯ãããšããç¹ãéçºããŒã ãšåæ¥ã§æ¹åããããšãããŠããããã§ããMagicPod ã䜿ã£ã E2E ãã¹ãã ãã§ãªãªãŒã¹ãŸã§ã§ããããã«ããã®ãçæ³ã§ã¯ãããŸããããã®åã«ããã»ã¹ã®å¶å®ãªã©å段éã®æºåãçã
ãšããŠããããã§ãã QA ãšã³ãžãã¢ãããªãã£ããã©ããªã? QA ãšã³ãžãã¢ã®ã€ãã³ãã§äžã
åºãŠããªããããªèšåããã倧å€é¢çœãã£ãã®ã§ãããããããã®ãQA ãšã³ãžãã¢ãããªãã£ããã©ããªã?ããšããèšåã§ããã è峿·±ãã£ãã®ã¯ãäºäººãšãåããããªè¿çã ã£ãããšã§ãã䞡瀟ãšãããªãªãŒã¹ã¯éåžžéãè¡ãªãããã ãããããªãªãŒã¹åŸã®äžå
·å察å¿ãªã©ãå¢ãããããããªãããšããããšã§ããããŸããããå
±éããŠãQA ãšã³ãžãã¢ãããªããŠãå質ä¿èšŒããããããšãçæ³ããšããã話ã§ããã å®éã« QA ãšã³ãžãã¢ã¯ããªããŠããã¡ããšé«ãå質ã®ãããã¯ããäžã«åºããŠãããä»çµã¿ãäœå¶ãçæ³ãšããã®ã¯ãé¢ä¿è
ã«å質ã«ã€ããŠã®æèãæ ¹å·®ããŠãããããã«ãããšããææ°èŸŒã¿ã®ããã«èããæéãåããŸããã QA ãšã³ãžãã¢ã®ãã£ãªã¢ ãŸãæ®æ®µãäºäººã¯ã©ã®ãããªæèé
åã§æ¥ã
ã®ä»äºããããŠããããšããã®ãåã°ã©ãã§è¡šãã詊ã¿ãè¯ãã£ãã§ãã æ®æ®µã©ã®ãããªäºã«æéãæèãå²ããŠããããšããã®ãåãããšèªåã®ä»äºã®æ¯çãšæ¯ã¹ãŠã¿ã¡ãããŸããã ãããããçãããæ°ã«ãªã QA ãšã³ãžãã¢ã®ãã£ãªã¢ã«ã€ããŠãäºäººã話ããããŸããã 米山㯠15 幎㮠QA çµéšãæã£ãŠããŸããããã®äžã§ã¢ãžã£ã€ã«ããã¹ãèªååãªã©ã®ãã¬ã³ãã«ã¯ãèªåã§ãã§ããããªããšæããªããå°å
¥ãããŠãã£ããšã®ããšã§ãããããããªãããèªåã®äžã®ãã©ã€ãªãªãã£ã¯ãããŸã§ãäºæ¥ã»ãããã¯ããšããéšåã ã£ãã®ã§ãããã«ã³ããããã§ããç«ã¡äœçœ®ã§ã®ä»äºããã£ãšç¶ããŠãããšèšããŸãã å
ã®ãã£ãªã¢ãšããŠã¯ãããžã·ã§ã³ã«æãããäºæ¥äŸ¡å€ãé«ããããã«åããŠãããã©ã®ãããªç¶æ³ã®ããŒã ã§ãå質ãé«ããããã®æšé²ãã§ããããã«ããŠãããããšããããšã§ããã äžæ¹ã®æšªç°ãããä»ãŸã§ã®çµéšãèžãŸã QA ã®ããžã·ã§ã³ãé«ããŠããããããªåããããŠãããããšããããšã§ããããã¹ããªã©ã«èå³ãæã€äººã®è£ŸéãåºããŠãããããšããææ¬²ãæããŸãããå人ãšããŠã¯ UI/UX ãªã©ãå«ããŠå質ãé«ãããšããããšãã§ããã°ãšã®ããšã§ããã ãäºäººãšãããèªåã®ãã£ãªã¢ãã«çãŸããåšå²ã®äººéã«ããè¯ã圱é¿ãäžããŠãããããšããããšããã£ããã£ãŠããã®ãéåžžã«å°è±¡çã§ããã æåŸã« 玹ä»ãã以å€ã«ãçŸå Žã«å³ãã QA ã«ã€ããŠããå質ã«ã€ããŠã®èãæ¹ã®äžç«¯ãåãããããªã€ãã³ãã§ãããèªåã¯ãšã³ãžãã¢ãšããç«å Žã§èŠèŽããŠããŸãããããããã人éã«ã倧å€ã«ç€ºåã«å¯ãã話ãå€ãããã£ãšããéã« 1 æéãçµéããŸãããQA ãšã³ãžãã¢ã®æ¹ã¯ãã¡ããããã®ä»ãããã¯ããäœããšããããšã«é¢ããæ¹ã¯ãã²ãã¢ãŒã«ã€ããèŠèŽããŠã¿ãŠãã ãã!
ã¯ããã« ããã«ã¡ã¯ãæè¡åºå ±ã»ãšã³ãžãã¢ã®å¹³æšã§ããæè¿äœ¿ã£ãŠãã Emacs ã Spacemacs ãã Doom Emacs ã«å€æŽãããšããæ°åãæ°ãã«ããã¹ã掻åãæãããã«ãªããŸããã ããŠã2022/05/11 ã«è¡ãªããã ã QA Night ãçµç¹å
ã§ QA ãšã³ãžãã¢ãããªã¥ãŒãçºæ®ãããã£ãªã¢ã¢ããããã«ã¯ã ã ãšãã QA ãšã³ãžãã¢åãã€ãã³ãã§åŒç€Ÿ QA ãšã³ãžãã¢ç±³å±±ããããªã¹ããšããŠç»å£ããŸããã®ã§ããã®æ§åãã€ãã³ãã¬ããŒããšããŠãå±ãããããšæããŸãã QA Night ãšã¯ ãã¡ãã®ã€ãã³ã㯠Showcase Gig ãããäž»å¬ããŠããã€ãã³ãã§ãã Geek Gig ãšãããšã³ãžãã¢ãªã³ã°ã«ã€ããŠã®å®æã€ãã³ãããããŸããŠããã®ã·ãªãŒãºã® 1 ã€ãšããŠéå¶ããããã®ã§ãã ä»å㯠Showcase Gig ãããåŒç€Ÿããã¹ãèªååããŒã«ã® MagicPod ã䜿ã£ãŠãããšãããçžããã声ããããã ãã€ãã³ãéå¬ã®éã³ãšãªããŸããã ã€ãã³ãã«ã€ã㊠ä»åã®ã€ãã³ãã¯ãããã«ãã£ã¹ã«ãã·ã§ã³ãšã㊠2 瀟㮠QA ã«ã€ããŠããããèªã圢åŒã«ãªããŸããã ã¢ãã¬ãŒã¿ãŒã Showcase Gig ãœãããŠã§ã¢ãšã³ãžãã¢ã§ VP of Technology ã§ãã èæ± ãã ãè¡ãªãããããªã¹ããšã㊠Showcase Gig QA ãšã³ãžã㢠暪ç°ãã ãšãåŒç€Ÿ QA ãšã³ãžãã¢ç±³å±±ãšã§ãã£ãã°ããã«ã€ãã³ããé²è¡ããŠãããŸããã QA ãšã³ãžãã¢ã®æ¹ã ãã§ã¯ãªããã¢ãã¬ãŒã¿ãŒã«ãšã³ãžãã¢ã®æ¹ãå
¥ã£ãããšã«ãããã©ã³ã¹ãè¯ãããã«ãã£ã¹ã«ãã·ã§ã³ã«ãªã£ãŠãããšããææ³ã§ããã ãã¡ãã®ã€ãã³ã㯠connpass ã§å
¬éåŸããããããããš 140 人ãŸã§ç³ã蟌ã¿ããããæ³šç®åºŠã®é«ãã䌺ããŸããã åœæ¥ã®ã€ãã³ãã®æ§åã¯äžèšããã芧ããã ããŸãã®ã§ããèå³ã®ããæ¹ã¯ãã²ã ããã«ãã£ã¹ã«ãã·ã§ã³ ããã«ãã£ã¹ã«ãã·ã§ã³ã¯å€§ãŸãã«ä»¥äžã®ãããªã»ã¯ã·ã§ã³ã«åãããŠå®æœãããŸããã ãããªã¹ãã»ã¢ãã¬ãŒã¿ãŒèªå·±çŽ¹ä» å瀟ã®éçº/QA ããã»ã¹ã®çæ³ãšçŸå® QA ãšã³ãžãã¢ãããªãã£ããã©ããªã? QA ãšã³ãžãã¢ã®ãã£ãªã¢ ãããã®ã»ã¯ã·ã§ã³ã«åãããŠããããªã¹ãããããã®ç«å Žã§åçãããŠãããŸããããéäžã§èŠèŽãããŠããæ¹ã®è³ªåãªã©ã¯ãã¢ãã¬ãŒã¿ãŒã®èæ± ãããã»ãŒãªã¢ã«ã¿ã€ã ã§æŸã£ãŠãããªããã®é²è¡ã ã£ãã®ã§ãã€ãã³ãã®äžäœæãéåžžã«æããããŠé¢çœãã£ãã§ãã èªå·±çŽ¹ä» æšªç°ããã米山ãçŸè·ã«è³ããŸã§ã®çµæŽãããªã䌌ãŠããŸããã第äžè
æ€èšŒäŒç€Ÿã§æ§ã
ãªæ¥æ
ã®äŒç€Ÿã顧客ãšããŠãæ§ã
ãªçµéšãç©ã¿éããŠãããäºæ¥äŒç€Ÿã§ã® QA ãšã³ãžãã¢ãšããŠç¹å®ã®ãããã¯ãã®å質ãé«ããä»äºãããŠããã£ããããšããç¹ã§ãã 第äžè
æ€èšŒäŒç€Ÿã§æ§ã
ãªããŒãºã«å¯Ÿå¿ããããšãããããã¯ããžã®è²¢ç®ã«æŽ»ããŠãããã ãšæããŸããã å瀟ã®éçº/QA ããã»ã¹ã®çæ³ãšçŸå® QA ãå«ããéçºäœå¶ã«ã€ããŠã¯ã䞡瀟ã§éãããã¡ãããããŸãã倧ããéãã§ãããšãçŸåšã®ã¡ãã¬ãŒã§ã¯ãããã¯ãéçºããŒã ã®äžå¡ãšã㊠QA ãšã³ãžãã¢ãæå±ããŠããŸãã仿¹ãShowcase Gig ããã§ã¯è€æ°ã®éçºããŒã ãæšªæã㊠QA ããŒã ãååšããŠãããšããéšåã§ããããã ã¡ãã¬ãŒã®çŸåšã®éçºäœå¶ã§ã¯ãããŒã å
ã§éçºã¡ã³ããŒãšå¯æ¥ã«ããåããããªããå質ãé«ããŠãããšããããã»ã¹ãåãããŠãããå¥ã®éçºããŒã ã®ãã«ããªã©ãããã¡ãããããŸããã¢ããã€ã¶ãŒçãªæãã§ãå®éã«ã¯ãã®ããŒã å
ã§å質ãé«ããããã«åããŠããŸãã äžæ¹ã§ Showcase Gig ããã§ã¯æšªæããŒã ãšããŠåãããã¯ãã俯ç°ããŠèŠãããããªäœå¶ã«ããŠããå°è±¡ã§ãããããããã®éçºããŒã ãšã¯èŠæã§ã·ã³ã¯ã¢ããããããšã«ããäŒç€Ÿå
šäœã§ã® QA ããã»ã¹ãçµ±äžããªããåããŒã ã«å±éã§ããã®ãè¯ãããã ãªãšæããŸããã çæ³ãšçŸå®ã«ã€ã㊠ãããªäž¡ç€Ÿã§ãããå
±éããéšåãšããŠäºæ¥é åã®é£ããããããŸããã ã¡ãã¬ãŒã¯å»çé åãšããé£ãããShowcase Gig ããã§ã¯ãªã³ã©ã€ã³ãšãªãã©ã€ã³ã®äž¡ç«ãããªããã°ãªããªãéšåãç¹ã«é£ãããšã®ããšã ãããã話㯠QA ã®çæ³ãšçŸå®ã«ç§»ã£ãŠãããŸããã¡ãã¬ãŒã§ã¯ãããã¯ãã®ããäžæµéšåã§ãã仿§çå®éšåãããã°ã朰ããããã«ããŠããã®ãç®æãã€ã€ããã¬ãã¬ããªæ¹æ³ãäœå¶ã«ãªããªãããã«æ¥ã
QA ãè¡ãªã£ãŠããŸãããŸã E2E ãã¹ãã®å€±æãéåžžäºæ
ã ãšã¡ã³ããŒãçŠããããã«æåçãé«ããŠãããããšããçæ³ããããŸãããã©ãããŠãããã¥ã¢ã«ã§ã®ãã¹ããå¿
èŠã«ãªã£ãŠãããããã¯ããªã®ã§ãE2E ãã¹ãã ãã«é Œããªãããã«è©Šè¡é¯èª€ããŠããŸãã Showcase Gig ããã§ã¯åè³ªã¯æ
ä¿ãã€ã€ãä»ä»¥äžã«ãªãªãŒã¹é »åºŠãäžããããã«ã©ããããè¯ãããšããç¹ãéçºããŒã ãšåæ¥ã§æ¹åããããšãããŠããããã§ããMagicPod ã䜿ã£ã E2E ãã¹ãã ãã§ãªãªãŒã¹ãŸã§ã§ããããã«ããã®ãçæ³ã§ã¯ãããŸããããã®åã«ããã»ã¹ã®å¶å®ãªã©å段éã®æºåãçã
ãšããŠããããã§ãã QA ãšã³ãžãã¢ãããªãã£ããã©ããªã? QA ãšã³ãžãã¢ã®ã€ãã³ãã§äžã
åºãŠããªããããªèšåããã倧å€é¢çœãã£ãã®ã§ãããããããã®ãQA ãšã³ãžãã¢ãããªãã£ããã©ããªã?ããšããèšåã§ããã è峿·±ãã£ãã®ã¯ãäºäººãšãåããããªè¿çã ã£ãããšã§ãã䞡瀟ãšãããªãªãŒã¹ã¯éåžžéãè¡ãªãããã ãããããªãªãŒã¹åŸã®äžå
·å察å¿ãªã©ãå¢ãããããããªãããšããããšã§ããããŸããããå
±éããŠãQA ãšã³ãžãã¢ãããªããŠãå質ä¿èšŒããããããšãçæ³ããšããã話ã§ããã å®éã« QA ãšã³ãžãã¢ã¯ããªããŠããã¡ããšé«ãå質ã®ãããã¯ããäžã«åºããŠãããä»çµã¿ãäœå¶ãçæ³ãšããã®ã¯ãé¢ä¿è
ã«å質ã«ã€ããŠã®æèãæ ¹å·®ããŠãããããã«ãããšããææ°èŸŒã¿ã®ããã«èããæéãåããŸããã QA ãšã³ãžãã¢ã®ãã£ãªã¢ ãŸãæ®æ®µãäºäººã¯ã©ã®ãããªæèé
åã§æ¥ã
ã®ä»äºããããŠããããšããã®ãåã°ã©ãã§è¡šãã詊ã¿ãè¯ãã£ãã§ãã æ®æ®µã©ã®ãããªäºã«æéãæèãå²ããŠããããšããã®ãåãããšèªåã®ä»äºã®æ¯çãšæ¯ã¹ãŠã¿ã¡ãããŸããã ãããããçãããæ°ã«ãªã QA ãšã³ãžãã¢ã®ãã£ãªã¢ã«ã€ããŠãäºäººã話ããããŸããã 米山㯠15 幎㮠QA çµéšãæã£ãŠããŸããããã®äžã§ã¢ãžã£ã€ã«ããã¹ãèªååãªã©ã®ãã¬ã³ãã«ã¯ãèªåã§ãã§ããããªããšæããªããå°å
¥ãããŠãã£ããšã®ããšã§ãããããããªãããèªåã®äžã®ãã©ã€ãªãªãã£ã¯ãããŸã§ãäºæ¥ã»ãããã¯ããšããéšåã ã£ãã®ã§ãããã«ã³ããããã§ããç«ã¡äœçœ®ã§ã®ä»äºããã£ãšç¶ããŠãããšèšããŸãã å
ã®ãã£ãªã¢ãšããŠã¯ãããžã·ã§ã³ã«æãããäºæ¥äŸ¡å€ãé«ããããã«åããŠãããã©ã®ãããªç¶æ³ã®ããŒã ã§ãå質ãé«ããããã®æšé²ãã§ããããã«ããŠãããããšããããšã§ããã äžæ¹ã®æšªç°ãããä»ãŸã§ã®çµéšãèžãŸã QA ã®ããžã·ã§ã³ãé«ããŠããããããªåããããŠãããããšããããšã§ããããã¹ããªã©ã«èå³ãæã€äººã®è£ŸéãåºããŠãããããšããææ¬²ãæããŸãããå人ãšããŠã¯ UI/UX ãªã©ãå«ããŠå質ãé«ãããšããããšãã§ããã°ãšã®ããšã§ããã ãäºäººãšãããèªåã®ãã£ãªã¢ãã«çãŸããåšå²ã®äººéã«ããè¯ã圱é¿ãäžããŠãããããšããããšããã£ããã£ãŠããã®ãéåžžã«å°è±¡çã§ããã æåŸã« 玹ä»ãã以å€ã«ãçŸå Žã«å³ãã QA ã«ã€ããŠããå質ã«ã€ããŠã®èãæ¹ã®äžç«¯ãåãããããªã€ãã³ãã§ãããèªåã¯ãšã³ãžãã¢ãšããç«å Žã§èŠèŽããŠããŸãããããããã人éã«ã倧å€ã«ç€ºåã«å¯ãã話ãå€ãããã£ãšããéã« 1 æéãçµéããŸãããQA ãšã³ãžãã¢ã®æ¹ã¯ãã¡ããããã®ä»ãããã¯ããäœããšããããšã«é¢ããæ¹ã¯ãã²ãã¢ãŒã«ã€ããèŠèŽããŠã¿ãŠãã ãã!
ã¯ããã« çãããããã«ã¡ã¯ããšã³ãžãã¢ã»æè¡åºå ±ã®å¹³æšã§ãã 以åããã芧ã«ãªã£ãŠããã ããŠããæ¹ã«ã¯ãåããããšæããŸããã3/18 ã«ä»ã芧ããã ããŠãããšã³ãžãã¢ã»ãã¶ã€ããŒããã°ããDeveloper Portalããšããåç§°ã«å€æŽã㊠2017 å¹Žä»¥æ¥ 5 幎ã¶ãã«ãªãã¥ãŒã¢ã«ãããŸãããä»åã¯ãªãã¥ãŒã¢ã«ã«ã€ããŠãç®æããšãããšè¥å¹²ã®æè¡çãªåŽé¢ããäŒãã§ããã°ãšæããŸãã ããã°ãããæ°æ§æ¯èŒ æ§ æ° ãšã³ãžãã¢ã»ãã¶ã€ããŒããã°ãªãã¥ãŒã¢ã«ã®èæ¯ ãŸãã¯ã ãªããªãã¥ãŒã¢ã«ããã? ãšããèæ¯ã«ã€ããŠã§ããåŒç€Ÿã®ãšã³ãžãã¢ã»ãã¶ã€ããŒããã°ã®å€é·ãšå
±ã«ã話ããŠãããããšæããŸãã ãšã³ãžãã¢ã»ãã¶ã€ããŒããã°ã®å€é· 第 1 æ(2016/04 ~ 2017/07) Developer Blog 㯠2016/04 æã«äŒç€Ÿå
¬åŒããã°ã«ãšã³ãžãã¢åãã®èšäºãæ²èŒãå§ããããããããã°ããã¯ä»ã®äŒç€Ÿæ
å ±ãšãšãã«æ²èŒãããŠããŸãããèšäºå
容ã¯ãšã³ãžãã¢ãç»å£ããã€ãã³ãæ
å ±ããä»ãç¶ããŠãã TechLunch(å
šç€Ÿæšªæã®ãšã³ãžãã¢ã»ãã¶ã€ããŒåã瀟å
å匷äŒ) ã®çºè¡šã¬ããŒããªã©ãã¡ã€ã³ãšãªã£ãŠããŸããã ãã®é ã¯éçºçµç¹ã®äººæ°ããããŸã§å€ããªãã£ãã®ã§ãããã¡ãã¬ãŒã®éçºçµç¹ã瀟å
ã®æ§ã
ãªéšçœ²ã®é°å²æ°ãšå
±ã«ãäŒãããããšããç®çãã¡ã€ã³ã§ããããŸãã¯ãã¡ãã¬ãŒã®éçºçµç¹ãšããŠã®ãã¬ãŒã³ã¹ãé«ãããããã¯ããå
è£œã§æ¥ã
éçºãããŠããããšããå€éšã®çããã«ç¥ã£ãŠãããããšããç®çãäžçªå€§ããã£ãããã«æããŸãã ãã®ãããªåœ¢ã§ 2017 幎äžé ãŸã§ã¯äŒç€Ÿå
¬åŒããã°ã§ã®æŽæ°ãããŠããŸããããéçºçµç¹ãæ¡å€§ããã«ã€ããçµç¹ãšããŠåºæ¥ãããšãå¢ããŠããŸãããããã«äŒŽãããããŸã§ã®ããã«ãéçºçµç¹ã®ååšã®ã¢ããŒã«ãããçµç¹ã®åãçµã¿ãã«å ããŠãçŽç²ã«æè¡çãªåŽé¢ããã£ãšæã¡åºããŠãããå»ç x ITããšããããŒãã«ã¡ãã¬ãŒã¯ã©ã®ããã«åããã£ãŠããããç¥ã£ãŠãããããšããæ©éãé«ãŸã£ãŠããŸããã 第 2 æ(2017/07 ~ 2022/03) ããããéã³ã§æ°ãã Medley Developer Blog ã 2017/07 æã«ç«ã¡äžããããšã«ãªããŸãããäŒç€Ÿå
¬åŒããã°ããå®å
šã«ç¬ç«ããããã¯ããã°ãšããããšã§ãç®è«èŠéãã«ãããŸã§ä»¥äžã«æè¡çãªæçš¿ãã§ããããã«ãªããŸãããç·šéæ¹åŒããã®æããçŸåšãŸã§ãšã³ãžãã¢ã»ãã¶ã€ããŒãäž»äœãšãªã£ãŠããŸãã æŽæ°é »åºŠãäžå®æã ã£ããã®ãæ 1~2 åãšå¢ãããã³ã³ã¹ã¿ã³ãã«ã¡ãã¬ãŒã®éçºã«é¢ãã話é¡ãåãæ±ãããã«ããŸãããéå¶ãããŠãã 5 幎ã®éã«ããã€ãã®èšäºã¯ããããããŸã§ã¯ãŠãªããã¯ããŒã¯ãªã©ã§ è©±é¡ ã«ãªãããšãããã第 1 æãããããã«çããã«èªãã§ããã ãããããªããã°ã«ãªããŸããã ãã®éã«ã¡ãã¬ãŒãæ§ã
ãªãšã³ãžãã¢ã»ãã¶ã€ããŒã€ãã³ãã«ã¹ãã³ãµãŒããããŠããã ããããããŠãããã°ãšåãããŠäžå®ã®ãã¬ãŒã³ã¹ãåŸãããšãã§ããŠããã®ã§ã¯ãªãããšæã£ãŠããŸããç¹ã«ãå»çãã«ã¹ã±ã¢æ¥çããšãã銎æã¿ãç¡ãæ¹ã«ã¯ããŒãã«ãé«ããšæãããããšãå€ãæ¥çã§ã®ãããã¯ãéçºã«ãäžè¬çãªã€ã³ã¿ãŒããããã¯ãããžãŒãé§äœ¿ããŠãããšããç¹ããè²ã
ãªåŽé¢ãããäŒãã§ããããã«ãªã£ãããšã¯å€§ãããšæããŠããŸãã çŸåš(2022/03 ~) ãããªããã°ã§ããããéèšãã 5 幎çµã¡ä»¥äžã®ãããªèª²é¡ãåºãŠããŸããã äŒç€ŸããŸã äžå Žåã«äœããããã¶ã€ã³ã ã£ããããçŸåšã®ã³ãŒãã¬ãŒããµã€ããªã©ã®ããŒã³ãšãºã¬ãåºãŠããŠãã äŒç€Ÿãçµç¹èŠæš¡ã倧ãããªããåžèã«ãªããã¡ãªå
éšã§åããŠããå人ã«ããã©ãŒã«ã¹ãåœãŠããããããªã³ã³ãã³ããæ¬²ãã æ¡çšçãªåŽé¢ãšããŠãã¡ãã¬ãŒã«èå³ãæã£ãæ¹ãžæäŸã§ããæ
å ±ããã©ãã©ã«ãªã£ãŠãã 以äžã®èª²é¡ã解決ããããã«ãããã°ã®ãªãã¥ãŒã¢ã«ãããããšã«ãªããŸããã ç¹ã«ä»å¹Žããå
šç€Ÿçãªæ¹éãšããŠãã¡ãã¬ãŒã®ãœããé¢ã§ã®è©±é¡ã«ãã©ãŒã«ã¹ããã³ã³ãã³ããäœã£ãŠãããšããããšã§ãæ¹ããŠå
¬åŒ note ã®æŽæ°ã«æ³šåããŠããããšãããããšã³ãžãã¢ã»ãã¶ã€ããŒããã°ããã®åããšé£åããå¿
èŠããããŸããã 以äžã®çç±ãããã³ã³ãã³ããšããŠã¯åŸæ¥éãã® ããã°èšäº ãæ§ã
ãªã¡ãã£ã¢ã§ã¡ã³ããŒãé²åºããŠãã ã€ã³ã¿ãã¥ãŒèšäº ãã€ãã³ããªã©ã§äœ¿ããã çºè¡šã¹ã©ã€ã ãå
šãŠèŠããããããªç·åçãªãµã€ãã«ããŠããããšãšãªããŸããã ã€ã³ã¿ãã¥ãŒã¯ãããŸã§ãã¡ã³ããŒãæ§ã
ãªã¡ãã£ã¢ã«åºãŠããããã¹ã©ã€ãã以åãã Speaker Deck ãæŽæ°ããŠããã®ã§ããããŸãšãŸã£ã圢ã§ã®æäŸãã§ããŠããŸããã§ããã ä»åã®ãªãã¥ãŒã¢ã«ã§ããããã®èŠçŽ ããŸãšããŠçããã«ãå±ãã§ããããã«ãªã£ãããããMedley Developer BlogããããMedley Developer Portalããšåç§°å€æŽãããŸããã ããããããã¡ãã¬ãŒã®éçºçµç¹ãããå€éšã®çããã«ç¥ã£ãŠãããããã«ãéå¶ãã§ããã°ãšèããŠããŸãã®ã§ããããããé¡ãããŸãã ãšã³ãžãã¢ã»ãã¶ã€ããŒããã°ãªãã¥ãŒã¢ã«ã®æè¡é¢ã«ã€ã㊠ããŠããããŸã§ãªãã¥ãŒã¢ã«ã®èæ¯ããäŒãããŸããããããããã¯ä»å䜿ã£ãæè¡é¢ã«ã€ããŠè»œãè§ŠããŠããããšæããŸãã äœ¿çšæè¡ã«ã€ã㊠æ§ããã°ã¯ãã¯ãŠãªããã°ãã§ã®éçšãããŠããŸããããªãã¥ãŒã¢ã«ã«ããã£ãŠäžèšã®èª²é¡ã解決ããããã«ã¯ãç¬èªã«ããã°ãéçºããã»ãããããšèããŸãããæ°ããã°ã¯ä»¥äžã®æè¡ã䜿ã£ãŠéçºããŸããã Gatsby Emotion TypeScript Netlify Gatsby ã«æ±ºããçç±ã¯å€§ããã¯ä»¥äžã§ããã æ¢ã«åŒç€Ÿå
ã§ Gatsby ã®å°å
¥å®çžŸãããããã瀟å
ã®ã¡ã³ããŒããããšãªã£ããè§Šãã ããã° + α ã®ãµã€ããäœãã®ã«ååãªæè»æ§ããã å
¬åŒãã³ãã¥ããã£ãã©ã°ã€ã³ãå
å®ããŠãããéçºãçååã§ãã Gatsby ã¯ç²Ÿåçã«ã¢ããããŒããè¡ãªãããŠãããæ©ããµã€ã¯ã«ã§é²åããã®ãé
åã® 1 ã€ã§ããã Gatsby 補ãµã€ããã©ã®ããã«å
¬éãããã¯ãæ©ãã ã®ã§ãããçµæçã«äºäŸãå€ããããããã€ã®ç°¡æããæ©èœã®è±å¯ããèã㊠Netlify ã«ããŸããã ã¯ãŠãªããã°ããã®èšäºç§»è¡ã«ã€ã㊠æåããæ§ããã°ã§ã®ã³ã³ãã³ãã¯æ°ããã°ã«ç§»è¡ããããšããã¹ãã ã£ãã®ã§ããŸãã¯ã©ã®ããã«ç§»è¡ãã§ããããšããããšãèæ
®ããããšããå§ããŸãããã¯ãŠãªããã°ã¯éåžžã®ãšã¯ã¹ããŒãã ãš Movable Type æ¹åŒã«ãªãã®ã§ããªããšã Markdown ã«å€æãããâŠãªã©ãšèããŠããŸããã ãããã blogsync ãšããã¯ãŠãªããã°ã® CLI ã¯ã©ã€ã¢ã³ããéããšããŒã«ã«ã« Markdown ãã¡ã€ã«ãšããŠããã°ãšã³ããªãåæããããšãå¯èœã ã£ãããã blogsync ã§å
šãŠã®æ§ããã°ã³ã³ãã³ããããŒã«ã«ã«åæ(ããŠã³ããŒã) ããŒã«ã«ã« Markdown ãã¡ã€ã«ãšããŠããŠã³ããŒãã§ããããã°ã³ã³ãã³ãã Gatsby è£œã®æ°ããã°ã«ã³ã㌠gatsby-source-filesystem ã§ã³ããŒãã Markdown ãã¡ã€ã«ãèªã¿èŸŒã¿ããã°ãšããŠè¡šç€º ãšããæé ã§æ¢åã®ããã°èšäºãå
šãŠç§»è¡ããããšãã§ããŸããã ãŸãããã¡ã€ã³ã«ã€ããŠã¯ç¬èªãã¡ã€ã³ããã®ãŸãŸæ°ããã°ã«ãç§»è¡ããããšãšãããããã¯ãŠãªããã°ãšåã URL 圢åŒã§ããã°ãèªã¿èŸŒããããã«ã«ãŒãã£ã³ã°ãããŸããã èŠåŽããéšå ä»åã®éçºã§èŠåŽããéšåããã€ãžã§ã¹ãã§æžããŠãããŸããèªåã®ããŒãºã«åãããŠèª¿ã¹ãŠã¿ãŠããç¹ã«æ·±ãéšåã«é¢ããŠãããŸãæ
å ±ãåºãŠããªããšãããã¿ãŒã³ãå€ãã£ãããã«æããŸãã ããŒãžã§ã³åºæã®æ
å ±ãããã©ã°ã€ã³ã®æ
å ±ãå°ãªãã£ã éçºåœå㯠Gatsby v4 ãåºãã°ããã ã£ãã®ã§ãäœãã«å°ã£ãŠæ€çŽ¢ããŠãå
¬åŒä»¥å€ã®æ
å ±ã¯ä»¥åã®ããŒãžã§ã³ã§äœ¿ããªãããšãå€ãã£ãã§ãã ãŸããã©ã°ã€ã³é¢ä¿ã®æ
å ±ã調ã¹ãå
容ã«ãã£ãŠã¯äžã
ç®çã®æ
å ±ãåºãŠããªãã£ããããŸããã gatsby-plugin-image åšãã§é¡èãªå°è±¡ã ã£ãã®ã§ãç»ååšãã®è¡šç€ºã«æ³£ããããããšããããŸããã ä»ã«ã Markdown 衚瀺㯠gatsby-plugin-mdx ã䜿çšããŠããŸãããåŸæ¥ã® gatsby-transformer-remark ãšæ
å ±ãæ··åšããŠããå°è±¡ããããŸããã®ã§æ··ä¹±ããããšãã ããŒãžããŒã·ã§ã³ã§ãã¹ããªãã©ã°ã€ã³ãèŠã€ãããªãã£ã å
¬åŒ ã¬ã€ããåèã«ããŒãžããŒã·ã§ã³ãèªåã§äœã£ãŠããã®ã§ããã GraphQL ããæã£ãŠããããŒã¿ã衚瀺ããã ãã§ã¯ããŸããŠãŒã¶ããªãã£ãè¯ããªãã£ãããããã©ã°ã€ã³ãªã©æ¢ããã®ã§ãããããšãã£ããã®ãèŠã€ãããªãã£ãã§ãã å
¬åŒã¬ã€ãåèã«äœããšå»¶ã
èšäºãå¢ãããããŒãžããŒã·ã§ã³ã®æ°ãå¢ããŠãã£ãŠããŸã埮åŠãªæãã§ããâŠãèªåã§å¶åŸ¡ãèããŸããããæçµçã«ã¯ mui/pagination ã³ã³ããŒãã³ããçµã¿åãããããšã§å¯Ÿå¿ããŸããã OGP ç»åèªåçæã«é¢ããŠæ
å ±ãå°ãªã OGP ç»åã¯èªåçæã«ããããšæããŸããããæ¡å€ããŒãºãç¡ãã®ãæ
å ±ãå°ãªãã£ãå°è±¡ã§ããæçµçã« ãã¡ã ã®ããã°ãçºèŠãã kentaro-m/catchy-image ã䜿ã£ãŠçæããããã«ããŸããã ããããããããããš æ©èœã®æ¡å
以å€ã ãšãä»ãŸã§ã¯ã§ããªãã£ã textlint ã§ã®æ ¡æ£ãªã©ãããŠãç·šéæã®è² è·è»œæžãªã©ããã£ãŠãããããšèããŠããŸãã ããã㫠以äžã Developer Portal ã®ãªãã¥ãŒã¢ã«ã«ã€ããŠæžãããŠããã ããŸããã åŒãç¶ããæ
å ±çºä¿¡ãªã©ãããŠããã¡ãã¬ãŒéçºçµç¹ã«ã€ããŠãçããã«ç¥ã£ãŠããã ããã°ãšæããŸãã æåŸã«ãªããŸãããå»çãã«ã¹ã±ã¢ã®ãããã¯ãéçºã«(ãã®ãããªããã°è£œäœã)é¢ãã£ãŠãããã!ãšããæ¹ã¯ãã²äžèšãããå¿åãåŸ
ã¡ããŠãããŸã! åéã®äžèЧ | æ ªåŒäŒç€Ÿã¡ãã¬ãŒ ã¡ãã¬ãŒã®æ¡çšæ
å ±ã¯ãã¡ãããã確èªãã ããã www.medley.jp
ã¯ããã« çãããããã«ã¡ã¯ããšã³ãžãã¢ã»æè¡åºå ±ã®å¹³æšã§ãã 以åããã芧ã«ãªã£ãŠããã ããŠããæ¹ã«ã¯ãåããããšæããŸããã3/18 ã«ä»ã芧ããã ããŠãããšã³ãžãã¢ã»ãã¶ã€ããŒããã°ããDeveloper Portalããšããåç§°ã«å€æŽã㊠2017 å¹Žä»¥æ¥ 5 幎ã¶ãã«ãªãã¥ãŒã¢ã«ãããŸãããä»åã¯ãªãã¥ãŒã¢ã«ã«ã€ããŠãç®æããšãããšè¥å¹²ã®æè¡çãªåŽé¢ããäŒãã§ããã°ãšæããŸãã ããã°ãããæ°æ§æ¯èŒ æ§ æ° ãšã³ãžãã¢ã»ãã¶ã€ããŒããã°ãªãã¥ãŒã¢ã«ã®èæ¯ ãŸãã¯ã ãªããªãã¥ãŒã¢ã«ããã? ãšããèæ¯ã«ã€ããŠã§ããåŒç€Ÿã®ãšã³ãžãã¢ã»ãã¶ã€ããŒããã°ã®å€é·ãšå
±ã«ã話ããŠãããããšæããŸãã ãšã³ãžãã¢ã»ãã¶ã€ããŒããã°ã®å€é· 第 1 æ(2016/04 ~ 2017/07) Developer Blog 㯠2016/04 æã«äŒç€Ÿå
¬åŒããã°ã«ãšã³ãžãã¢åãã®èšäºãæ²èŒãå§ããããããããã°ããã¯ä»ã®äŒç€Ÿæ
å ±ãšãšãã«æ²èŒãããŠããŸãããèšäºå
容ã¯ãšã³ãžãã¢ãç»å£ããã€ãã³ãæ
å ±ããä»ãç¶ããŠãã TechLunch(å
šç€Ÿæšªæã®ãšã³ãžãã¢ã»ãã¶ã€ããŒåã瀟å
å匷äŒ) ã®çºè¡šã¬ããŒããªã©ãã¡ã€ã³ãšãªã£ãŠããŸããã ãã®é ã¯éçºçµç¹ã®äººæ°ããããŸã§å€ããªãã£ãã®ã§ãããã¡ãã¬ãŒã®éçºçµç¹ã瀟å
ã®æ§ã
ãªéšçœ²ã®é°å²æ°ãšå
±ã«ãäŒãããããšããç®çãã¡ã€ã³ã§ããããŸãã¯ãã¡ãã¬ãŒã®éçºçµç¹ãšããŠã®ãã¬ãŒã³ã¹ãé«ãããããã¯ããå
è£œã§æ¥ã
éçºãããŠããããšããå€éšã®çããã«ç¥ã£ãŠãããããšããç®çãäžçªå€§ããã£ãããã«æããŸãã ãã®ãããªåœ¢ã§ 2017 幎äžé ãŸã§ã¯äŒç€Ÿå
¬åŒããã°ã§ã®æŽæ°ãããŠããŸããããéçºçµç¹ãæ¡å€§ããã«ã€ããçµç¹ãšããŠåºæ¥ãããšãå¢ããŠããŸãããããã«äŒŽãããããŸã§ã®ããã«ãéçºçµç¹ã®ååšã®ã¢ããŒã«ãããçµç¹ã®åãçµã¿ãã«å ããŠãçŽç²ã«æè¡çãªåŽé¢ããã£ãšæã¡åºããŠãããå»ç x ITããšããããŒãã«ã¡ãã¬ãŒã¯ã©ã®ããã«åããã£ãŠããããç¥ã£ãŠãããããšããæ©éãé«ãŸã£ãŠããŸããã 第 2 æ(2017/07 ~ 2022/03) ããããéã³ã§æ°ãã Medley Developer Blog ã 2017/07 æã«ç«ã¡äžããããšã«ãªããŸãããäŒç€Ÿå
¬åŒããã°ããå®å
šã«ç¬ç«ããããã¯ããã°ãšããããšã§ãç®è«èŠéãã«ãããŸã§ä»¥äžã«æè¡çãªæçš¿ãã§ããããã«ãªããŸãããç·šéæ¹åŒããã®æããçŸåšãŸã§ãšã³ãžãã¢ã»ãã¶ã€ããŒãäž»äœãšãªã£ãŠããŸãã æŽæ°é »åºŠãäžå®æã ã£ããã®ãæ 1~2 åãšå¢ãããã³ã³ã¹ã¿ã³ãã«ã¡ãã¬ãŒã®éçºã«é¢ãã話é¡ãåãæ±ãããã«ããŸãããéå¶ãããŠãã 5 幎ã®éã«ããã€ãã®èšäºã¯ããããããŸã§ã¯ãŠãªããã¯ããŒã¯ãªã©ã§ è©±é¡ ã«ãªãããšãããã第 1 æãããããã«çããã«èªãã§ããã ãããããªããã°ã«ãªããŸããã ãã®éã«ã¡ãã¬ãŒãæ§ã
ãªãšã³ãžãã¢ã»ãã¶ã€ããŒã€ãã³ãã«ã¹ãã³ãµãŒããããŠããã ããããããŠãããã°ãšåãããŠäžå®ã®ãã¬ãŒã³ã¹ãåŸãããšãã§ããŠããã®ã§ã¯ãªãããšæã£ãŠããŸããç¹ã«ãå»çãã«ã¹ã±ã¢æ¥çããšãã銎æã¿ãç¡ãæ¹ã«ã¯ããŒãã«ãé«ããšæãããããšãå€ãæ¥çã§ã®ãããã¯ãéçºã«ãäžè¬çãªã€ã³ã¿ãŒããããã¯ãããžãŒãé§äœ¿ããŠãããšããç¹ããè²ã
ãªåŽé¢ãããäŒãã§ããããã«ãªã£ãããšã¯å€§ãããšæããŠããŸãã çŸåš(2022/03 ~) ãããªããã°ã§ããããéèšãã 5 幎çµã¡ä»¥äžã®ãããªèª²é¡ãåºãŠããŸããã äŒç€ŸããŸã äžå Žåã«äœããããã¶ã€ã³ã ã£ããããçŸåšã®ã³ãŒãã¬ãŒããµã€ããªã©ã®ããŒã³ãšãºã¬ãåºãŠããŠãã äŒç€Ÿãçµç¹èŠæš¡ã倧ãããªããåžèã«ãªããã¡ãªå
éšã§åããŠããå人ã«ããã©ãŒã«ã¹ãåœãŠããããããªã³ã³ãã³ããæ¬²ãã æ¡çšçãªåŽé¢ãšããŠãã¡ãã¬ãŒã«èå³ãæã£ãæ¹ãžæäŸã§ããæ
å ±ããã©ãã©ã«ãªã£ãŠãã 以äžã®èª²é¡ã解決ããããã«ãããã°ã®ãªãã¥ãŒã¢ã«ãããããšã«ãªããŸããã ç¹ã«ä»å¹Žããå
šç€Ÿçãªæ¹éãšããŠãã¡ãã¬ãŒã®ãœããé¢ã§ã®è©±é¡ã«ãã©ãŒã«ã¹ããã³ã³ãã³ããäœã£ãŠãããšããããšã§ãæ¹ããŠå
¬åŒ note ã®æŽæ°ã«æ³šåããŠããããšãããããšã³ãžãã¢ã»ãã¶ã€ããŒããã°ããã®åããšé£åããå¿
èŠããããŸããã 以äžã®çç±ãããã³ã³ãã³ããšããŠã¯åŸæ¥éãã® ããã°èšäº ãæ§ã
ãªã¡ãã£ã¢ã§ã¡ã³ããŒãé²åºããŠãã ã€ã³ã¿ãã¥ãŒèšäº ãã€ãã³ããªã©ã§äœ¿ããã çºè¡šã¹ã©ã€ã ãå
šãŠèŠããããããªç·åçãªãµã€ãã«ããŠããããšãšãªããŸããã ã€ã³ã¿ãã¥ãŒã¯ãããŸã§ãã¡ã³ããŒãæ§ã
ãªã¡ãã£ã¢ã«åºãŠããããã¹ã©ã€ãã以åãã Speaker Deck ãæŽæ°ããŠããã®ã§ããããŸãšãŸã£ã圢ã§ã®æäŸãã§ããŠããŸããã§ããã ä»åã®ãªãã¥ãŒã¢ã«ã§ããããã®èŠçŽ ããŸãšããŠçããã«ãå±ãã§ããããã«ãªã£ãããããMedley Developer BlogããããMedley Developer Portalããšåç§°å€æŽãããŸããã ããããããã¡ãã¬ãŒã®éçºçµç¹ãããå€éšã®çããã«ç¥ã£ãŠãããããã«ãéå¶ãã§ããã°ãšèããŠããŸãã®ã§ããããããé¡ãããŸãã ãšã³ãžãã¢ã»ãã¶ã€ããŒããã°ãªãã¥ãŒã¢ã«ã®æè¡é¢ã«ã€ã㊠ããŠããããŸã§ãªãã¥ãŒã¢ã«ã®èæ¯ããäŒãããŸããããããããã¯ä»å䜿ã£ãæè¡é¢ã«ã€ããŠè»œãè§ŠããŠããããšæããŸãã äœ¿çšæè¡ã«ã€ã㊠æ§ããã°ã¯ãã¯ãŠãªããã°ãã§ã®éçšãããŠããŸããããªãã¥ãŒã¢ã«ã«ããã£ãŠäžèšã®èª²é¡ã解決ããããã«ã¯ãç¬èªã«ããã°ãéçºããã»ãããããšèããŸãããæ°ããã°ã¯ä»¥äžã®æè¡ã䜿ã£ãŠéçºããŸããã Gatsby Emotion TypeScript Netlify Gatsby ã«æ±ºããçç±ã¯å€§ããã¯ä»¥äžã§ããã æ¢ã«åŒç€Ÿå
ã§ Gatsby ã®å°å
¥å®çžŸãããããã瀟å
ã®ã¡ã³ããŒããããšãªã£ããè§Šãã ããã° + α ã®ãµã€ããäœãã®ã«ååãªæè»æ§ããã å
¬åŒãã³ãã¥ããã£ãã©ã°ã€ã³ãå
å®ããŠãããéçºãçååã§ãã Gatsby ã¯ç²Ÿåçã«ã¢ããããŒããè¡ãªãããŠãããæ©ããµã€ã¯ã«ã§é²åããã®ãé
åã® 1 ã€ã§ããã Gatsby 補ãµã€ããã©ã®ããã«å
¬éãããã¯ãæ©ãã ã®ã§ãããçµæçã«äºäŸãå€ããããããã€ã®ç°¡æããæ©èœã®è±å¯ããèã㊠Netlify ã«ããŸããã ã¯ãŠãªããã°ããã®èšäºç§»è¡ã«ã€ã㊠æåããæ§ããã°ã§ã®ã³ã³ãã³ãã¯æ°ããã°ã«ç§»è¡ããããšããã¹ãã ã£ãã®ã§ããŸãã¯ã©ã®ããã«ç§»è¡ãã§ããããšããããšãèæ
®ããããšããå§ããŸãããã¯ãŠãªããã°ã¯éåžžã®ãšã¯ã¹ããŒãã ãš Movable Type æ¹åŒã«ãªãã®ã§ããªããšã Markdown ã«å€æãããâŠãªã©ãšèããŠããŸããã ãããã blogsync ãšããã¯ãŠãªããã°ã® CLI ã¯ã©ã€ã¢ã³ããéããšããŒã«ã«ã« Markdown ãã¡ã€ã«ãšããŠããã°ãšã³ããªãåæããããšãå¯èœã ã£ãããã blogsync ã§å
šãŠã®æ§ããã°ã³ã³ãã³ããããŒã«ã«ã«åæ(ããŠã³ããŒã) ããŒã«ã«ã« Markdown ãã¡ã€ã«ãšããŠããŠã³ããŒãã§ããããã°ã³ã³ãã³ãã Gatsby è£œã®æ°ããã°ã«ã³ã㌠gatsby-source-filesystem ã§ã³ããŒãã Markdown ãã¡ã€ã«ãèªã¿èŸŒã¿ããã°ãšããŠè¡šç€º ãšããæé ã§æ¢åã®ããã°èšäºãå
šãŠç§»è¡ããããšãã§ããŸããã ãŸãããã¡ã€ã³ã«ã€ããŠã¯ç¬èªãã¡ã€ã³ããã®ãŸãŸæ°ããã°ã«ãç§»è¡ããããšãšãããããã¯ãŠãªããã°ãšåã URL 圢åŒã§ããã°ãèªã¿èŸŒããããã«ã«ãŒãã£ã³ã°ãããŸããã èŠåŽããéšå ä»åã®éçºã§èŠåŽããéšåããã€ãžã§ã¹ãã§æžããŠãããŸããèªåã®ããŒãºã«åãããŠèª¿ã¹ãŠã¿ãŠããç¹ã«æ·±ãéšåã«é¢ããŠãããŸãæ
å ±ãåºãŠããªããšãããã¿ãŒã³ãå€ãã£ãããã«æããŸãã ããŒãžã§ã³åºæã®æ
å ±ãããã©ã°ã€ã³ã®æ
å ±ãå°ãªãã£ã éçºåœå㯠Gatsby v4 ãåºãã°ããã ã£ãã®ã§ãäœãã«å°ã£ãŠæ€çŽ¢ããŠãå
¬åŒä»¥å€ã®æ
å ±ã¯ä»¥åã®ããŒãžã§ã³ã§äœ¿ããªãããšãå€ãã£ãã§ãã ãŸããã©ã°ã€ã³é¢ä¿ã®æ
å ±ã調ã¹ãå
容ã«ãã£ãŠã¯äžã
ç®çã®æ
å ±ãåºãŠããªãã£ããããŸããã gatsby-plugin-image åšãã§é¡èãªå°è±¡ã ã£ãã®ã§ãç»ååšãã®è¡šç€ºã«æ³£ããããããšããããŸããã ä»ã«ã Markdown 衚瀺㯠gatsby-plugin-mdx ã䜿çšããŠããŸãããåŸæ¥ã® gatsby-transformer-remark ãšæ
å ±ãæ··åšããŠããå°è±¡ããããŸããã®ã§æ··ä¹±ããããšãã ããŒãžããŒã·ã§ã³ã§ãã¹ããªãã©ã°ã€ã³ãèŠã€ãããªãã£ã å
¬åŒ ã¬ã€ããåèã«ããŒãžããŒã·ã§ã³ãèªåã§äœã£ãŠããã®ã§ããã GraphQL ããæã£ãŠããããŒã¿ã衚瀺ããã ãã§ã¯ããŸããŠãŒã¶ããªãã£ãè¯ããªãã£ãããããã©ã°ã€ã³ãªã©æ¢ããã®ã§ãããããšãã£ããã®ãèŠã€ãããªãã£ãã§ãã å
¬åŒã¬ã€ãåèã«äœããšå»¶ã
èšäºãå¢ãããããŒãžããŒã·ã§ã³ã®æ°ãå¢ããŠãã£ãŠããŸã埮åŠãªæãã§ããâŠãèªåã§å¶åŸ¡ãèããŸããããæçµçã«ã¯ mui/pagination ã³ã³ããŒãã³ããçµã¿åãããããšã§å¯Ÿå¿ããŸããã OGP ç»åèªåçæã«é¢ããŠæ
å ±ãå°ãªã OGP ç»åã¯èªåçæã«ããããšæããŸããããæ¡å€ããŒãºãç¡ãã®ãæ
å ±ãå°ãªãã£ãå°è±¡ã§ããæçµçã« ãã¡ã ã®ããã°ãçºèŠãã kentaro-m/catchy-image ã䜿ã£ãŠçæããããã«ããŸããã ããããããããããš æ©èœã®æ¡å
以å€ã ãšãä»ãŸã§ã¯ã§ããªãã£ã textlint ã§ã®æ ¡æ£ãªã©ãããŠãç·šéæã®è² è·è»œæžãªã©ããã£ãŠãããããšèããŠããŸãã ããã㫠以äžã Developer Portal ã®ãªãã¥ãŒã¢ã«ã«ã€ããŠæžãããŠããã ããŸããã åŒãç¶ããæ
å ±çºä¿¡ãªã©ãããŠããã¡ãã¬ãŒéçºçµç¹ã«ã€ããŠãçããã«ç¥ã£ãŠããã ããã°ãšæããŸãã æåŸã«ãªããŸãããå»çãã«ã¹ã±ã¢ã®ãããã¯ãéçºã«(ãã®ãããªããã°è£œäœã)é¢ãã£ãŠãããã!ãšããæ¹ã¯ãã²äžèšãããå¿åãåŸ
ã¡ããŠãããŸã! åéã®äžèЧ | æ ªåŒäŒç€Ÿã¡ãã¬ãŒ ã¡ãã¬ãŒã®æ¡çšæ
å ±ã¯ãã¡ãããã確èªãã ããã www.medley.jp
ã¯ããã« çãããããã«ã¡ã¯ããšã³ãžãã¢ã»æè¡åºå ±ã®å¹³æšã§ãã 以åããã芧ã«ãªã£ãŠããã ããŠããæ¹ã«ã¯ãåããããšæããŸããã3/18 ã«ä»ã芧ããã ããŠãããšã³ãžãã¢ã»ãã¶ã€ããŒããã°ããDeveloper Portalããšããåç§°ã«å€æŽã㊠2017 å¹Žä»¥æ¥ 5 幎ã¶ãã«ãªãã¥ãŒã¢ã«ãããŸãããä»åã¯ãªãã¥ãŒã¢ã«ã«ã€ããŠãç®æããšãããšè¥å¹²ã®æè¡çãªåŽé¢ããäŒãã§ããã°ãšæããŸãã ããã°ãããæ°æ§æ¯èŒ æ§ æ° ãšã³ãžãã¢ã»ãã¶ã€ããŒããã°ãªãã¥ãŒã¢ã«ã®èæ¯ ãŸãã¯ã ãªããªãã¥ãŒã¢ã«ããã? ãšããèæ¯ã«ã€ããŠã§ããåŒç€Ÿã®ãšã³ãžãã¢ã»ãã¶ã€ããŒããã°ã®å€é·ãšå
±ã«ã話ããŠãããããšæããŸãã ãšã³ãžãã¢ã»ãã¶ã€ããŒããã°ã®å€é· 第 1 æ(2016/04 ~ 2017/07) Developer Blog 㯠2016/04 æã«äŒç€Ÿå
¬åŒããã°ã«ãšã³ãžãã¢åãã®èšäºãæ²èŒãå§ããããããããã°ããã¯ä»ã®äŒç€Ÿæ
å ±ãšãšãã«æ²èŒãããŠããŸãããèšäºå
容ã¯ãšã³ãžãã¢ãç»å£ããã€ãã³ãæ
å ±ããä»ãç¶ããŠãã TechLunch(å
šç€Ÿæšªæã®ãšã³ãžãã¢ã»ãã¶ã€ããŒåã瀟å
å匷äŒ) ã®çºè¡šã¬ããŒããªã©ãã¡ã€ã³ãšãªã£ãŠããŸããã ãã®é ã¯éçºçµç¹ã®äººæ°ããããŸã§å€ããªãã£ãã®ã§ãããã¡ãã¬ãŒã®éçºçµç¹ã瀟å
ã®æ§ã
ãªéšçœ²ã®é°å²æ°ãšå
±ã«ãäŒãããããšããç®çãã¡ã€ã³ã§ããããŸãã¯ãã¡ãã¬ãŒã®éçºçµç¹ãšããŠã®ãã¬ãŒã³ã¹ãé«ãããããã¯ããå
è£œã§æ¥ã
éçºãããŠããããšããå€éšã®çããã«ç¥ã£ãŠãããããšããç®çãäžçªå€§ããã£ãããã«æããŸãã ãã®ãããªåœ¢ã§ 2017 幎äžé ãŸã§ã¯äŒç€Ÿå
¬åŒããã°ã§ã®æŽæ°ãããŠããŸããããéçºçµç¹ãæ¡å€§ããã«ã€ããçµç¹ãšããŠåºæ¥ãããšãå¢ããŠããŸãããããã«äŒŽãããããŸã§ã®ããã«ãéçºçµç¹ã®ååšã®ã¢ããŒã«ãããçµç¹ã®åãçµã¿ãã«å ããŠãçŽç²ã«æè¡çãªåŽé¢ããã£ãšæã¡åºããŠãããå»ç x ITããšããããŒãã«ã¡ãã¬ãŒã¯ã©ã®ããã«åããã£ãŠããããç¥ã£ãŠãããããšããæ©éãé«ãŸã£ãŠããŸããã 第 2 æ(2017/07 ~ 2022/03) ããããéã³ã§æ°ãã Medley Developer Blog ã 2017/07 æã«ç«ã¡äžããããšã«ãªããŸãããäŒç€Ÿå
¬åŒããã°ããå®å
šã«ç¬ç«ããããã¯ããã°ãšããããšã§ãç®è«èŠéãã«ãããŸã§ä»¥äžã«æè¡çãªæçš¿ãã§ããããã«ãªããŸãããç·šéæ¹åŒããã®æããçŸåšãŸã§ãšã³ãžãã¢ã»ãã¶ã€ããŒãäž»äœãšãªã£ãŠããŸãã æŽæ°é »åºŠãäžå®æã ã£ããã®ãæ 1~2 åãšå¢ãããã³ã³ã¹ã¿ã³ãã«ã¡ãã¬ãŒã®éçºã«é¢ãã話é¡ãåãæ±ãããã«ããŸãããéå¶ãããŠãã 5 幎ã®éã«ããã€ãã®èšäºã¯ããããããŸã§ã¯ãŠãªããã¯ããŒã¯ãªã©ã§ è©±é¡ ã«ãªãããšãããã第 1 æãããããã«çããã«èªãã§ããã ãããããªããã°ã«ãªããŸããã ãã®éã«ã¡ãã¬ãŒãæ§ã
ãªãšã³ãžãã¢ã»ãã¶ã€ããŒã€ãã³ãã«ã¹ãã³ãµãŒããããŠããã ããããããŠãããã°ãšåãããŠäžå®ã®ãã¬ãŒã³ã¹ãåŸãããšãã§ããŠããã®ã§ã¯ãªãããšæã£ãŠããŸããç¹ã«ãå»çãã«ã¹ã±ã¢æ¥çããšãã銎æã¿ãç¡ãæ¹ã«ã¯ããŒãã«ãé«ããšæãããããšãå€ãæ¥çã§ã®ãããã¯ãéçºã«ãäžè¬çãªã€ã³ã¿ãŒããããã¯ãããžãŒãé§äœ¿ããŠãããšããç¹ããè²ã
ãªåŽé¢ãããäŒãã§ããããã«ãªã£ãããšã¯å€§ãããšæããŠããŸãã çŸåš(2022/03 ~) ãããªããã°ã§ããããéèšãã 5 幎çµã¡ä»¥äžã®ãããªèª²é¡ãåºãŠããŸããã äŒç€ŸããŸã äžå Žåã«äœããããã¶ã€ã³ã ã£ããããçŸåšã®ã³ãŒãã¬ãŒããµã€ããªã©ã®ããŒã³ãšãºã¬ãåºãŠããŠãã äŒç€Ÿãçµç¹èŠæš¡ã倧ãããªããåžèã«ãªããã¡ãªå
éšã§åããŠããå人ã«ããã©ãŒã«ã¹ãåœãŠããããããªã³ã³ãã³ããæ¬²ãã æ¡çšçãªåŽé¢ãšããŠãã¡ãã¬ãŒã«èå³ãæã£ãæ¹ãžæäŸã§ããæ
å ±ããã©ãã©ã«ãªã£ãŠãã 以äžã®èª²é¡ã解決ããããã«ãããã°ã®ãªãã¥ãŒã¢ã«ãããããšã«ãªããŸããã ç¹ã«ä»å¹Žããå
šç€Ÿçãªæ¹éãšããŠãã¡ãã¬ãŒã®ãœããé¢ã§ã®è©±é¡ã«ãã©ãŒã«ã¹ããã³ã³ãã³ããäœã£ãŠãããšããããšã§ãæ¹ããŠå
¬åŒ note ã®æŽæ°ã«æ³šåããŠããããšãããããšã³ãžãã¢ã»ãã¶ã€ããŒããã°ããã®åããšé£åããå¿
èŠããããŸããã 以äžã®çç±ãããã³ã³ãã³ããšããŠã¯åŸæ¥éãã® ããã°èšäº ãæ§ã
ãªã¡ãã£ã¢ã§ã¡ã³ããŒãé²åºããŠãã ã€ã³ã¿ãã¥ãŒèšäº ãã€ãã³ããªã©ã§äœ¿ããã çºè¡šã¹ã©ã€ã ãå
šãŠèŠããããããªç·åçãªãµã€ãã«ããŠããããšãšãªããŸããã ã€ã³ã¿ãã¥ãŒã¯ãããŸã§ãã¡ã³ããŒãæ§ã
ãªã¡ãã£ã¢ã«åºãŠããããã¹ã©ã€ãã以åãã Speaker Deck ãæŽæ°ããŠããã®ã§ããããŸãšãŸã£ã圢ã§ã®æäŸãã§ããŠããŸããã§ããã ä»åã®ãªãã¥ãŒã¢ã«ã§ããããã®èŠçŽ ããŸãšããŠçããã«ãå±ãã§ããããã«ãªã£ãããããMedley Developer BlogããããMedley Developer Portalããšåç§°å€æŽãããŸããã ããããããã¡ãã¬ãŒã®éçºçµç¹ãããå€éšã®çããã«ç¥ã£ãŠãããããã«ãéå¶ãã§ããã°ãšèããŠããŸãã®ã§ããããããé¡ãããŸãã ãšã³ãžãã¢ã»ãã¶ã€ããŒããã°ãªãã¥ãŒã¢ã«ã®æè¡é¢ã«ã€ã㊠ããŠããããŸã§ãªãã¥ãŒã¢ã«ã®èæ¯ããäŒãããŸããããããããã¯ä»å䜿ã£ãæè¡é¢ã«ã€ããŠè»œãè§ŠããŠããããšæããŸãã äœ¿çšæè¡ã«ã€ã㊠æ§ããã°ã¯ãã¯ãŠãªããã°ãã§ã®éçšãããŠããŸããããªãã¥ãŒã¢ã«ã«ããã£ãŠäžèšã®èª²é¡ã解決ããããã«ã¯ãç¬èªã«ããã°ãéçºããã»ãããããšèããŸãããæ°ããã°ã¯ä»¥äžã®æè¡ã䜿ã£ãŠéçºããŸããã Gatsby Emotion TypeScript Netlify Gatsby ã«æ±ºããçç±ã¯å€§ããã¯ä»¥äžã§ããã æ¢ã«åŒç€Ÿå
ã§ Gatsby ã®å°å
¥å®çžŸãããããã瀟å
ã®ã¡ã³ããŒããããšãªã£ããè§Šãã ããã° + α ã®ãµã€ããäœãã®ã«ååãªæè»æ§ããã å
¬åŒãã³ãã¥ããã£ãã©ã°ã€ã³ãå
å®ããŠãããéçºãçååã§ãã Gatsby ã¯ç²Ÿåçã«ã¢ããããŒããè¡ãªãããŠãããæ©ããµã€ã¯ã«ã§é²åããã®ãé
åã® 1 ã€ã§ããã Gatsby 補ãµã€ããã©ã®ããã«å
¬éãããã¯ãæ©ãã ã®ã§ãããçµæçã«äºäŸãå€ããããããã€ã®ç°¡æããæ©èœã®è±å¯ããèã㊠Netlify ã«ããŸããã ã¯ãŠãªããã°ããã®èšäºç§»è¡ã«ã€ã㊠æåããæ§ããã°ã§ã®ã³ã³ãã³ãã¯æ°ããã°ã«ç§»è¡ããããšããã¹ãã ã£ãã®ã§ããŸãã¯ã©ã®ããã«ç§»è¡ãã§ããããšããããšãèæ
®ããããšããå§ããŸãããã¯ãŠãªããã°ã¯éåžžã®ãšã¯ã¹ããŒãã ãš Movable Type æ¹åŒã«ãªãã®ã§ããªããšã Markdown ã«å€æãããâŠãªã©ãšèããŠããŸããã ãããã blogsync ãšããã¯ãŠãªããã°ã® CLI ã¯ã©ã€ã¢ã³ããéããšããŒã«ã«ã« Markdown ãã¡ã€ã«ãšããŠããã°ãšã³ããªãåæããããšãå¯èœã ã£ãããã blogsync ã§å
šãŠã®æ§ããã°ã³ã³ãã³ããããŒã«ã«ã«åæ(ããŠã³ããŒã) ããŒã«ã«ã« Markdown ãã¡ã€ã«ãšããŠããŠã³ããŒãã§ããããã°ã³ã³ãã³ãã Gatsby è£œã®æ°ããã°ã«ã³ã㌠gatsby-source-filesystem ã§ã³ããŒãã Markdown ãã¡ã€ã«ãèªã¿èŸŒã¿ããã°ãšããŠè¡šç€º ãšããæé ã§æ¢åã®ããã°èšäºãå
šãŠç§»è¡ããããšãã§ããŸããã ãŸãããã¡ã€ã³ã«ã€ããŠã¯ç¬èªãã¡ã€ã³ããã®ãŸãŸæ°ããã°ã«ãç§»è¡ããããšãšãããããã¯ãŠãªããã°ãšåã URL 圢åŒã§ããã°ãèªã¿èŸŒããããã«ã«ãŒãã£ã³ã°ãããŸããã èŠåŽããéšå ä»åã®éçºã§èŠåŽããéšåããã€ãžã§ã¹ãã§æžããŠãããŸããèªåã®ããŒãºã«åãããŠèª¿ã¹ãŠã¿ãŠããç¹ã«æ·±ãéšåã«é¢ããŠãããŸãæ
å ±ãåºãŠããªããšãããã¿ãŒã³ãå€ãã£ãããã«æããŸãã ããŒãžã§ã³åºæã®æ
å ±ãããã©ã°ã€ã³ã®æ
å ±ãå°ãªãã£ã éçºåœå㯠Gatsby v4 ãåºãã°ããã ã£ãã®ã§ãäœãã«å°ã£ãŠæ€çŽ¢ããŠãå
¬åŒä»¥å€ã®æ
å ±ã¯ä»¥åã®ããŒãžã§ã³ã§äœ¿ããªãããšãå€ãã£ãã§ãã ãŸããã©ã°ã€ã³é¢ä¿ã®æ
å ±ã調ã¹ãå
容ã«ãã£ãŠã¯äžã
ç®çã®æ
å ±ãåºãŠããªãã£ããããŸããã gatsby-plugin-image åšãã§é¡èãªå°è±¡ã ã£ãã®ã§ãç»ååšãã®è¡šç€ºã«æ³£ããããããšããããŸããã ä»ã«ã Markdown 衚瀺㯠gatsby-plugin-mdx ã䜿çšããŠããŸãããåŸæ¥ã® gatsby-transformer-remark ãšæ
å ±ãæ··åšããŠããå°è±¡ããããŸããã®ã§æ··ä¹±ããããšãã ããŒãžããŒã·ã§ã³ã§ãã¹ããªãã©ã°ã€ã³ãèŠã€ãããªãã£ã å
¬åŒ ã¬ã€ããåèã«ããŒãžããŒã·ã§ã³ãèªåã§äœã£ãŠããã®ã§ããã GraphQL ããæã£ãŠããããŒã¿ã衚瀺ããã ãã§ã¯ããŸããŠãŒã¶ããªãã£ãè¯ããªãã£ãããããã©ã°ã€ã³ãªã©æ¢ããã®ã§ãããããšãã£ããã®ãèŠã€ãããªãã£ãã§ãã å
¬åŒã¬ã€ãåèã«äœããšå»¶ã
èšäºãå¢ãããããŒãžããŒã·ã§ã³ã®æ°ãå¢ããŠãã£ãŠããŸã埮åŠãªæãã§ããâŠãèªåã§å¶åŸ¡ãèããŸããããæçµçã«ã¯ mui/pagination ã³ã³ããŒãã³ããçµã¿åãããããšã§å¯Ÿå¿ããŸããã OGP ç»åèªåçæã«é¢ããŠæ
å ±ãå°ãªã OGP ç»åã¯èªåçæã«ããããšæããŸããããæ¡å€ããŒãºãç¡ãã®ãæ
å ±ãå°ãªãã£ãå°è±¡ã§ããæçµçã« ãã¡ã ã®ããã°ãçºèŠãã kentaro-m/catchy-image ã䜿ã£ãŠçæããããã«ããŸããã ããããããããããš æ©èœã®æ¡å
以å€ã ãšãä»ãŸã§ã¯ã§ããªãã£ã textlint ã§ã®æ ¡æ£ãªã©ãããŠãç·šéæã®è² è·è»œæžãªã©ããã£ãŠãããããšèããŠããŸãã ããã㫠以äžã Developer Portal ã®ãªãã¥ãŒã¢ã«ã«ã€ããŠæžãããŠããã ããŸããã åŒãç¶ããæ
å ±çºä¿¡ãªã©ãããŠããã¡ãã¬ãŒéçºçµç¹ã«ã€ããŠãçããã«ç¥ã£ãŠããã ããã°ãšæããŸãã æåŸã«ãªããŸãããå»çãã«ã¹ã±ã¢ã®ãããã¯ãéçºã«(ãã®ãããªããã°è£œäœã)é¢ãã£ãŠãããã!ãšããæ¹ã¯ãã²äžèšãããå¿åãåŸ
ã¡ããŠãããŸã! https://www.medley.jp/jobs/
ã¯ããã« çãããããã«ã¡ã¯ããšã³ãžãã¢ã»æè¡åºå ±ã®å¹³æšã§ãã 以åããã芧ã«ãªã£ãŠããã ããŠããæ¹ã«ã¯ãåããããšæããŸããã3/18 ã«ä»ã芧ããã ããŠãããšã³ãžãã¢ã»ãã¶ã€ããŒããã°ããDeveloper Portalããšããåç§°ã«å€æŽã㊠2017 å¹Žä»¥æ¥ 5 幎ã¶ãã«ãªãã¥ãŒã¢ã«ãããŸãããä»åã¯ãªãã¥ãŒã¢ã«ã«ã€ããŠãç®æããšãããšè¥å¹²ã®æè¡çãªåŽé¢ããäŒãã§ããã°ãšæããŸãã ããã°ãããæ°æ§æ¯èŒ æ§ æ° ãšã³ãžãã¢ã»ãã¶ã€ããŒããã°ãªãã¥ãŒã¢ã«ã®èæ¯ ãŸãã¯ã ãªããªãã¥ãŒã¢ã«ããã? ãšããèæ¯ã«ã€ããŠã§ããåŒç€Ÿã®ãšã³ãžãã¢ã»ãã¶ã€ããŒããã°ã®å€é·ãšå
±ã«ã話ããŠãããããšæããŸãã ãšã³ãžãã¢ã»ãã¶ã€ããŒããã°ã®å€é· 第 1 æ(2016/04 ~ 2017/07) Developer Blog 㯠2016/04 æã«äŒç€Ÿå
¬åŒããã°ã«ãšã³ãžãã¢åãã®èšäºãæ²èŒãå§ããããããããã°ããã¯ä»ã®äŒç€Ÿæ
å ±ãšãšãã«æ²èŒãããŠããŸãããèšäºå
容ã¯ãšã³ãžãã¢ãç»å£ããã€ãã³ãæ
å ±ããä»ãç¶ããŠãã TechLunch(å
šç€Ÿæšªæã®ãšã³ãžãã¢ã»ãã¶ã€ããŒåã瀟å
å匷äŒ) ã®çºè¡šã¬ããŒããªã©ãã¡ã€ã³ãšãªã£ãŠããŸããã ãã®é ã¯éçºçµç¹ã®äººæ°ããããŸã§å€ããªãã£ãã®ã§ãããã¡ãã¬ãŒã®éçºçµç¹ã瀟å
ã®æ§ã
ãªéšçœ²ã®é°å²æ°ãšå
±ã«ãäŒãããããšããç®çãã¡ã€ã³ã§ããããŸãã¯ãã¡ãã¬ãŒã®éçºçµç¹ãšããŠã®ãã¬ãŒã³ã¹ãé«ãããããã¯ããå
è£œã§æ¥ã
éçºãããŠããããšããå€éšã®çããã«ç¥ã£ãŠãããããšããç®çãäžçªå€§ããã£ãããã«æããŸãã ãã®ãããªåœ¢ã§ 2017 幎äžé ãŸã§ã¯äŒç€Ÿå
¬åŒããã°ã§ã®æŽæ°ãããŠããŸããããéçºçµç¹ãæ¡å€§ããã«ã€ããçµç¹ãšããŠåºæ¥ãããšãå¢ããŠããŸãããããã«äŒŽãããããŸã§ã®ããã«ãéçºçµç¹ã®ååšã®ã¢ããŒã«ãããçµç¹ã®åãçµã¿ãã«å ããŠãçŽç²ã«æè¡çãªåŽé¢ããã£ãšæã¡åºããŠãããå»ç x ITããšããããŒãã«ã¡ãã¬ãŒã¯ã©ã®ããã«åããã£ãŠããããç¥ã£ãŠãããããšããæ©éãé«ãŸã£ãŠããŸããã 第 2 æ(2017/07 ~ 2022/03) ããããéã³ã§æ°ãã Medley Developer Blog ã 2017/07 æã«ç«ã¡äžããããšã«ãªããŸãããäŒç€Ÿå
¬åŒããã°ããå®å
šã«ç¬ç«ããããã¯ããã°ãšããããšã§ãç®è«èŠéãã«ãããŸã§ä»¥äžã«æè¡çãªæçš¿ãã§ããããã«ãªããŸãããç·šéæ¹åŒããã®æããçŸåšãŸã§ãšã³ãžãã¢ã»ãã¶ã€ããŒãäž»äœãšãªã£ãŠããŸãã æŽæ°é »åºŠãäžå®æã ã£ããã®ãæ 1~2 åãšå¢ãããã³ã³ã¹ã¿ã³ãã«ã¡ãã¬ãŒã®éçºã«é¢ãã話é¡ãåãæ±ãããã«ããŸãããéå¶ãããŠãã 5 幎ã®éã«ããã€ãã®èšäºã¯ããããããŸã§ã¯ãŠãªããã¯ããŒã¯ãªã©ã§ è©±é¡ ã«ãªãããšãããã第 1 æãããããã«çããã«èªãã§ããã ãããããªããã°ã«ãªããŸããã ãã®éã«ã¡ãã¬ãŒãæ§ã
ãªãšã³ãžãã¢ã»ãã¶ã€ããŒã€ãã³ãã«ã¹ãã³ãµãŒããããŠããã ããããããŠãããã°ãšåãããŠäžå®ã®ãã¬ãŒã³ã¹ãåŸãããšãã§ããŠããã®ã§ã¯ãªãããšæã£ãŠããŸããç¹ã«ãå»çãã«ã¹ã±ã¢æ¥çããšãã銎æã¿ãç¡ãæ¹ã«ã¯ããŒãã«ãé«ããšæãããããšãå€ãæ¥çã§ã®ãããã¯ãéçºã«ãäžè¬çãªã€ã³ã¿ãŒããããã¯ãããžãŒãé§äœ¿ããŠãããšããç¹ããè²ã
ãªåŽé¢ãããäŒãã§ããããã«ãªã£ãããšã¯å€§ãããšæããŠããŸãã çŸåš(2022/03 ~) ãããªããã°ã§ããããéèšãã 5 幎çµã¡ä»¥äžã®ãããªèª²é¡ãåºãŠããŸããã äŒç€ŸããŸã äžå Žåã«äœããããã¶ã€ã³ã ã£ããããçŸåšã®ã³ãŒãã¬ãŒããµã€ããªã©ã®ããŒã³ãšãºã¬ãåºãŠããŠãã äŒç€Ÿãçµç¹èŠæš¡ã倧ãããªããåžèã«ãªããã¡ãªå
éšã§åããŠããå人ã«ããã©ãŒã«ã¹ãåœãŠããããããªã³ã³ãã³ããæ¬²ãã æ¡çšçãªåŽé¢ãšããŠãã¡ãã¬ãŒã«èå³ãæã£ãæ¹ãžæäŸã§ããæ
å ±ããã©ãã©ã«ãªã£ãŠãã 以äžã®èª²é¡ã解決ããããã«ãããã°ã®ãªãã¥ãŒã¢ã«ãããããšã«ãªããŸããã ç¹ã«ä»å¹Žããå
šç€Ÿçãªæ¹éãšããŠãã¡ãã¬ãŒã®ãœããé¢ã§ã®è©±é¡ã«ãã©ãŒã«ã¹ããã³ã³ãã³ããäœã£ãŠãããšããããšã§ãæ¹ããŠå
¬åŒ note ã®æŽæ°ã«æ³šåããŠããããšãããããšã³ãžãã¢ã»ãã¶ã€ããŒããã°ããã®åããšé£åããå¿
èŠããããŸããã 以äžã®çç±ãããã³ã³ãã³ããšããŠã¯åŸæ¥éãã® ããã°èšäº ãæ§ã
ãªã¡ãã£ã¢ã§ã¡ã³ããŒãé²åºããŠãã ã€ã³ã¿ãã¥ãŒèšäº ãã€ãã³ããªã©ã§äœ¿ããã çºè¡šã¹ã©ã€ã ãå
šãŠèŠããããããªç·åçãªãµã€ãã«ããŠããããšãšãªããŸããã ã€ã³ã¿ãã¥ãŒã¯ãããŸã§ãã¡ã³ããŒãæ§ã
ãªã¡ãã£ã¢ã«åºãŠããããã¹ã©ã€ãã以åãã Speaker Deck ãæŽæ°ããŠããã®ã§ããããŸãšãŸã£ã圢ã§ã®æäŸãã§ããŠããŸããã§ããã ä»åã®ãªãã¥ãŒã¢ã«ã§ããããã®èŠçŽ ããŸãšããŠçããã«ãå±ãã§ããããã«ãªã£ãããããMedley Developer BlogããããMedley Developer Portalããšåç§°å€æŽãããŸããã ããããããã¡ãã¬ãŒã®éçºçµç¹ãããå€éšã®çããã«ç¥ã£ãŠãããããã«ãéå¶ãã§ããã°ãšèããŠããŸãã®ã§ããããããé¡ãããŸãã ãšã³ãžãã¢ã»ãã¶ã€ããŒããã°ãªãã¥ãŒã¢ã«ã®æè¡é¢ã«ã€ã㊠ããŠããããŸã§ãªãã¥ãŒã¢ã«ã®èæ¯ããäŒãããŸããããããããã¯ä»å䜿ã£ãæè¡é¢ã«ã€ããŠè»œãè§ŠããŠããããšæããŸãã äœ¿çšæè¡ã«ã€ã㊠æ§ããã°ã¯ãã¯ãŠãªããã°ãã§ã®éçšãããŠããŸããããªãã¥ãŒã¢ã«ã«ããã£ãŠäžèšã®èª²é¡ã解決ããããã«ã¯ãç¬èªã«ããã°ãéçºããã»ãããããšèããŸãããæ°ããã°ã¯ä»¥äžã®æè¡ã䜿ã£ãŠéçºããŸããã Gatsby Emotion TypeScript Netlify Gatsby ã«æ±ºããçç±ã¯å€§ããã¯ä»¥äžã§ããã æ¢ã«åŒç€Ÿå
ã§ Gatsby ã®å°å
¥å®çžŸãããããã瀟å
ã®ã¡ã³ããŒããããšãªã£ããè§Šãã ããã° + α ã®ãµã€ããäœãã®ã«ååãªæè»æ§ããã å
¬åŒãã³ãã¥ããã£ãã©ã°ã€ã³ãå
å®ããŠãããéçºãçååã§ãã Gatsby ã¯ç²Ÿåçã«ã¢ããããŒããè¡ãªãããŠãããæ©ããµã€ã¯ã«ã§é²åããã®ãé
åã® 1 ã€ã§ããã Gatsby 補ãµã€ããã©ã®ããã«å
¬éãããã¯ãæ©ãã ã®ã§ãããçµæçã«äºäŸãå€ããããããã€ã®ç°¡æããæ©èœã®è±å¯ããèã㊠Netlify ã«ããŸããã ã¯ãŠãªããã°ããã®èšäºç§»è¡ã«ã€ã㊠æåããæ§ããã°ã§ã®ã³ã³ãã³ãã¯æ°ããã°ã«ç§»è¡ããããšããã¹ãã ã£ãã®ã§ããŸãã¯ã©ã®ããã«ç§»è¡ãã§ããããšããããšãèæ
®ããããšããå§ããŸãããã¯ãŠãªããã°ã¯éåžžã®ãšã¯ã¹ããŒãã ãš Movable Type æ¹åŒã«ãªãã®ã§ããªããšã Markdown ã«å€æãããâŠãªã©ãšèããŠããŸããã ãããã blogsync ãšããã¯ãŠãªããã°ã® CLI ã¯ã©ã€ã¢ã³ããéããšããŒã«ã«ã« Markdown ãã¡ã€ã«ãšããŠããã°ãšã³ããªãåæããããšãå¯èœã ã£ãããã blogsync ã§å
šãŠã®æ§ããã°ã³ã³ãã³ããããŒã«ã«ã«åæ(ããŠã³ããŒã) ããŒã«ã«ã« Markdown ãã¡ã€ã«ãšããŠããŠã³ããŒãã§ããããã°ã³ã³ãã³ãã Gatsby è£œã®æ°ããã°ã«ã³ã㌠gatsby-source-filesystem ã§ã³ããŒãã Markdown ãã¡ã€ã«ãèªã¿èŸŒã¿ããã°ãšããŠè¡šç€º ãšããæé ã§æ¢åã®ããã°èšäºãå
šãŠç§»è¡ããããšãã§ããŸããã ãŸãããã¡ã€ã³ã«ã€ããŠã¯ç¬èªãã¡ã€ã³ããã®ãŸãŸæ°ããã°ã«ãç§»è¡ããããšãšãããããã¯ãŠãªããã°ãšåã URL 圢åŒã§ããã°ãèªã¿èŸŒããããã«ã«ãŒãã£ã³ã°ãããŸããã èŠåŽããéšå ä»åã®éçºã§èŠåŽããéšåããã€ãžã§ã¹ãã§æžããŠãããŸããèªåã®ããŒãºã«åãããŠèª¿ã¹ãŠã¿ãŠããç¹ã«æ·±ãéšåã«é¢ããŠãããŸãæ
å ±ãåºãŠããªããšãããã¿ãŒã³ãå€ãã£ãããã«æããŸãã ããŒãžã§ã³åºæã®æ
å ±ãããã©ã°ã€ã³ã®æ
å ±ãå°ãªãã£ã éçºåœå㯠Gatsby v4 ãåºãã°ããã ã£ãã®ã§ãäœãã«å°ã£ãŠæ€çŽ¢ããŠãå
¬åŒä»¥å€ã®æ
å ±ã¯ä»¥åã®ããŒãžã§ã³ã§äœ¿ããªãããšãå€ãã£ãã§ãã ãŸããã©ã°ã€ã³é¢ä¿ã®æ
å ±ã調ã¹ãå
容ã«ãã£ãŠã¯äžã
ç®çã®æ
å ±ãåºãŠããªãã£ããããŸããã gatsby-plugin-image åšãã§é¡èãªå°è±¡ã ã£ãã®ã§ãç»ååšãã®è¡šç€ºã«æ³£ããããããšããããŸããã ä»ã«ã Markdown 衚瀺㯠gatsby-plugin-mdx ã䜿çšããŠããŸãããåŸæ¥ã® gatsby-transformer-remark ãšæ
å ±ãæ··åšããŠããå°è±¡ããããŸããã®ã§æ··ä¹±ããããšãã ããŒãžããŒã·ã§ã³ã§ãã¹ããªãã©ã°ã€ã³ãèŠã€ãããªãã£ã å
¬åŒ ã¬ã€ããåèã«ããŒãžããŒã·ã§ã³ãèªåã§äœã£ãŠããã®ã§ããã GraphQL ããæã£ãŠããããŒã¿ã衚瀺ããã ãã§ã¯ããŸããŠãŒã¶ããªãã£ãè¯ããªãã£ãããããã©ã°ã€ã³ãªã©æ¢ããã®ã§ãããããšãã£ããã®ãèŠã€ãããªãã£ãã§ãã å
¬åŒã¬ã€ãåèã«äœããšå»¶ã
èšäºãå¢ãããããŒãžããŒã·ã§ã³ã®æ°ãå¢ããŠãã£ãŠããŸã埮åŠãªæãã§ããâŠãèªåã§å¶åŸ¡ãèããŸããããæçµçã«ã¯ mui/pagination ã³ã³ããŒãã³ããçµã¿åãããããšã§å¯Ÿå¿ããŸããã OGP ç»åèªåçæã«é¢ããŠæ
å ±ãå°ãªã OGP ç»åã¯èªåçæã«ããããšæããŸããããæ¡å€ããŒãºãç¡ãã®ãæ
å ±ãå°ãªãã£ãå°è±¡ã§ããæçµçã« ãã¡ã ã®ããã°ãçºèŠãã kentaro-m/catchy-image ã䜿ã£ãŠçæããããã«ããŸããã ããããããããããš æ©èœã®æ¡å
以å€ã ãšãä»ãŸã§ã¯ã§ããªãã£ã textlint ã§ã®æ ¡æ£ãªã©ãããŠãç·šéæã®è² è·è»œæžãªã©ããã£ãŠãããããšèããŠããŸãã ããã㫠以äžã Developer Portal ã®ãªãã¥ãŒã¢ã«ã«ã€ããŠæžãããŠããã ããŸããã åŒãç¶ããæ
å ±çºä¿¡ãªã©ãããŠããã¡ãã¬ãŒéçºçµç¹ã«ã€ããŠãçããã«ç¥ã£ãŠããã ããã°ãšæããŸãã æåŸã«ãªããŸãããå»çãã«ã¹ã±ã¢ã®ãããã¯ãéçºã«(ãã®ãããªããã°è£œäœã)é¢ãã£ãŠãããã!ãšããæ¹ã¯ãã²äžèšãããå¿åãåŸ
ã¡ããŠãããŸã! åéã®äžèЧ | æ ªåŒäŒç€Ÿã¡ãã¬ãŒ ã¡ãã¬ãŒã®æ¡çšæ
å ±ã¯ãã¡ãããã確èªãã ããã www.medley.jp
ã¯ããã« çãããããã«ã¡ã¯ããšã³ãžãã¢ã»æè¡åºå ±ã®å¹³æšã§ãã 以åããã芧ã«ãªã£ãŠããã ããŠããæ¹ã«ã¯ãåããããšæããŸããã3/18 ã«ä»ã芧ããã ããŠãããšã³ãžãã¢ã»ãã¶ã€ããŒããã°ããDeveloper Portalããšããåç§°ã«å€æŽã㊠2017 å¹Žä»¥æ¥ 5 幎ã¶ãã«ãªãã¥ãŒã¢ã«ãããŸãããä»åã¯ãªãã¥ãŒã¢ã«ã«ã€ããŠãç®æããšãããšè¥å¹²ã®æè¡çãªåŽé¢ããäŒãã§ããã°ãšæããŸãã ããã°ãããæ°æ§æ¯èŒ æ§ æ° ãšã³ãžãã¢ã»ãã¶ã€ããŒããã°ãªãã¥ãŒã¢ã«ã®èæ¯ ãŸãã¯ã ãªããªãã¥ãŒã¢ã«ããã? ãšããèæ¯ã«ã€ããŠã§ããåŒç€Ÿã®ãšã³ãžãã¢ã»ãã¶ã€ããŒããã°ã®å€é·ãšå
±ã«ã話ããŠãããããšæããŸãã ãšã³ãžãã¢ã»ãã¶ã€ããŒããã°ã®å€é· 第 1 æ(2016/04 ~ 2017/07) Developer Blog 㯠2016/04 æã«äŒç€Ÿå
¬åŒããã°ã«ãšã³ãžãã¢åãã®èšäºãæ²èŒãå§ããããããããã°ããã¯ä»ã®äŒç€Ÿæ
å ±ãšãšãã«æ²èŒãããŠããŸãããèšäºå
容ã¯ãšã³ãžãã¢ãç»å£ããã€ãã³ãæ
å ±ããä»ãç¶ããŠãã TechLunch(å
šç€Ÿæšªæã®ãšã³ãžãã¢ã»ãã¶ã€ããŒåã瀟å
å匷äŒ) ã®çºè¡šã¬ããŒããªã©ãã¡ã€ã³ãšãªã£ãŠããŸããã ãã®é ã¯éçºçµç¹ã®äººæ°ããããŸã§å€ããªãã£ãã®ã§ãããã¡ãã¬ãŒã®éçºçµç¹ã瀟å
ã®æ§ã
ãªéšçœ²ã®é°å²æ°ãšå
±ã«ãäŒãããããšããç®çãã¡ã€ã³ã§ããããŸãã¯ãã¡ãã¬ãŒã®éçºçµç¹ãšããŠã®ãã¬ãŒã³ã¹ãé«ãããããã¯ããå
è£œã§æ¥ã
éçºãããŠããããšããå€éšã®çããã«ç¥ã£ãŠãããããšããç®çãäžçªå€§ããã£ãããã«æããŸãã ãã®ãããªåœ¢ã§ 2017 幎äžé ãŸã§ã¯äŒç€Ÿå
¬åŒããã°ã§ã®æŽæ°ãããŠããŸããããéçºçµç¹ãæ¡å€§ããã«ã€ããçµç¹ãšããŠåºæ¥ãããšãå¢ããŠããŸãããããã«äŒŽãããããŸã§ã®ããã«ãéçºçµç¹ã®ååšã®ã¢ããŒã«ãããçµç¹ã®åãçµã¿ãã«å ããŠãçŽç²ã«æè¡çãªåŽé¢ããã£ãšæã¡åºããŠãããå»ç x ITããšããããŒãã«ã¡ãã¬ãŒã¯ã©ã®ããã«åããã£ãŠããããç¥ã£ãŠãããããšããæ©éãé«ãŸã£ãŠããŸããã 第 2 æ(2017/07 ~ 2022/03) ããããéã³ã§æ°ãã Medley Developer Blog ã 2017/07 æã«ç«ã¡äžããããšã«ãªããŸãããäŒç€Ÿå
¬åŒããã°ããå®å
šã«ç¬ç«ããããã¯ããã°ãšããããšã§ãç®è«èŠéãã«ãããŸã§ä»¥äžã«æè¡çãªæçš¿ãã§ããããã«ãªããŸãããç·šéæ¹åŒããã®æããçŸåšãŸã§ãšã³ãžãã¢ã»ãã¶ã€ããŒãäž»äœãšãªã£ãŠããŸãã æŽæ°é »åºŠãäžå®æã ã£ããã®ãæ 1~2 åãšå¢ãããã³ã³ã¹ã¿ã³ãã«ã¡ãã¬ãŒã®éçºã«é¢ãã話é¡ãåãæ±ãããã«ããŸãããéå¶ãããŠãã 5 幎ã®éã«ããã€ãã®èšäºã¯ããããããŸã§ã¯ãŠãªããã¯ããŒã¯ãªã©ã§ è©±é¡ ã«ãªãããšãããã第 1 æãããããã«çããã«èªãã§ããã ãããããªããã°ã«ãªããŸããã ãã®éã«ã¡ãã¬ãŒãæ§ã
ãªãšã³ãžãã¢ã»ãã¶ã€ããŒã€ãã³ãã«ã¹ãã³ãµãŒããããŠããã ããããããŠãããã°ãšåãããŠäžå®ã®ãã¬ãŒã³ã¹ãåŸãããšãã§ããŠããã®ã§ã¯ãªãããšæã£ãŠããŸããç¹ã«ãå»çãã«ã¹ã±ã¢æ¥çããšãã銎æã¿ãç¡ãæ¹ã«ã¯ããŒãã«ãé«ããšæãããããšãå€ãæ¥çã§ã®ãããã¯ãéçºã«ãäžè¬çãªã€ã³ã¿ãŒããããã¯ãããžãŒãé§äœ¿ããŠãããšããç¹ããè²ã
ãªåŽé¢ãããäŒãã§ããããã«ãªã£ãããšã¯å€§ãããšæããŠããŸãã çŸåš(2022/03 ~) ãããªããã°ã§ããããéèšãã 5 幎çµã¡ä»¥äžã®ãããªèª²é¡ãåºãŠããŸããã äŒç€ŸããŸã äžå Žåã«äœããããã¶ã€ã³ã ã£ããããçŸåšã®ã³ãŒãã¬ãŒããµã€ããªã©ã®ããŒã³ãšãºã¬ãåºãŠããŠãã äŒç€Ÿãçµç¹èŠæš¡ã倧ãããªããåžèã«ãªããã¡ãªå
éšã§åããŠããå人ã«ããã©ãŒã«ã¹ãåœãŠããããããªã³ã³ãã³ããæ¬²ãã æ¡çšçãªåŽé¢ãšããŠãã¡ãã¬ãŒã«èå³ãæã£ãæ¹ãžæäŸã§ããæ
å ±ããã©ãã©ã«ãªã£ãŠãã 以äžã®èª²é¡ã解決ããããã«ãããã°ã®ãªãã¥ãŒã¢ã«ãããããšã«ãªããŸããã ç¹ã«ä»å¹Žããå
šç€Ÿçãªæ¹éãšããŠãã¡ãã¬ãŒã®ãœããé¢ã§ã®è©±é¡ã«ãã©ãŒã«ã¹ããã³ã³ãã³ããäœã£ãŠãããšããããšã§ãæ¹ããŠå
¬åŒ note ã®æŽæ°ã«æ³šåããŠããããšãããããšã³ãžãã¢ã»ãã¶ã€ããŒããã°ããã®åããšé£åããå¿
èŠããããŸããã 以äžã®çç±ãããã³ã³ãã³ããšããŠã¯åŸæ¥éãã® ããã°èšäº ãæ§ã
ãªã¡ãã£ã¢ã§ã¡ã³ããŒãé²åºããŠãã ã€ã³ã¿ãã¥ãŒèšäº ãã€ãã³ããªã©ã§äœ¿ããã çºè¡šã¹ã©ã€ã ãå
šãŠèŠããããããªç·åçãªãµã€ãã«ããŠããããšãšãªããŸããã ã€ã³ã¿ãã¥ãŒã¯ãããŸã§ãã¡ã³ããŒãæ§ã
ãªã¡ãã£ã¢ã«åºãŠããããã¹ã©ã€ãã以åãã Speaker Deck ãæŽæ°ããŠããã®ã§ããããŸãšãŸã£ã圢ã§ã®æäŸãã§ããŠããŸããã§ããã ä»åã®ãªãã¥ãŒã¢ã«ã§ããããã®èŠçŽ ããŸãšããŠçããã«ãå±ãã§ããããã«ãªã£ãããããMedley Developer BlogããããMedley Developer Portalããšåç§°å€æŽãããŸããã ããããããã¡ãã¬ãŒã®éçºçµç¹ãããå€éšã®çããã«ç¥ã£ãŠãããããã«ãéå¶ãã§ããã°ãšèããŠããŸãã®ã§ããããããé¡ãããŸãã ãšã³ãžãã¢ã»ãã¶ã€ããŒããã°ãªãã¥ãŒã¢ã«ã®æè¡é¢ã«ã€ã㊠ããŠããããŸã§ãªãã¥ãŒã¢ã«ã®èæ¯ããäŒãããŸããããããããã¯ä»å䜿ã£ãæè¡é¢ã«ã€ããŠè»œãè§ŠããŠããããšæããŸãã äœ¿çšæè¡ã«ã€ã㊠æ§ããã°ã¯ãã¯ãŠãªããã°ãã§ã®éçšãããŠããŸããããªãã¥ãŒã¢ã«ã«ããã£ãŠäžèšã®èª²é¡ã解決ããããã«ã¯ãç¬èªã«ããã°ãéçºããã»ãããããšèããŸãããæ°ããã°ã¯ä»¥äžã®æè¡ã䜿ã£ãŠéçºããŸããã Gatsby Emotion TypeScript Netlify Gatsby ã«æ±ºããçç±ã¯å€§ããã¯ä»¥äžã§ããã æ¢ã«åŒç€Ÿå
ã§ Gatsby ã®å°å
¥å®çžŸãããããã瀟å
ã®ã¡ã³ããŒããããšãªã£ããè§Šãã ããã° + α ã®ãµã€ããäœãã®ã«ååãªæè»æ§ããã å
¬åŒãã³ãã¥ããã£ãã©ã°ã€ã³ãå
å®ããŠãããéçºãçååã§ãã Gatsby ã¯ç²Ÿåçã«ã¢ããããŒããè¡ãªãããŠãããæ©ããµã€ã¯ã«ã§é²åããã®ãé
åã® 1 ã€ã§ããã Gatsby 補ãµã€ããã©ã®ããã«å
¬éãããã¯ãæ©ãã ã®ã§ãããçµæçã«äºäŸãå€ããããããã€ã®ç°¡æããæ©èœã®è±å¯ããèã㊠Netlify ã«ããŸããã ã¯ãŠãªããã°ããã®èšäºç§»è¡ã«ã€ã㊠æåããæ§ããã°ã§ã®ã³ã³ãã³ãã¯æ°ããã°ã«ç§»è¡ããããšããã¹ãã ã£ãã®ã§ããŸãã¯ã©ã®ããã«ç§»è¡ãã§ããããšããããšãèæ
®ããããšããå§ããŸãããã¯ãŠãªããã°ã¯éåžžã®ãšã¯ã¹ããŒãã ãš Movable Type æ¹åŒã«ãªãã®ã§ããªããšã Markdown ã«å€æãããâŠãªã©ãšèããŠããŸããã ãããã blogsync ãšããã¯ãŠãªããã°ã® CLI ã¯ã©ã€ã¢ã³ããéããšããŒã«ã«ã« Markdown ãã¡ã€ã«ãšããŠããã°ãšã³ããªãåæããããšãå¯èœã ã£ãããã blogsync ã§å
šãŠã®æ§ããã°ã³ã³ãã³ããããŒã«ã«ã«åæ(ããŠã³ããŒã) ããŒã«ã«ã« Markdown ãã¡ã€ã«ãšããŠããŠã³ããŒãã§ããããã°ã³ã³ãã³ãã Gatsby è£œã®æ°ããã°ã«ã³ã㌠gatsby-source-filesystem ã§ã³ããŒãã Markdown ãã¡ã€ã«ãèªã¿èŸŒã¿ããã°ãšããŠè¡šç€º ãšããæé ã§æ¢åã®ããã°èšäºãå
šãŠç§»è¡ããããšãã§ããŸããã ãŸãããã¡ã€ã³ã«ã€ããŠã¯ç¬èªãã¡ã€ã³ããã®ãŸãŸæ°ããã°ã«ãç§»è¡ããããšãšãããããã¯ãŠãªããã°ãšåã URL 圢åŒã§ããã°ãèªã¿èŸŒããããã«ã«ãŒãã£ã³ã°ãããŸããã èŠåŽããéšå ä»åã®éçºã§èŠåŽããéšåããã€ãžã§ã¹ãã§æžããŠãããŸããèªåã®ããŒãºã«åãããŠèª¿ã¹ãŠã¿ãŠããç¹ã«æ·±ãéšåã«é¢ããŠãããŸãæ
å ±ãåºãŠããªããšãããã¿ãŒã³ãå€ãã£ãããã«æããŸãã ããŒãžã§ã³åºæã®æ
å ±ãããã©ã°ã€ã³ã®æ
å ±ãå°ãªãã£ã éçºåœå㯠Gatsby v4 ãåºãã°ããã ã£ãã®ã§ãäœãã«å°ã£ãŠæ€çŽ¢ããŠãå
¬åŒä»¥å€ã®æ
å ±ã¯ä»¥åã®ããŒãžã§ã³ã§äœ¿ããªãããšãå€ãã£ãã§ãã ãŸããã©ã°ã€ã³é¢ä¿ã®æ
å ±ã調ã¹ãå
容ã«ãã£ãŠã¯äžã
ç®çã®æ
å ±ãåºãŠããªãã£ããããŸããã gatsby-plugin-image åšãã§é¡èãªå°è±¡ã ã£ãã®ã§ãç»ååšãã®è¡šç€ºã«æ³£ããããããšããããŸããã ä»ã«ã Markdown 衚瀺㯠gatsby-plugin-mdx ã䜿çšããŠããŸãããåŸæ¥ã® gatsby-transformer-remark ãšæ
å ±ãæ··åšããŠããå°è±¡ããããŸããã®ã§æ··ä¹±ããããšãã ããŒãžããŒã·ã§ã³ã§ãã¹ããªãã©ã°ã€ã³ãèŠã€ãããªãã£ã å
¬åŒ ã¬ã€ããåèã«ããŒãžããŒã·ã§ã³ãèªåã§äœã£ãŠããã®ã§ããã GraphQL ããæã£ãŠããããŒã¿ã衚瀺ããã ãã§ã¯ããŸããŠãŒã¶ããªãã£ãè¯ããªãã£ãããããã©ã°ã€ã³ãªã©æ¢ããã®ã§ãããããšãã£ããã®ãèŠã€ãããªãã£ãã§ãã å
¬åŒã¬ã€ãåèã«äœããšå»¶ã
èšäºãå¢ãããããŒãžããŒã·ã§ã³ã®æ°ãå¢ããŠãã£ãŠããŸã埮åŠãªæãã§ããâŠãèªåã§å¶åŸ¡ãèããŸããããæçµçã«ã¯ mui/pagination ã³ã³ããŒãã³ããçµã¿åãããããšã§å¯Ÿå¿ããŸããã OGP ç»åèªåçæã«é¢ããŠæ
å ±ãå°ãªã OGP ç»åã¯èªåçæã«ããããšæããŸããããæ¡å€ããŒãºãç¡ãã®ãæ
å ±ãå°ãªãã£ãå°è±¡ã§ããæçµçã« ãã¡ã ã®ããã°ãçºèŠãã kentaro-m/catchy-image ã䜿ã£ãŠçæããããã«ããŸããã ããããããããããš æ©èœã®æ¡å
以å€ã ãšãä»ãŸã§ã¯ã§ããªãã£ã textlint ã§ã®æ ¡æ£ãªã©ãããŠãç·šéæã®è² è·è»œæžãªã©ããã£ãŠãããããšèããŠããŸãã ããã㫠以äžã Developer Portal ã®ãªãã¥ãŒã¢ã«ã«ã€ããŠæžãããŠããã ããŸããã åŒãç¶ããæ
å ±çºä¿¡ãªã©ãããŠããã¡ãã¬ãŒéçºçµç¹ã«ã€ããŠãçããã«ç¥ã£ãŠããã ããã°ãšæããŸãã æåŸã«ãªããŸãããå»çãã«ã¹ã±ã¢ã®ãããã¯ãéçºã«(ãã®ãããªããã°è£œäœã)é¢ãã£ãŠãããã!ãšããæ¹ã¯ãã²äžèšãããå¿åãåŸ
ã¡ããŠãããŸã! åéã®äžèЧ | æ ªåŒäŒç€Ÿã¡ãã¬ãŒ ã¡ãã¬ãŒã®æ¡çšæ
å ±ã¯ãã¡ãããã確èªãã ããã www.medley.jp
ã¯ããã« çãããããã«ã¡ã¯ããšã³ãžãã¢ã»æè¡åºå ±ã®å¹³æšã§ãã 以åããã芧ã«ãªã£ãŠããã ããŠããæ¹ã«ã¯ãåããããšæããŸããã3/18 ã«ä»ã芧ããã ããŠãããšã³ãžãã¢ã»ãã¶ã€ããŒããã°ããDeveloper Portalããšããåç§°ã«å€æŽã㊠2017 å¹Žä»¥æ¥ 5 幎ã¶ãã«ãªãã¥ãŒã¢ã«ãããŸãããä»åã¯ãªãã¥ãŒã¢ã«ã«ã€ããŠãç®æããšãããšè¥å¹²ã®æè¡çãªåŽé¢ããäŒãã§ããã°ãšæããŸãã ããã°ãããæ°æ§æ¯èŒ æ§ æ° ãšã³ãžãã¢ã»ãã¶ã€ããŒããã°ãªãã¥ãŒã¢ã«ã®èæ¯ ãŸãã¯ã ãªããªãã¥ãŒã¢ã«ããã? ãšããèæ¯ã«ã€ããŠã§ããåŒç€Ÿã®ãšã³ãžãã¢ã»ãã¶ã€ããŒããã°ã®å€é·ãšå
±ã«ã話ããŠãããããšæããŸãã ãšã³ãžãã¢ã»ãã¶ã€ããŒããã°ã®å€é· 第 1 æ(2016/04 ~ 2017/07) Developer Blog 㯠2016/04 æã«äŒç€Ÿå
¬åŒããã°ã«ãšã³ãžãã¢åãã®èšäºãæ²èŒãå§ããããããããã°ããã¯ä»ã®äŒç€Ÿæ
å ±ãšãšãã«æ²èŒãããŠããŸãããèšäºå
容ã¯ãšã³ãžãã¢ãç»å£ããã€ãã³ãæ
å ±ããä»ãç¶ããŠãã TechLunch(å
šç€Ÿæšªæã®ãšã³ãžãã¢ã»ãã¶ã€ããŒåã瀟å
å匷äŒ) ã®çºè¡šã¬ããŒããªã©ãã¡ã€ã³ãšãªã£ãŠããŸããã ãã®é ã¯éçºçµç¹ã®äººæ°ããããŸã§å€ããªãã£ãã®ã§ãããã¡ãã¬ãŒã®éçºçµç¹ã瀟å
ã®æ§ã
ãªéšçœ²ã®é°å²æ°ãšå
±ã«ãäŒãããããšããç®çãã¡ã€ã³ã§ããããŸãã¯ãã¡ãã¬ãŒã®éçºçµç¹ãšããŠã®ãã¬ãŒã³ã¹ãé«ãããããã¯ããå
è£œã§æ¥ã
éçºãããŠããããšããå€éšã®çããã«ç¥ã£ãŠãããããšããç®çãäžçªå€§ããã£ãããã«æããŸãã ãã®ãããªåœ¢ã§ 2017 幎äžé ãŸã§ã¯äŒç€Ÿå
¬åŒããã°ã§ã®æŽæ°ãããŠããŸããããéçºçµç¹ãæ¡å€§ããã«ã€ããçµç¹ãšããŠåºæ¥ãããšãå¢ããŠããŸãããããã«äŒŽãããããŸã§ã®ããã«ãéçºçµç¹ã®ååšã®ã¢ããŒã«ãããçµç¹ã®åãçµã¿ãã«å ããŠãçŽç²ã«æè¡çãªåŽé¢ããã£ãšæã¡åºããŠãããå»ç x ITããšããããŒãã«ã¡ãã¬ãŒã¯ã©ã®ããã«åããã£ãŠããããç¥ã£ãŠãããããšããæ©éãé«ãŸã£ãŠããŸããã 第 2 æ(2017/07 ~ 2022/03) ããããéã³ã§æ°ãã Medley Developer Blog ã 2017/07 æã«ç«ã¡äžããããšã«ãªããŸãããäŒç€Ÿå
¬åŒããã°ããå®å
šã«ç¬ç«ããããã¯ããã°ãšããããšã§ãç®è«èŠéãã«ãããŸã§ä»¥äžã«æè¡çãªæçš¿ãã§ããããã«ãªããŸãããç·šéæ¹åŒããã®æããçŸåšãŸã§ãšã³ãžãã¢ã»ãã¶ã€ããŒãäž»äœãšãªã£ãŠããŸãã æŽæ°é »åºŠãäžå®æã ã£ããã®ãæ 1~2 åãšå¢ãããã³ã³ã¹ã¿ã³ãã«ã¡ãã¬ãŒã®éçºã«é¢ãã話é¡ãåãæ±ãããã«ããŸãããéå¶ãããŠãã 5 幎ã®éã«ããã€ãã®èšäºã¯ããããããŸã§ã¯ãŠãªããã¯ããŒã¯ãªã©ã§ è©±é¡ ã«ãªãããšãããã第 1 æãããããã«çããã«èªãã§ããã ãããããªããã°ã«ãªããŸããã ãã®éã«ã¡ãã¬ãŒãæ§ã
ãªãšã³ãžãã¢ã»ãã¶ã€ããŒã€ãã³ãã«ã¹ãã³ãµãŒããããŠããã ããããããŠãããã°ãšåãããŠäžå®ã®ãã¬ãŒã³ã¹ãåŸãããšãã§ããŠããã®ã§ã¯ãªãããšæã£ãŠããŸããç¹ã«ãå»çãã«ã¹ã±ã¢æ¥çããšãã銎æã¿ãç¡ãæ¹ã«ã¯ããŒãã«ãé«ããšæãããããšãå€ãæ¥çã§ã®ãããã¯ãéçºã«ãäžè¬çãªã€ã³ã¿ãŒããããã¯ãããžãŒãé§äœ¿ããŠãããšããç¹ããè²ã
ãªåŽé¢ãããäŒãã§ããããã«ãªã£ãããšã¯å€§ãããšæããŠããŸãã çŸåš(2022/03 ~) ãããªããã°ã§ããããéèšãã 5 幎çµã¡ä»¥äžã®ãããªèª²é¡ãåºãŠããŸããã äŒç€ŸããŸã äžå Žåã«äœããããã¶ã€ã³ã ã£ããããçŸåšã®ã³ãŒãã¬ãŒããµã€ããªã©ã®ããŒã³ãšãºã¬ãåºãŠããŠãã äŒç€Ÿãçµç¹èŠæš¡ã倧ãããªããåžèã«ãªããã¡ãªå
éšã§åããŠããå人ã«ããã©ãŒã«ã¹ãåœãŠããããããªã³ã³ãã³ããæ¬²ãã æ¡çšçãªåŽé¢ãšããŠãã¡ãã¬ãŒã«èå³ãæã£ãæ¹ãžæäŸã§ããæ
å ±ããã©ãã©ã«ãªã£ãŠãã 以äžã®èª²é¡ã解決ããããã«ãããã°ã®ãªãã¥ãŒã¢ã«ãããããšã«ãªããŸããã ç¹ã«ä»å¹Žããå
šç€Ÿçãªæ¹éãšããŠãã¡ãã¬ãŒã®ãœããé¢ã§ã®è©±é¡ã«ãã©ãŒã«ã¹ããã³ã³ãã³ããäœã£ãŠãããšããããšã§ãæ¹ããŠå
¬åŒ note ã®æŽæ°ã«æ³šåããŠããããšãããããšã³ãžãã¢ã»ãã¶ã€ããŒããã°ããã®åããšé£åããå¿
èŠããããŸããã 以äžã®çç±ãããã³ã³ãã³ããšããŠã¯åŸæ¥éãã® ããã°èšäº ãæ§ã
ãªã¡ãã£ã¢ã§ã¡ã³ããŒãé²åºããŠãã ã€ã³ã¿ãã¥ãŒèšäº ãã€ãã³ããªã©ã§äœ¿ããã çºè¡šã¹ã©ã€ã ãå
šãŠèŠããããããªç·åçãªãµã€ãã«ããŠããããšãšãªããŸããã ã€ã³ã¿ãã¥ãŒã¯ãããŸã§ãã¡ã³ããŒãæ§ã
ãªã¡ãã£ã¢ã«åºãŠããããã¹ã©ã€ãã以åãã Speaker Deck ãæŽæ°ããŠããã®ã§ããããŸãšãŸã£ã圢ã§ã®æäŸãã§ããŠããŸããã§ããã ä»åã®ãªãã¥ãŒã¢ã«ã§ããããã®èŠçŽ ããŸãšããŠçããã«ãå±ãã§ããããã«ãªã£ãããããMedley Developer BlogããããMedley Developer Portalããšåç§°å€æŽãããŸããã ããããããã¡ãã¬ãŒã®éçºçµç¹ãããå€éšã®çããã«ç¥ã£ãŠãããããã«ãéå¶ãã§ããã°ãšèããŠããŸãã®ã§ããããããé¡ãããŸãã ãšã³ãžãã¢ã»ãã¶ã€ããŒããã°ãªãã¥ãŒã¢ã«ã®æè¡é¢ã«ã€ã㊠ããŠããããŸã§ãªãã¥ãŒã¢ã«ã®èæ¯ããäŒãããŸããããããããã¯ä»å䜿ã£ãæè¡é¢ã«ã€ããŠè»œãè§ŠããŠããããšæããŸãã äœ¿çšæè¡ã«ã€ã㊠æ§ããã°ã¯ãã¯ãŠãªããã°ãã§ã®éçšãããŠããŸããããªãã¥ãŒã¢ã«ã«ããã£ãŠäžèšã®èª²é¡ã解決ããããã«ã¯ãç¬èªã«ããã°ãéçºããã»ãããããšèããŸãããæ°ããã°ã¯ä»¥äžã®æè¡ã䜿ã£ãŠéçºããŸããã Gatsby Emotion TypeScript Netlify Gatsby ã«æ±ºããçç±ã¯å€§ããã¯ä»¥äžã§ããã æ¢ã«åŒç€Ÿå
ã§ Gatsby ã®å°å
¥å®çžŸãããããã瀟å
ã®ã¡ã³ããŒããããšãªã£ããè§Šãã ããã° + α ã®ãµã€ããäœãã®ã«ååãªæè»æ§ããã å
¬åŒãã³ãã¥ããã£ãã©ã°ã€ã³ãå
å®ããŠãããéçºãçååã§ãã Gatsby ã¯ç²Ÿåçã«ã¢ããããŒããè¡ãªãããŠãããæ©ããµã€ã¯ã«ã§é²åããã®ãé
åã® 1 ã€ã§ããã Gatsby 補ãµã€ããã©ã®ããã«å
¬éãããã¯ãæ©ãã ã®ã§ãããçµæçã«äºäŸãå€ããããããã€ã®ç°¡æããæ©èœã®è±å¯ããèã㊠Netlify ã«ããŸããã ã¯ãŠãªããã°ããã®èšäºç§»è¡ã«ã€ã㊠æåããæ§ããã°ã§ã®ã³ã³ãã³ãã¯æ°ããã°ã«ç§»è¡ããããšããã¹ãã ã£ãã®ã§ããŸãã¯ã©ã®ããã«ç§»è¡ãã§ããããšããããšãèæ
®ããããšããå§ããŸãããã¯ãŠãªããã°ã¯éåžžã®ãšã¯ã¹ããŒãã ãš Movable Type æ¹åŒã«ãªãã®ã§ããªããšã Markdown ã«å€æãããâŠãªã©ãšèããŠããŸããã ãããã blogsync ãšããã¯ãŠãªããã°ã® CLI ã¯ã©ã€ã¢ã³ããéããšããŒã«ã«ã« Markdown ãã¡ã€ã«ãšããŠããã°ãšã³ããªãåæããããšãå¯èœã ã£ãããã blogsync ã§å
šãŠã®æ§ããã°ã³ã³ãã³ããããŒã«ã«ã«åæ(ããŠã³ããŒã) ããŒã«ã«ã« Markdown ãã¡ã€ã«ãšããŠããŠã³ããŒãã§ããããã°ã³ã³ãã³ãã Gatsby è£œã®æ°ããã°ã«ã³ã㌠gatsby-source-filesystem ã§ã³ããŒãã Markdown ãã¡ã€ã«ãèªã¿èŸŒã¿ããã°ãšããŠè¡šç€º ãšããæé ã§æ¢åã®ããã°èšäºãå
šãŠç§»è¡ããããšãã§ããŸããã ãŸãããã¡ã€ã³ã«ã€ããŠã¯ç¬èªãã¡ã€ã³ããã®ãŸãŸæ°ããã°ã«ãç§»è¡ããããšãšãããããã¯ãŠãªããã°ãšåã URL 圢åŒã§ããã°ãèªã¿èŸŒããããã«ã«ãŒãã£ã³ã°ãããŸããã èŠåŽããéšå ä»åã®éçºã§èŠåŽããéšåããã€ãžã§ã¹ãã§æžããŠãããŸããèªåã®ããŒãºã«åãããŠèª¿ã¹ãŠã¿ãŠããç¹ã«æ·±ãéšåã«é¢ããŠãããŸãæ
å ±ãåºãŠããªããšãããã¿ãŒã³ãå€ãã£ãããã«æããŸãã ããŒãžã§ã³åºæã®æ
å ±ãããã©ã°ã€ã³ã®æ
å ±ãå°ãªãã£ã éçºåœå㯠Gatsby v4 ãåºãã°ããã ã£ãã®ã§ãäœãã«å°ã£ãŠæ€çŽ¢ããŠãå
¬åŒä»¥å€ã®æ
å ±ã¯ä»¥åã®ããŒãžã§ã³ã§äœ¿ããªãããšãå€ãã£ãã§ãã ãŸããã©ã°ã€ã³é¢ä¿ã®æ
å ±ã調ã¹ãå
容ã«ãã£ãŠã¯äžã
ç®çã®æ
å ±ãåºãŠããªãã£ããããŸããã gatsby-plugin-image åšãã§é¡èãªå°è±¡ã ã£ãã®ã§ãç»ååšãã®è¡šç€ºã«æ³£ããããããšããããŸããã ä»ã«ã Markdown 衚瀺㯠gatsby-plugin-mdx ã䜿çšããŠããŸãããåŸæ¥ã® gatsby-transformer-remark ãšæ
å ±ãæ··åšããŠããå°è±¡ããããŸããã®ã§æ··ä¹±ããããšãã ããŒãžããŒã·ã§ã³ã§ãã¹ããªãã©ã°ã€ã³ãèŠã€ãããªãã£ã å
¬åŒ ã¬ã€ããåèã«ããŒãžããŒã·ã§ã³ãèªåã§äœã£ãŠããã®ã§ããã GraphQL ããæã£ãŠããããŒã¿ã衚瀺ããã ãã§ã¯ããŸããŠãŒã¶ããªãã£ãè¯ããªãã£ãããããã©ã°ã€ã³ãªã©æ¢ããã®ã§ãããããšãã£ããã®ãèŠã€ãããªãã£ãã§ãã å
¬åŒã¬ã€ãåèã«äœããšå»¶ã
èšäºãå¢ãããããŒãžããŒã·ã§ã³ã®æ°ãå¢ããŠãã£ãŠããŸã埮åŠãªæãã§ããâŠãèªåã§å¶åŸ¡ãèããŸããããæçµçã«ã¯ mui/pagination ã³ã³ããŒãã³ããçµã¿åãããããšã§å¯Ÿå¿ããŸããã OGP ç»åèªåçæã«é¢ããŠæ
å ±ãå°ãªã OGP ç»åã¯èªåçæã«ããããšæããŸããããæ¡å€ããŒãºãç¡ãã®ãæ
å ±ãå°ãªãã£ãå°è±¡ã§ããæçµçã« ãã¡ã ã®ããã°ãçºèŠãã kentaro-m/catchy-image ã䜿ã£ãŠçæããããã«ããŸããã ããããããããããš æ©èœã®æ¡å
以å€ã ãšãä»ãŸã§ã¯ã§ããªãã£ã textlint ã§ã®æ ¡æ£ãªã©ãããŠãç·šéæã®è² è·è»œæžãªã©ããã£ãŠãããããšèããŠããŸãã ããã㫠以äžã Developer Portal ã®ãªãã¥ãŒã¢ã«ã«ã€ããŠæžãããŠããã ããŸããã åŒãç¶ããæ
å ±çºä¿¡ãªã©ãããŠããã¡ãã¬ãŒéçºçµç¹ã«ã€ããŠãçããã«ç¥ã£ãŠããã ããã°ãšæããŸãã æåŸã«ãªããŸãããå»çãã«ã¹ã±ã¢ã®ãããã¯ãéçºã«(ãã®ãããªããã°è£œäœã)é¢ãã£ãŠãããã!ãšããæ¹ã¯ãã²äžèšãããå¿åãåŸ
ã¡ããŠãããŸã! åéã®äžèЧ | æ ªåŒäŒç€Ÿã¡ãã¬ãŒ ã¡ãã¬ãŒã®æ¡çšæ
å ±ã¯ãã¡ãããã確èªãã ããã www.medley.jp
ã¯ããã« çãããããã«ã¡ã¯ããšã³ãžãã¢ã»æè¡åºå ±ã®å¹³æšã§ãã 以åããã芧ã«ãªã£ãŠããã ããŠããæ¹ã«ã¯ãåããããšæããŸããã3/18 ã«ä»ã芧ããã ããŠãããšã³ãžãã¢ã»ãã¶ã€ããŒããã°ããDeveloper Portalããšããåç§°ã«å€æŽã㊠2017 å¹Žä»¥æ¥ 5 幎ã¶ãã«ãªãã¥ãŒã¢ã«ãããŸãããä»åã¯ãªãã¥ãŒã¢ã«ã«ã€ããŠãç®æããšãããšè¥å¹²ã®æè¡çãªåŽé¢ããäŒãã§ããã°ãšæããŸãã ããã°ãããæ°æ§æ¯èŒ æ§ æ° ãšã³ãžãã¢ã»ãã¶ã€ããŒããã°ãªãã¥ãŒã¢ã«ã®èæ¯ ãŸãã¯ã ãªããªãã¥ãŒã¢ã«ããã? ãšããèæ¯ã«ã€ããŠã§ããåŒç€Ÿã®ãšã³ãžãã¢ã»ãã¶ã€ããŒããã°ã®å€é·ãšå
±ã«ã話ããŠãããããšæããŸãã ãšã³ãžãã¢ã»ãã¶ã€ããŒããã°ã®å€é· 第 1 æ(2016/04 ~ 2017/07) Developer Blog 㯠2016/04 æã«äŒç€Ÿå
¬åŒããã°ã«ãšã³ãžãã¢åãã®èšäºãæ²èŒãå§ããããããããã°ããã¯ä»ã®äŒç€Ÿæ
å ±ãšãšãã«æ²èŒãããŠããŸãããèšäºå
容ã¯ãšã³ãžãã¢ãç»å£ããã€ãã³ãæ
å ±ããä»ãç¶ããŠãã TechLunch(å
šç€Ÿæšªæã®ãšã³ãžãã¢ã»ãã¶ã€ããŒåã瀟å
å匷äŒ) ã®çºè¡šã¬ããŒããªã©ãã¡ã€ã³ãšãªã£ãŠããŸããã ãã®é ã¯éçºçµç¹ã®äººæ°ããããŸã§å€ããªãã£ãã®ã§ãããã¡ãã¬ãŒã®éçºçµç¹ã瀟å
ã®æ§ã
ãªéšçœ²ã®é°å²æ°ãšå
±ã«ãäŒãããããšããç®çãã¡ã€ã³ã§ããããŸãã¯ãã¡ãã¬ãŒã®éçºçµç¹ãšããŠã®ãã¬ãŒã³ã¹ãé«ãããããã¯ããå
è£œã§æ¥ã
éçºãããŠããããšããå€éšã®çããã«ç¥ã£ãŠãããããšããç®çãäžçªå€§ããã£ãããã«æããŸãã ãã®ãããªåœ¢ã§ 2017 幎äžé ãŸã§ã¯äŒç€Ÿå
¬åŒããã°ã§ã®æŽæ°ãããŠããŸããããéçºçµç¹ãæ¡å€§ããã«ã€ããçµç¹ãšããŠåºæ¥ãããšãå¢ããŠããŸãããããã«äŒŽãããããŸã§ã®ããã«ãéçºçµç¹ã®ååšã®ã¢ããŒã«ãããçµç¹ã®åãçµã¿ãã«å ããŠãçŽç²ã«æè¡çãªåŽé¢ããã£ãšæã¡åºããŠãããå»ç x ITããšããããŒãã«ã¡ãã¬ãŒã¯ã©ã®ããã«åããã£ãŠããããç¥ã£ãŠãããããšããæ©éãé«ãŸã£ãŠããŸããã 第 2 æ(2017/07 ~ 2022/03) ããããéã³ã§æ°ãã Medley Developer Blog ã 2017/07 æã«ç«ã¡äžããããšã«ãªããŸãããäŒç€Ÿå
¬åŒããã°ããå®å
šã«ç¬ç«ããããã¯ããã°ãšããããšã§ãç®è«èŠéãã«ãããŸã§ä»¥äžã«æè¡çãªæçš¿ãã§ããããã«ãªããŸãããç·šéæ¹åŒããã®æããçŸåšãŸã§ãšã³ãžãã¢ã»ãã¶ã€ããŒãäž»äœãšãªã£ãŠããŸãã æŽæ°é »åºŠãäžå®æã ã£ããã®ãæ 1~2 åãšå¢ãããã³ã³ã¹ã¿ã³ãã«ã¡ãã¬ãŒã®éçºã«é¢ãã話é¡ãåãæ±ãããã«ããŸãããéå¶ãããŠãã 5 幎ã®éã«ããã€ãã®èšäºã¯ããããããŸã§ã¯ãŠãªããã¯ããŒã¯ãªã©ã§ è©±é¡ ã«ãªãããšãããã第 1 æãããããã«çããã«èªãã§ããã ãããããªããã°ã«ãªããŸããã ãã®éã«ã¡ãã¬ãŒãæ§ã
ãªãšã³ãžãã¢ã»ãã¶ã€ããŒã€ãã³ãã«ã¹ãã³ãµãŒããããŠããã ããããããŠãããã°ãšåãããŠäžå®ã®ãã¬ãŒã³ã¹ãåŸãããšãã§ããŠããã®ã§ã¯ãªãããšæã£ãŠããŸããç¹ã«ãå»çãã«ã¹ã±ã¢æ¥çããšãã銎æã¿ãç¡ãæ¹ã«ã¯ããŒãã«ãé«ããšæãããããšãå€ãæ¥çã§ã®ãããã¯ãéçºã«ãäžè¬çãªã€ã³ã¿ãŒããããã¯ãããžãŒãé§äœ¿ããŠãããšããç¹ããè²ã
ãªåŽé¢ãããäŒãã§ããããã«ãªã£ãããšã¯å€§ãããšæããŠããŸãã çŸåš(2022/03 ~) ãããªããã°ã§ããããéèšãã 5 幎çµã¡ä»¥äžã®ãããªèª²é¡ãåºãŠããŸããã äŒç€ŸããŸã äžå Žåã«äœããããã¶ã€ã³ã ã£ããããçŸåšã®ã³ãŒãã¬ãŒããµã€ããªã©ã®ããŒã³ãšãºã¬ãåºãŠããŠãã äŒç€Ÿãçµç¹èŠæš¡ã倧ãããªããåžèã«ãªããã¡ãªå
éšã§åããŠããå人ã«ããã©ãŒã«ã¹ãåœãŠããããããªã³ã³ãã³ããæ¬²ãã æ¡çšçãªåŽé¢ãšããŠãã¡ãã¬ãŒã«èå³ãæã£ãæ¹ãžæäŸã§ããæ
å ±ããã©ãã©ã«ãªã£ãŠãã 以äžã®èª²é¡ã解決ããããã«ãããã°ã®ãªãã¥ãŒã¢ã«ãããããšã«ãªããŸããã ç¹ã«ä»å¹Žããå
šç€Ÿçãªæ¹éãšããŠãã¡ãã¬ãŒã®ãœããé¢ã§ã®è©±é¡ã«ãã©ãŒã«ã¹ããã³ã³ãã³ããäœã£ãŠãããšããããšã§ãæ¹ããŠå
¬åŒ note ã®æŽæ°ã«æ³šåããŠããããšãããããšã³ãžãã¢ã»ãã¶ã€ããŒããã°ããã®åããšé£åããå¿
èŠããããŸããã 以äžã®çç±ãããã³ã³ãã³ããšããŠã¯åŸæ¥éãã® ããã°èšäº ãæ§ã
ãªã¡ãã£ã¢ã§ã¡ã³ããŒãé²åºããŠãã ã€ã³ã¿ãã¥ãŒèšäº ãã€ãã³ããªã©ã§äœ¿ããã çºè¡šã¹ã©ã€ã ãå
šãŠèŠããããããªç·åçãªãµã€ãã«ããŠããããšãšãªããŸããã ã€ã³ã¿ãã¥ãŒã¯ãããŸã§ãã¡ã³ããŒãæ§ã
ãªã¡ãã£ã¢ã«åºãŠããããã¹ã©ã€ãã以åãã Speaker Deck ãæŽæ°ããŠããã®ã§ããããŸãšãŸã£ã圢ã§ã®æäŸãã§ããŠããŸããã§ããã ä»åã®ãªãã¥ãŒã¢ã«ã§ããããã®èŠçŽ ããŸãšããŠçããã«ãå±ãã§ããããã«ãªã£ãããããMedley Developer BlogããããMedley Developer Portalããšåç§°å€æŽãããŸããã ããããããã¡ãã¬ãŒã®éçºçµç¹ãããå€éšã®çããã«ç¥ã£ãŠãããããã«ãéå¶ãã§ããã°ãšèããŠããŸãã®ã§ããããããé¡ãããŸãã ãšã³ãžãã¢ã»ãã¶ã€ããŒããã°ãªãã¥ãŒã¢ã«ã®æè¡é¢ã«ã€ã㊠ããŠããããŸã§ãªãã¥ãŒã¢ã«ã®èæ¯ããäŒãããŸããããããããã¯ä»å䜿ã£ãæè¡é¢ã«ã€ããŠè»œãè§ŠããŠããããšæããŸãã äœ¿çšæè¡ã«ã€ã㊠æ§ããã°ã¯ãã¯ãŠãªããã°ãã§ã®éçšãããŠããŸããããªãã¥ãŒã¢ã«ã«ããã£ãŠäžèšã®èª²é¡ã解決ããããã«ã¯ãç¬èªã«ããã°ãéçºããã»ãããããšèããŸãããæ°ããã°ã¯ä»¥äžã®æè¡ã䜿ã£ãŠéçºããŸããã Gatsby Emotion TypeScript Netlify Gatsby ã«æ±ºããçç±ã¯å€§ããã¯ä»¥äžã§ããã æ¢ã«åŒç€Ÿå
ã§ Gatsby ã®å°å
¥å®çžŸãããããã瀟å
ã®ã¡ã³ããŒããããšãªã£ããè§Šãã ããã° + α ã®ãµã€ããäœãã®ã«ååãªæè»æ§ããã å
¬åŒãã³ãã¥ããã£ãã©ã°ã€ã³ãå
å®ããŠãããéçºãçååã§ãã Gatsby ã¯ç²Ÿåçã«ã¢ããããŒããè¡ãªãããŠãããæ©ããµã€ã¯ã«ã§é²åããã®ãé
åã® 1 ã€ã§ããã Gatsby 補ãµã€ããã©ã®ããã«å
¬éãããã¯ãæ©ãã ã®ã§ãããçµæçã«äºäŸãå€ããããããã€ã®ç°¡æããæ©èœã®è±å¯ããèã㊠Netlify ã«ããŸããã ã¯ãŠãªããã°ããã®èšäºç§»è¡ã«ã€ã㊠æåããæ§ããã°ã§ã®ã³ã³ãã³ãã¯æ°ããã°ã«ç§»è¡ããããšããã¹ãã ã£ãã®ã§ããŸãã¯ã©ã®ããã«ç§»è¡ãã§ããããšããããšãèæ
®ããããšããå§ããŸãããã¯ãŠãªããã°ã¯éåžžã®ãšã¯ã¹ããŒãã ãš Movable Type æ¹åŒã«ãªãã®ã§ããªããšã Markdown ã«å€æãããâŠãªã©ãšèããŠããŸããã ãããã blogsync ãšããã¯ãŠãªããã°ã® CLI ã¯ã©ã€ã¢ã³ããéããšããŒã«ã«ã« Markdown ãã¡ã€ã«ãšããŠããã°ãšã³ããªãåæããããšãå¯èœã ã£ãããã blogsync ã§å
šãŠã®æ§ããã°ã³ã³ãã³ããããŒã«ã«ã«åæ(ããŠã³ããŒã) ããŒã«ã«ã« Markdown ãã¡ã€ã«ãšããŠããŠã³ããŒãã§ããããã°ã³ã³ãã³ãã Gatsby è£œã®æ°ããã°ã«ã³ã㌠gatsby-source-filesystem ã§ã³ããŒãã Markdown ãã¡ã€ã«ãèªã¿èŸŒã¿ããã°ãšããŠè¡šç€º ãšããæé ã§æ¢åã®ããã°èšäºãå
šãŠç§»è¡ããããšãã§ããŸããã ãŸãããã¡ã€ã³ã«ã€ããŠã¯ç¬èªãã¡ã€ã³ããã®ãŸãŸæ°ããã°ã«ãç§»è¡ããããšãšãããããã¯ãŠãªããã°ãšåã URL 圢åŒã§ããã°ãèªã¿èŸŒããããã«ã«ãŒãã£ã³ã°ãããŸããã èŠåŽããéšå ä»åã®éçºã§èŠåŽããéšåããã€ãžã§ã¹ãã§æžããŠãããŸããèªåã®ããŒãºã«åãããŠèª¿ã¹ãŠã¿ãŠããç¹ã«æ·±ãéšåã«é¢ããŠãããŸãæ
å ±ãåºãŠããªããšãããã¿ãŒã³ãå€ãã£ãããã«æããŸãã ããŒãžã§ã³åºæã®æ
å ±ãããã©ã°ã€ã³ã®æ
å ±ãå°ãªãã£ã éçºåœå㯠Gatsby v4 ãåºãã°ããã ã£ãã®ã§ãäœãã«å°ã£ãŠæ€çŽ¢ããŠãå
¬åŒä»¥å€ã®æ
å ±ã¯ä»¥åã®ããŒãžã§ã³ã§äœ¿ããªãããšãå€ãã£ãã§ãã ãŸããã©ã°ã€ã³é¢ä¿ã®æ
å ±ã調ã¹ãå
容ã«ãã£ãŠã¯äžã
ç®çã®æ
å ±ãåºãŠããªãã£ããããŸããã gatsby-plugin-image åšãã§é¡èãªå°è±¡ã ã£ãã®ã§ãç»ååšãã®è¡šç€ºã«æ³£ããããããšããããŸããã ä»ã«ã Markdown 衚瀺㯠gatsby-plugin-mdx ã䜿çšããŠããŸãããåŸæ¥ã® gatsby-transformer-remark ãšæ
å ±ãæ··åšããŠããå°è±¡ããããŸããã®ã§æ··ä¹±ããããšãã ããŒãžããŒã·ã§ã³ã§ãã¹ããªãã©ã°ã€ã³ãèŠã€ãããªãã£ã å
¬åŒ ã¬ã€ããåèã«ããŒãžããŒã·ã§ã³ãèªåã§äœã£ãŠããã®ã§ããã GraphQL ããæã£ãŠããããŒã¿ã衚瀺ããã ãã§ã¯ããŸããŠãŒã¶ããªãã£ãè¯ããªãã£ãããããã©ã°ã€ã³ãªã©æ¢ããã®ã§ãããããšãã£ããã®ãèŠã€ãããªãã£ãã§ãã å
¬åŒã¬ã€ãåèã«äœããšå»¶ã
èšäºãå¢ãããããŒãžããŒã·ã§ã³ã®æ°ãå¢ããŠãã£ãŠããŸã埮åŠãªæãã§ããâŠãèªåã§å¶åŸ¡ãèããŸããããæçµçã«ã¯ mui/pagination ã³ã³ããŒãã³ããçµã¿åãããããšã§å¯Ÿå¿ããŸããã OGP ç»åèªåçæã«é¢ããŠæ
å ±ãå°ãªã OGP ç»åã¯èªåçæã«ããããšæããŸããããæ¡å€ããŒãºãç¡ãã®ãæ
å ±ãå°ãªãã£ãå°è±¡ã§ããæçµçã« ãã¡ã ã®ããã°ãçºèŠãã kentaro-m/catchy-image ã䜿ã£ãŠçæããããã«ããŸããã ããããããããããš æ©èœã®æ¡å
以å€ã ãšãä»ãŸã§ã¯ã§ããªãã£ã textlint ã§ã®æ ¡æ£ãªã©ãããŠãç·šéæã®è² è·è»œæžãªã©ããã£ãŠãããããšèããŠããŸãã ããã㫠以äžã Developer Portal ã®ãªãã¥ãŒã¢ã«ã«ã€ããŠæžãããŠããã ããŸããã åŒãç¶ããæ
å ±çºä¿¡ãªã©ãããŠããã¡ãã¬ãŒéçºçµç¹ã«ã€ããŠãçããã«ç¥ã£ãŠããã ããã°ãšæããŸãã æåŸã«ãªããŸãããå»çãã«ã¹ã±ã¢ã®ãããã¯ãéçºã«(ãã®ãããªããã°è£œäœã)é¢ãã£ãŠãããã!ãšããæ¹ã¯ãã²äžèšãããå¿åãåŸ
ã¡ããŠãããŸã! åéã®äžèЧ | æ ªåŒäŒç€Ÿã¡ãã¬ãŒ ã¡ãã¬ãŒã®æ¡çšæ
å ±ã¯ãã¡ãããã確èªãã ããã www.medley.jp
ã¯ããã« çãããããã«ã¡ã¯ããšã³ãžãã¢ã»æè¡åºå ±ã®å¹³æšã§ãã 以åããã芧ã«ãªã£ãŠããã ããŠããæ¹ã«ã¯ãåããããšæããŸããã3/18 ã«ä»ã芧ããã ããŠãããšã³ãžãã¢ã»ãã¶ã€ããŒããã°ããDeveloper Portalããšããåç§°ã«å€æŽã㊠2017 å¹Žä»¥æ¥ 5 幎ã¶ãã«ãªãã¥ãŒã¢ã«ãããŸãããä»åã¯ãªãã¥ãŒã¢ã«ã«ã€ããŠãç®æããšãããšè¥å¹²ã®æè¡çãªåŽé¢ããäŒãã§ããã°ãšæããŸãã ããã°ãããæ°æ§æ¯èŒ æ§ æ° ãšã³ãžãã¢ã»ãã¶ã€ããŒããã°ãªãã¥ãŒã¢ã«ã®èæ¯ ãŸãã¯ã ãªããªãã¥ãŒã¢ã«ããã? ãšããèæ¯ã«ã€ããŠã§ããåŒç€Ÿã®ãšã³ãžãã¢ã»ãã¶ã€ããŒããã°ã®å€é·ãšå
±ã«ã話ããŠãããããšæããŸãã ãšã³ãžãã¢ã»ãã¶ã€ããŒããã°ã®å€é· 第 1 æ(2016/04 ~ 2017/07) Developer Blog 㯠2016/04 æã«äŒç€Ÿå
¬åŒããã°ã«ãšã³ãžãã¢åãã®èšäºãæ²èŒãå§ããããããããã°ããã¯ä»ã®äŒç€Ÿæ
å ±ãšãšãã«æ²èŒãããŠããŸãããèšäºå
容ã¯ãšã³ãžãã¢ãç»å£ããã€ãã³ãæ
å ±ããä»ãç¶ããŠãã TechLunch(å
šç€Ÿæšªæã®ãšã³ãžãã¢ã»ãã¶ã€ããŒåã瀟å
å匷äŒ) ã®çºè¡šã¬ããŒããªã©ãã¡ã€ã³ãšãªã£ãŠããŸããã ãã®é ã¯éçºçµç¹ã®äººæ°ããããŸã§å€ããªãã£ãã®ã§ãããã¡ãã¬ãŒã®éçºçµç¹ã瀟å
ã®æ§ã
ãªéšçœ²ã®é°å²æ°ãšå
±ã«ãäŒãããããšããç®çãã¡ã€ã³ã§ããããŸãã¯ãã¡ãã¬ãŒã®éçºçµç¹ãšããŠã®ãã¬ãŒã³ã¹ãé«ãããããã¯ããå
è£œã§æ¥ã
éçºãããŠããããšããå€éšã®çããã«ç¥ã£ãŠãããããšããç®çãäžçªå€§ããã£ãããã«æããŸãã ãã®ãããªåœ¢ã§ 2017 幎äžé ãŸã§ã¯äŒç€Ÿå
¬åŒããã°ã§ã®æŽæ°ãããŠããŸããããéçºçµç¹ãæ¡å€§ããã«ã€ããçµç¹ãšããŠåºæ¥ãããšãå¢ããŠããŸãããããã«äŒŽãããããŸã§ã®ããã«ãéçºçµç¹ã®ååšã®ã¢ããŒã«ãããçµç¹ã®åãçµã¿ãã«å ããŠãçŽç²ã«æè¡çãªåŽé¢ããã£ãšæã¡åºããŠãããå»ç x ITããšããããŒãã«ã¡ãã¬ãŒã¯ã©ã®ããã«åããã£ãŠããããç¥ã£ãŠãããããšããæ©éãé«ãŸã£ãŠããŸããã 第 2 æ(2017/07 ~ 2022/03) ããããéã³ã§æ°ãã Medley Developer Blog ã 2017/07 æã«ç«ã¡äžããããšã«ãªããŸãããäŒç€Ÿå
¬åŒããã°ããå®å
šã«ç¬ç«ããããã¯ããã°ãšããããšã§ãç®è«èŠéãã«ãããŸã§ä»¥äžã«æè¡çãªæçš¿ãã§ããããã«ãªããŸãããç·šéæ¹åŒããã®æããçŸåšãŸã§ãšã³ãžãã¢ã»ãã¶ã€ããŒãäž»äœãšãªã£ãŠããŸãã æŽæ°é »åºŠãäžå®æã ã£ããã®ãæ 1~2 åãšå¢ãããã³ã³ã¹ã¿ã³ãã«ã¡ãã¬ãŒã®éçºã«é¢ãã話é¡ãåãæ±ãããã«ããŸãããéå¶ãããŠãã 5 幎ã®éã«ããã€ãã®èšäºã¯ããããããŸã§ã¯ãŠãªããã¯ããŒã¯ãªã©ã§ è©±é¡ ã«ãªãããšãããã第 1 æãããããã«çããã«èªãã§ããã ãããããªããã°ã«ãªããŸããã ãã®éã«ã¡ãã¬ãŒãæ§ã
ãªãšã³ãžãã¢ã»ãã¶ã€ããŒã€ãã³ãã«ã¹ãã³ãµãŒããããŠããã ããããããŠãããã°ãšåãããŠäžå®ã®ãã¬ãŒã³ã¹ãåŸãããšãã§ããŠããã®ã§ã¯ãªãããšæã£ãŠããŸããç¹ã«ãå»çãã«ã¹ã±ã¢æ¥çããšãã銎æã¿ãç¡ãæ¹ã«ã¯ããŒãã«ãé«ããšæãããããšãå€ãæ¥çã§ã®ãããã¯ãéçºã«ãäžè¬çãªã€ã³ã¿ãŒããããã¯ãããžãŒãé§äœ¿ããŠãããšããç¹ããè²ã
ãªåŽé¢ãããäŒãã§ããããã«ãªã£ãããšã¯å€§ãããšæããŠããŸãã çŸåš(2022/03 ~) ãããªããã°ã§ããããéèšãã 5 幎çµã¡ä»¥äžã®ãããªèª²é¡ãåºãŠããŸããã äŒç€ŸããŸã äžå Žåã«äœããããã¶ã€ã³ã ã£ããããçŸåšã®ã³ãŒãã¬ãŒããµã€ããªã©ã®ããŒã³ãšãºã¬ãåºãŠããŠãã äŒç€Ÿãçµç¹èŠæš¡ã倧ãããªããåžèã«ãªããã¡ãªå
éšã§åããŠããå人ã«ããã©ãŒã«ã¹ãåœãŠããããããªã³ã³ãã³ããæ¬²ãã æ¡çšçãªåŽé¢ãšããŠãã¡ãã¬ãŒã«èå³ãæã£ãæ¹ãžæäŸã§ããæ
å ±ããã©ãã©ã«ãªã£ãŠãã 以äžã®èª²é¡ã解決ããããã«ãããã°ã®ãªãã¥ãŒã¢ã«ãããããšã«ãªããŸããã ç¹ã«ä»å¹Žããå
šç€Ÿçãªæ¹éãšããŠãã¡ãã¬ãŒã®ãœããé¢ã§ã®è©±é¡ã«ãã©ãŒã«ã¹ããã³ã³ãã³ããäœã£ãŠãããšããããšã§ãæ¹ããŠå
¬åŒ note ã®æŽæ°ã«æ³šåããŠããããšãããããšã³ãžãã¢ã»ãã¶ã€ããŒããã°ããã®åããšé£åããå¿
èŠããããŸããã 以äžã®çç±ãããã³ã³ãã³ããšããŠã¯åŸæ¥éãã® ããã°èšäº ãæ§ã
ãªã¡ãã£ã¢ã§ã¡ã³ããŒãé²åºããŠãã ã€ã³ã¿ãã¥ãŒèšäº ãã€ãã³ããªã©ã§äœ¿ããã çºè¡šã¹ã©ã€ã ãå
šãŠèŠããããããªç·åçãªãµã€ãã«ããŠããããšãšãªããŸããã ã€ã³ã¿ãã¥ãŒã¯ãããŸã§ãã¡ã³ããŒãæ§ã
ãªã¡ãã£ã¢ã«åºãŠããããã¹ã©ã€ãã以åãã Speaker Deck ãæŽæ°ããŠããã®ã§ããããŸãšãŸã£ã圢ã§ã®æäŸãã§ããŠããŸããã§ããã ä»åã®ãªãã¥ãŒã¢ã«ã§ããããã®èŠçŽ ããŸãšããŠçããã«ãå±ãã§ããããã«ãªã£ãããããMedley Developer BlogããããMedley Developer Portalããšåç§°å€æŽãããŸããã ããããããã¡ãã¬ãŒã®éçºçµç¹ãããå€éšã®çããã«ç¥ã£ãŠãããããã«ãéå¶ãã§ããã°ãšèããŠããŸãã®ã§ããããããé¡ãããŸãã ãšã³ãžãã¢ã»ãã¶ã€ããŒããã°ãªãã¥ãŒã¢ã«ã®æè¡é¢ã«ã€ã㊠ããŠããããŸã§ãªãã¥ãŒã¢ã«ã®èæ¯ããäŒãããŸããããããããã¯ä»å䜿ã£ãæè¡é¢ã«ã€ããŠè»œãè§ŠããŠããããšæããŸãã äœ¿çšæè¡ã«ã€ã㊠æ§ããã°ã¯ãã¯ãŠãªããã°ãã§ã®éçšãããŠããŸããããªãã¥ãŒã¢ã«ã«ããã£ãŠäžèšã®èª²é¡ã解決ããããã«ã¯ãç¬èªã«ããã°ãéçºããã»ãããããšèããŸãããæ°ããã°ã¯ä»¥äžã®æè¡ã䜿ã£ãŠéçºããŸããã Gatsby Emotion TypeScript Netlify Gatsby ã«æ±ºããçç±ã¯å€§ããã¯ä»¥äžã§ããã æ¢ã«åŒç€Ÿå
ã§ Gatsby ã®å°å
¥å®çžŸãããããã瀟å
ã®ã¡ã³ããŒããããšãªã£ããè§Šãã ããã° + α ã®ãµã€ããäœãã®ã«ååãªæè»æ§ããã å
¬åŒãã³ãã¥ããã£ãã©ã°ã€ã³ãå
å®ããŠãããéçºãçååã§ãã Gatsby ã¯ç²Ÿåçã«ã¢ããããŒããè¡ãªãããŠãããæ©ããµã€ã¯ã«ã§é²åããã®ãé
åã® 1 ã€ã§ããã Gatsby 補ãµã€ããã©ã®ããã«å
¬éãããã¯ãæ©ãã ã®ã§ãããçµæçã«äºäŸãå€ããããããã€ã®ç°¡æããæ©èœã®è±å¯ããèã㊠Netlify ã«ããŸããã ã¯ãŠãªããã°ããã®èšäºç§»è¡ã«ã€ã㊠æåããæ§ããã°ã§ã®ã³ã³ãã³ãã¯æ°ããã°ã«ç§»è¡ããããšããã¹ãã ã£ãã®ã§ããŸãã¯ã©ã®ããã«ç§»è¡ãã§ããããšããããšãèæ
®ããããšããå§ããŸãããã¯ãŠãªããã°ã¯éåžžã®ãšã¯ã¹ããŒãã ãš Movable Type æ¹åŒã«ãªãã®ã§ããªããšã Markdown ã«å€æãããâŠãªã©ãšèããŠããŸããã ãããã blogsync ãšããã¯ãŠãªããã°ã® CLI ã¯ã©ã€ã¢ã³ããéããšããŒã«ã«ã« Markdown ãã¡ã€ã«ãšããŠããã°ãšã³ããªãåæããããšãå¯èœã ã£ãããã blogsync ã§å
šãŠã®æ§ããã°ã³ã³ãã³ããããŒã«ã«ã«åæ(ããŠã³ããŒã) ããŒã«ã«ã« Markdown ãã¡ã€ã«ãšããŠããŠã³ããŒãã§ããããã°ã³ã³ãã³ãã Gatsby è£œã®æ°ããã°ã«ã³ã㌠gatsby-source-filesystem ã§ã³ããŒãã Markdown ãã¡ã€ã«ãèªã¿èŸŒã¿ããã°ãšããŠè¡šç€º ãšããæé ã§æ¢åã®ããã°èšäºãå
šãŠç§»è¡ããããšãã§ããŸããã ãŸãããã¡ã€ã³ã«ã€ããŠã¯ç¬èªãã¡ã€ã³ããã®ãŸãŸæ°ããã°ã«ãç§»è¡ããããšãšãããããã¯ãŠãªããã°ãšåã URL 圢åŒã§ããã°ãèªã¿èŸŒããããã«ã«ãŒãã£ã³ã°ãããŸããã èŠåŽããéšå ä»åã®éçºã§èŠåŽããéšåããã€ãžã§ã¹ãã§æžããŠãããŸããèªåã®ããŒãºã«åãããŠèª¿ã¹ãŠã¿ãŠããç¹ã«æ·±ãéšåã«é¢ããŠãããŸãæ
å ±ãåºãŠããªããšãããã¿ãŒã³ãå€ãã£ãããã«æããŸãã ããŒãžã§ã³åºæã®æ
å ±ãããã©ã°ã€ã³ã®æ
å ±ãå°ãªãã£ã éçºåœå㯠Gatsby v4 ãåºãã°ããã ã£ãã®ã§ãäœãã«å°ã£ãŠæ€çŽ¢ããŠãå
¬åŒä»¥å€ã®æ
å ±ã¯ä»¥åã®ããŒãžã§ã³ã§äœ¿ããªãããšãå€ãã£ãã§ãã ãŸããã©ã°ã€ã³é¢ä¿ã®æ
å ±ã調ã¹ãå
容ã«ãã£ãŠã¯äžã
ç®çã®æ
å ±ãåºãŠããªãã£ããããŸããã gatsby-plugin-image åšãã§é¡èãªå°è±¡ã ã£ãã®ã§ãç»ååšãã®è¡šç€ºã«æ³£ããããããšããããŸããã ä»ã«ã Markdown 衚瀺㯠gatsby-plugin-mdx ã䜿çšããŠããŸãããåŸæ¥ã® gatsby-transformer-remark ãšæ
å ±ãæ··åšããŠããå°è±¡ããããŸããã®ã§æ··ä¹±ããããšãã ããŒãžããŒã·ã§ã³ã§ãã¹ããªãã©ã°ã€ã³ãèŠã€ãããªãã£ã å
¬åŒ ã¬ã€ããåèã«ããŒãžããŒã·ã§ã³ãèªåã§äœã£ãŠããã®ã§ããã GraphQL ããæã£ãŠããããŒã¿ã衚瀺ããã ãã§ã¯ããŸããŠãŒã¶ããªãã£ãè¯ããªãã£ãããããã©ã°ã€ã³ãªã©æ¢ããã®ã§ãããããšãã£ããã®ãèŠã€ãããªãã£ãã§ãã å
¬åŒã¬ã€ãåèã«äœããšå»¶ã
èšäºãå¢ãããããŒãžããŒã·ã§ã³ã®æ°ãå¢ããŠãã£ãŠããŸã埮åŠãªæãã§ããâŠãèªåã§å¶åŸ¡ãèããŸããããæçµçã«ã¯ mui/pagination ã³ã³ããŒãã³ããçµã¿åãããããšã§å¯Ÿå¿ããŸããã OGP ç»åèªåçæã«é¢ããŠæ
å ±ãå°ãªã OGP ç»åã¯èªåçæã«ããããšæããŸããããæ¡å€ããŒãºãç¡ãã®ãæ
å ±ãå°ãªãã£ãå°è±¡ã§ããæçµçã« ãã¡ã ã®ããã°ãçºèŠãã kentaro-m/catchy-image ã䜿ã£ãŠçæããããã«ããŸããã ããããããããããš æ©èœã®æ¡å
以å€ã ãšãä»ãŸã§ã¯ã§ããªãã£ã textlint ã§ã®æ ¡æ£ãªã©ãããŠãç·šéæã®è² è·è»œæžãªã©ããã£ãŠãããããšèããŠããŸãã ããã㫠以äžã Developer Portal ã®ãªãã¥ãŒã¢ã«ã«ã€ããŠæžãããŠããã ããŸããã åŒãç¶ããæ
å ±çºä¿¡ãªã©ãããŠããã¡ãã¬ãŒéçºçµç¹ã«ã€ããŠãçããã«ç¥ã£ãŠããã ããã°ãšæããŸãã æåŸã«ãªããŸãããå»çãã«ã¹ã±ã¢ã®ãããã¯ãéçºã«(ãã®ãããªããã°è£œäœã)é¢ãã£ãŠãããã!ãšããæ¹ã¯ãã²äžèšãããå¿åãåŸ
ã¡ããŠãããŸã! åéã®äžèЧ | æ ªåŒäŒç€Ÿã¡ãã¬ãŒ ã¡ãã¬ãŒã®æ¡çšæ
å ±ã¯ãã¡ãããã確èªãã ããã www.medley.jp
ããã«ã¡ã¯ãå»çãã©ãããã©ãŒã æ¬éš/ãããã¯ãéçºå®€/第äžéçºã°ã«ãŒãæå±ã®äžåè¯ã§ãã ã¡ãã¬ãŒã«ã¯ 2018 幎ã®é ã«å
¥ç€ŸããŠãããä»å¹Žã§ 4 幎ç®ã«ãªããŸãã åœåã¯ãµãŒããŒãµã€ããäžå¿ã«éçºãæ
åœããŠããã®ã§ãããæè¿ã¯æ£è
ãšã³ã²ãŒãžã¡ã³ãããŒã ãšããæ£è
æ§ã«æäŸãããµãŒãã¹ãéçºããããŒã ã§äž»ã« iOS ã®ä»äºãæ
åœããããšãå€ãã§ãã ããŠå»å¹Žã® 12 æã«ãªããŸããã CLINICS ã¢ã㪠㯠UI ã®ãã«ãªãã¥ãŒã¢ã« ãè¡ããŸããã ä»åã¯ãªãã¥ãŒã¢ã«ã®è£è©± (iOS ã«ã€ããŠ) ãããŠãããããšæããŸãã ãããŸã§ã® CLINICS ã¢ããªã«ã€ã㊠æ¬é¡ãæžãåã«ãCLINICS ã¢ããªã®æŽå²ã玹ä»ããŸãã ãã¡ãŒã¹ãã³ããããèŠãŠã¿ããšãã¢ããªã®éçºã¯ 2016 幎 2 æããããã¹ã¿ãŒããããã¡ãŒã¹ããªãªãŒã¹ãè¡ãããã®ã 2016 幎 5 æã§ããã åœåãæ
åœããŠãããšã³ãžãã¢ã¯ iOS ã®çµéšãè±å¯ãªæ¹ã¯ããããå
šå¡ã§è©Šè¡é¯èª€ããªããéçºãé²ããŠããããã§ãã ãã°ããã®éã¯æ©èœã®è¿œå ãªã©ãè¡ãããŠããŸãããã CLINICS ã«ã«ã ã®éçºã«æ³šåããããã«å€§ããªéçºã¯ã¹ããããã Pharms ãšã®é£æºãéå§ããã 2020 幎 5 æé ãŸã§æ©èœãèšèšã«é¢ããèŠçŽããã»ãšãã©è¡ãããŠããŸããã§ããã iOS ã«è©³ãããšã³ãžãã¢ãããªãã£ãã«ãé¢ããããããªãã®ã¹ããŒãæã§ãªãªãŒã¹ããŠããããšã¯ãããã®éçºåãšããäžèšã«å°œããã®ã§ãããPharms ãšã®é£æºããè¬æåž³ãšãã£ãæ©èœã远å ãããããä»åŸã®éçºãèŠæ®ããéã«æ¢åæ©èœãèšèšã®èŠçŽããè¡ããããšæãããã«ãªã£ãŠããŸããã æ¹åãããéšåã¯ãããããã£ãã®ã§ããã察å¿å·¥æ°ãèžãŸãä»åã®ãªãã¥ãŒã¢ã«ã§ã¯ä»¥äžã® 2 ç¹ã®æ¹åã«æ³šåããããšã«ããŸããã Storyboard ã«ãã View ã®ç®¡ç View ãšããžãã¯ã®åé¢ ãã® 2 ç¹ã«ã€ããŠãããã詳ãã説æããŸãã 1. Storyboard ã«ãã View ã®ç®¡ç åŸæ¥ã®éçºã§ã¯ Storyboard ãå©çšã㊠View ãäœæããŠããŸããã Storyboard ã䜿ããšã¬ã€ã¢ãŠããç»é¢é·ç§»ãç°¡åã«å®è£
ããããšãã§ããŸãããéçºãç¶ããŠãããã¡ã«ä»¥äžã®ãããªåé¡ãç®ç«ã€ããã«ãªã£ãŠããŸããã Storyboard ã巚倧åããŠãããè€æ°äººéçºãè¡ãéã«æ¯éãã§ã ã¬ã€ã¢ãŠãã«è¿œå ã»å€æŽãè¡ãããå Žåã« AutoLayout ã®åèšå®ã«æéãããã ã³ã³ããŒãã³ãèªäœã«ãµã€ãºãèšå®ãããŠããããšããããã³ã³ããŒãã³ããåå©çšã§ããªãããšããã èª²é¡ ãã¡ãã¯å®éã«ãã£ã Storyboard ã®ãã£ããã£ã§ãããè€æ°ã®ç»é¢ã 1 ã€ã® Storyboard å
ã«è©°ã蟌ãŸããç¶æ
ãšãªã£ãŠããŸããã Storyboard 㯠Xcode ã®ããŒãžã§ã³ã«ãã埮åŠãªå·®åãçºçããŠããŸã£ãããAutoLayout ã®èª¿æŽãå¿
èŠã«ãªãå ŽåããããŸãã ãã¡ãã¯å€ã Storyboard ã®ç»é¢ãéããåŸã®å·®åãªã®ã§ããããã®å€æŽãã·ã¹ãã ã«ãã£ãŠå ãããã倿Žãªã®ããä»äººã®æ¹ä¿®ã«ãã倿Žãªã®ããåŸããèŠãæã«ãããã¥ãããšããåé¡ããããŸããã ä»®ã«åé¡ãçºçããå Žåã¯ä¿®æ£ã詊ã¿ãã®ã§ãããç¬èªã® XML ã«ãã£ãŠè¡šçŸãããŠãããããiOS ã®çµéšãæµ
ãåã«ãšã£ãŠã¯ä¿®æ£ãéåžžã«é£ããã£ãã§ãã ãŸããè€æ°äººã§äžŠè¡ããŠéçºããéã«ãã³ã³ããªã¯ããèµ·ãããããªã£ãŠããŸãè§£æ¶ã«æéãããããšããåé¡ãšãªã£ãŠããŸããã ããã«åŸæ¥ã® CLINICS ã¢ããªã¯ DLS ãå©çšããŠã¬ã€ã¢ãŠããäœæããŠããã®ã§ãããã³ã³ããŒãã³ãã«çŽæ¥ãµã€ãºãèšå®ãããŠãããã®ããããããç»é¢ã§ã¯åŸ®åŠã«ãµã€ãºã調æŽãããâŠãšãã£ãèŠä»¶ã«å¯Ÿå¿ã§ããããã£ããã®ã³ã³ããŒãã³ããåå©çšã§ããªãã±ãŒã¹ããããŸããã è§£æ±ºæ¡ èª²é¡ã«å¯Ÿãã解決æ¡ã¯è²ã
ãšèããããŸãããåŒç€Ÿã®éçºã¹ã¿ã€ã«ããšã³ãžãã¢ã®ã¹ãã«ãèæ
®ã以äžã®ãããªæ¹éãç«ãŠãŸããã Storyboard ãšåç»é¢ã®å®è£
㯠1 : 1 ã®é¢ä¿ãšãã ç»é¢é·ç§»ã®è²¬åã Storyboard ããåãé¢ã ã³ã³ããŒãã³ãã«ã¢ãããã¯ãã¶ã€ã³ãé©çšãã Storyboard ã®åå²ã¯ä»¥äžã®ãããªã¹ãããã§è¡ã£ãŠããŸããã Refactor to Storyboard ã䜿ã£ãŠå·šå€§ãª Storyboard ãåå²ãã SwiftGen ãå©çšãç»é¢çæã®ã³ãŒããèªåäœæãã 2 ã§çæãããã®ãå©çšããŠç»é¢é·ç§»ãè¡ã æ¢åã® Segue ãåé€ãã ãŸãæåã« Xcode 7 ããå©çšå¯èœãšãªã£ããRefactor to Storyboardãã䜿ã£ãŠç»é¢ãåå²ãããšããããå§ããŸãã ãã®æ©èœãå©çšãããšéžæãã View ãæ°ãã Storyboard ã«åãåºãããå
ã® Storyboard ã«ã¯åãåºãã Storyboard ãžã®ãªãã¡ã¬ã³ã¹ã Segue çã®æ¥ç¶ãä¿æãããç¶æ
ã«ãªããŸãã æ¬¡ã«åç»é¢éã®é·ç§»ã Segue ã䜿ããã«è¡ãããã«ããŸãã Segue ã¯äŸ¿å©ãªã®ã§ãããIdentifier ãåãªãæååã§ãã£ãããStoryboard ãåå²ããŠããªãã¡ã¬ã³ã¹ã¯ä¿æããŠããå¿
èŠãããç¹ã埮åŠã«æããŠããŸãå©çšããªãããšã«ããŸããã Segue ã䜿ããã«ç»é¢é·ç§»ãè¡ãå¿
èŠããããããç»é¢çæãšç»é¢é·ç§»ã®æ¹æ³ãèªåã§å®è£
ããå¿
èŠããããŸãã ä»åã¯ç»é¢çæã®åŠçã SwiftGen ãå©çšããŠèªåçæå¯èœã«ããVIPER ãšããã¢ãŒããã¯ãã£ã® Router ãåèã«ããŠç»é¢é·ç§»ã Storyboard ããåãé¢ãããšã«ããŸããã â» SwiftGen ã®å©ç𿹿³ã¯ SwiftGen#interface-builder ãåç
§ãã ããã Router ã®å®è£
ã¯ä»¥äžã®éãã§ãã å®è£
ããããããã³ã«ãé·ç§»å
ã® VC ã«ç¶æ¿ããç»é¢é·ç§»ã®ã³ãŒããåŒã³åºãã ãã§ç»é¢é·ç§»ãè¡ãããšãã§ããŸãã protocol ClinicWireframe : AnyObject { var viewController: UIViewController { get } func presentClinic ( clinicId : String ) func pushClinic ( clinicId : String ) } extension ClinicWireframe { func presentClinic ( clinicId : String ) { let vc = StoryboardScene. Clinic . initialScene . instantiate { ClinicViewController ( coder : $0 , isHeaderEnabled : true ) } let presenter = ClinicPresenter ( view : vc) presenter. setClinicId ( clinicId : clinicId) vc. inject ( presenter : presenter) vc. modalPresentationStyle = . pageSheet let nc = UINavigationController ( rootViewController : vc) viewController. present (nc, animated : true ) } func pushClinic ( clinicId : String ) { let vc = StoryboardScene. Clinic . initialScene . instantiate { ClinicViewController ( coder : $0 , isHeaderEnabled : false ) } let presenter = ClinicPresenter ( view : vc) presenter. setClinicId ( clinicId : clinicId) vc. inject ( presenter : presenter) viewController. navigationController ?. pushViewController (vc, animated : true ) } æåŸã«ã³ã³ããŒãã³ãã®èª¿æŽã«ã€ããŠã§ãããCLINICS ã¢ããªã§ã¯ã¢ãããã¯ãã¶ã€ã³ãç°¡ç¥åãã以äžã®ãããªåºæºã§ã³ã³ããŒãã³ããå®è£
ããŠããŸãã Block: UI ã®æå°åäœ (ä»ã® PJT ã«ãæã¡èŸŒããããªã¬ãã«ãŸã§åè§£ããããã®) Partial: CLINICS ã® PJT åºæã®ã³ã³ããŒãã³ã Layout: ãã«ãçšã®ã¢ãŒãã«ããšã©ãŒç»é¢ãªã©ä»ã®ç»é¢ããåŒã³åºãããããšã§åããŠæå³ããªãç»é¢ãªã© Page: å ViewController ãšããã«çŽã¥ã Storyboard ãã®ç®¡çæ¹æ³èªäœã¯ åŒç€Ÿã®å¥ãããã¯ãã®éçºãæ
åœããŠãããšã³ãžãã¢ã«ãã£ãŠèæ¡ããããã®ã§ãã åŒç€Ÿã§ã¯ãµãŒããŒã»ããã³ãåãéãŠãªãéçºãä»»ãããããšãå€ããå³å¯ãªã¢ãããã¯ãã¶ã€ã³ã ãšã³ã³ããŒãã³ãã®åé¡ã«å°ãããšãå€ãã£ããããã®ãããªç®¡çæ¹æ³ããšã£ãŠããããã§ãã ä»åã®ãªãã¥ãŒã¢ã«ã«éã㊠CLINICS ã¢ããªã§ããããåèã«ããããšã«ããŸããã ãããŸã§ DLS ãšããŠç®¡çãããŠããã³ã³ããŒãã³ã㯠Block ã§å®è£
ããªãããWidth / Height ãšãã£ããµã€ãºã®èšå®ãè¡ããªãããã«ããŸããã ãã®ããã«ã³ã³ããŒãã³ãã®å®è£
ã¬ãã«ãæç¢ºã«ããããšã§ãå®è£
ã«äžå®ã®æéãçãŸã䜿ãåãã®å¹ãã³ã³ããŒãã³ããäœæãããããªããŸããã 2. View ãšããžãã¯ã®åé¢ ã¹ããŒãéçºãæ±ããããèæ¯ãèãããšä»æ¹ã®ãªãããšã§ã¯ããã®ã§ãããåŸæ¥ã® CLINICS ã¢ããªã§ã¯ ViewController ã«ããžãã¯ãèšè¿°ãããŠãããä¿ã«ãã Fat ViewController ã®ç¶æ
ã«ãªã£ãŠããŸã£ãŠããŸããã Fat ViewController ã®åé¡ç¹ã«ã€ããŠã¯æ¢ã«ããŸããŸãªæ¹ãåãäžããŠããŸããã以äžã®éšåãåé¡ãšæããŠããŸãã UI ãšããžãã¯ãåé¢ãããŠããªãããããã¹ããæžãããšãé£ãã å¯èªæ§ãäœããªããã¡ ããžãã¯ãåãåºãããŠããªããã䌌ããããªå®è£
ãç¹åšããå Žåããã èª²é¡ ãã¡ãã¯å®éã«ãã£ã ViewController ã®äžéšã§ãã ãã®ã³ãŒãã«é¢ããŠã¯ä»¥äžã®éšåãåé¡ãšæããŠããŸããã éä¿¡åŠçã®åŒã³åºãã ViewController ã®è²¬åã«ãªã£ãŠããããš éä¿¡çµæãæŽåœ¢ããããžãã¯ã ViewController ã®è²¬åã«ãªã£ãŠããããš ç»é¢æç»ã®ããã® State 管çã ViewController ã®è²¬åã«ãªã£ãŠããããš è§£æ±ºæ¡ UI ãšããžãã¯ãåé¢ããããã®ææ³ã¯ããŸããŸãªãã®ããããŸãããåŒç€Ÿã®ã¢ããªã«ã¯ä»¥äžã®ãããªç¹åŸŽããããŸãã iOS 以å€ã«ãè€æ°ã®ãã©ãããã©ãŒã ããµããŒãããŠããããããã³ããšã³ãã§ä¿æããããŒã¿ãè€éãªããžãã¯èªäœã¯å°ãªã (ãµãŒããŒåŽã§ãªãã¹ãæ
ä¿ããŠãã) å®è£
æã QA æã«æããéåæã«ã€ããŠçްãããã£ã¬ã¯ã¿ãŒãšæã¡åãããããã®çµææ¬¡ç¬¬ã§ã¯ä»æ§ã倿Žããããšããã ããããèæ
®ãããšããããžã§ã¯ãã®æéçã«åæã®å°å
¥ã³ã¹ããäœããããŒã¿ãããŒãã·ã³ãã«ãªãã®ã«çããããšããããã«èãããŸãšãŸã£ãŠããŸããã ããããèæ
®ããCLINICS ã¢ããªã§ã¯ MVP ãšããã¢ãŒããã¯ãã£ãæ¡çšããããšã«ããŸããã ãã詳现ã«ã¯ MVP ã® Passive View æ¹åŒãæ¡çšããŠããã以äžã®ãããªåœ¢ã§å®è£
ããŠããŸãã View ã¯åºæ¬çã«ãã¹ãŠã®å
¥åã€ãã³ãã«å¯Ÿå¿ãã Presenter ã®åŠçãåŒã³åºã Presenter ã¯å
¥åã«å¿ããŠéä¿¡åŠçãªã©ã®å€éšèŠå ãšãªãåŠçãåŒã³åºããçµæãæŽåœ¢ãã ãã¬ãŒã³ããŒã·ã§ã³ããžãã¯ã®çµæãæç»ããããã« View ã«æç€ºãåºã View 㯠Presenter ã®æç€ºã«ãã£ãŠã®ã¿æç»åŠçãè¡ããèªèº«ãèµ·ç¹ãšããæç»åŠçã¯è¡ããªã Modelâviewâpresenter - Wikipedia æ¢ã« Router ã¯å°å
¥ããŠããããè€éãªåŠçãããŒãå®è£
ãããå Žå㯠Interactor ãå°å
¥ããã ãã§ VIPER ã¢ãŒããã¯ãã£ãžãšçºå±ãããããšãç°¡åã«ã§ããç¹ãé
åã§ããã CLINICS ã¢ããªã§ã® ViewController / Presenter ã®å®è£
ãç°¡åã«ãŸãšãããã®ã¯ä»¥äžã®ããã«ãªã£ãŠããŸãã final class ClinicViewController : UIViewController { private lazy var presenter: ClinicPresenterInput = { fatalError (âFailed to inject presenterâ) }() override func viewDidLoad () { super . viewDidLoad () presenter?. refresh () } func inject ( presenter : ClinicPresenterInput) { self . presenter = presenter } // ã¿ãããããéã«åŒã³åºã func onTapServiceCell ( _ service : ServiceEntity, isTelemedicine : Bool ) { presenter?. didTapServiceButton (service, isTelemedicine : isTelemedicine) } } // MARK: - ClinicPresenterOutput extension ClinicViewController : ClinicPresenterOutput { func reloadData ( clinic : ClinicEntity?) { clinicViewStore. clinic = clinic } func openCreateAppointmentView ( clinic : ClinicEntity, service : ServiceEntity, isTelemedicine : Bool ) // äºçŽãžé²ã } func showErrorAlert ( _ error : Error ) { // ãšã©ãŒè¡šç€ºãè¡ã } } protocol ClinicPresenterInput : AnyObject { func refresh () func didTapServiceButton ( _ service : ServiceEntity, isTelemedicine : Bool ) } protocol ClinicPresenterOutput : AnyObject { func reloadData ( clinic : ClinicEntity?) func openCreateAppointmentView ( clinic : ClinicEntity, service : ServiceEntity, isTelemedicine : Bool ) func showErrorAlert ( _ error : Error ) } final class ClinicPresenter { private let clinicRepository: ClinicRepository private var clinic: ClinicEntity? private var cancellables: Set <AnyCancellable> = . init () init ( view : ClinicPresenterOutput, container : DIContainer) { self . view = view clinicRepository = container. resolve () } private func reloadView () { view?. reloadData ( clinic : clinic) } } // MARK: - PresenterInput extension ClinicPresenter : ClinicPresenterInput { func refresh () { guard let clinicId = clinicId else { return } clinicRepository. getClinic ( clinicId : clinicId) . sink ( receiveCompletion : { [ weak self ] completion in guard let self = self else { return } guard case let . failure (error) = completion else { return } self . view ?. showErrorAlert (error) } }, receiveValue : { [ weak self ] response in guard let self = self else { return } self . clinic = response. data self . reloadView () } ) . store ( in : &cancellables) } func didTapServiceButton ( _ service : ClinicsServiceEntity, isTelemedicine : Bool ) { guard let clinic = clinic else { return } view?. openCreateAppointmentView ( clinic : clinic, service : service, isTelemedicine : isTelemedicine) } } ViewController ãš Presenter ã¯ä»¥äžã®ããã« Router ã®å
éšã§ DI ããããã«ããŠããŸãã protocol ClinicWireframe : AnyObject { var viewController: UIViewController { get } func pushClinic ( clinicId : String ) } extension ClinicWireframe { func pushClinic ( clinicId : String ) { let vc = StoryboardScene. Clinic . initialScene . instantiate { ClinicViewController ( coder : $0 , isHeaderEnabled : false ) } let presenter = ClinicPresenter ( view : vc, container : DIContainer ()) presenter. setClinicId ( clinicId : clinicId) vc. inject ( presenter : presenter) viewController. navigationController ?. pushViewController (vc, animated : true ) } } ããã«ãã£ãŠãããšããš ViewController ã«ãã£ãåŠçã¯ä»¥äžã®ããã«åé¢ãããŸããã ãŸããView ãš Presenter ã¯ã€ã³ã¿ãŒãã§ãŒã¹ãä»ããŠãããäºããç¥ããªããããå®è£
ã®äº€æãç°¡åã«ã§ããããã«ãªããŸããã Presenter ã亀æããããšã§ 1 ã€ã® View ã§å¥ã
ã®åŠçã衚çŸããããšãå¯èœãšãªã£ãããView ããã¹ãã³ãŒãã亀æããããšã§ Presenter ã®å
¥åºåå€ããã¹ãããããšãã§ããããã«ãªã£ãŠããŸãã ãŸãšã CLINICS ã¢ããªã¯æŽå²ã®ãããããžã§ã¯ãã§ãããä»åã®ãããžã§ã¯ããéã㊠UI ã ãã§ãªãè£åŽã®å®è£
ãå·æ°ããŠããŸãã 巚倧㪠Storyboard ãåè§£ããããšã§ã¡ã³ããããªãã£ãåäžããMVP (+ Router) ã®å°å
¥ã«ãã£ãŠ View ãšããžãã¯ã®äº€æãç°¡åã«ãªãããã¹ããªã©ã®å®è£
ãåãå
¥ãããããªããŸããã ãããã« ããã°ã®æ¬ç·šã«ã¯æžããªãã£ãã®ã§ãããä»åãªãã¥ãŒã¢ã«ãããç»é¢ã«é¢ããŠã¯ SwiftUI ãå©çšããŠãã«ã¹ã¯ã©ããã§å®è£
ããŠãããã Asset ã®ç®¡çæ¹æ³ã«ã€ããŠã倧ããªèŠçŽããè¡ããŸããã ãŸãã¢ãŒããã¯ãã£ã®éžå®ã«ããããã iOS ã¢ããªèšèšãã¿ãŒã³å
¥é ãã倧å€åèã«ãªããŸãããiOS ã®éçºãè¡ãæ¹ã¯ãã²äžèªããŠã»ãããšæããŸãã çŽå幎ã»ã©ããã£ã倧ããªãããžã§ã¯ãã§ããããæ£è
ãšã³ã²ãŒãžã¡ã³ãããŒã ã®ã¡ã³ããŒå
šå¡ã§åãçµã¿ç¡äºã«ãªãªãŒã¹ãŸã§æŒãçããããšãã§ããŸããããŸã ãŸã ææ¢ããªéšåããããŸãããä»åŸãæ£è
ããã«ãšã£ãŠããå®å¿ããŠäœ¿ãããµãŒãã¹ãšãªãããã«éçºãç¶ããŠãããã°ãšæã£ãŠããŸãã é·ããªããŸããããæåŸãŸã§ãèªã¿ããã ãããããšãããããŸããã åéã®äžèЧ | æ ªåŒäŒç€Ÿã¡ãã¬ãŒ ã¡ãã¬ãŒã®æ¡çšæ
å ±ã¯ãã¡ãããã確èªãã ããã www.medley.jp
ããã«ã¡ã¯ãå»çãã©ãããã©ãŒã æ¬éš/ãããã¯ãéçºå®€/第äžéçºã°ã«ãŒãæå±ã®äžåè¯ã§ãã ã¡ãã¬ãŒã«ã¯ 2018 幎ã®é ã«å
¥ç€ŸããŠãããä»å¹Žã§ 4 幎ç®ã«ãªããŸãã åœåã¯ãµãŒããŒãµã€ããäžå¿ã«éçºãæ
åœããŠããã®ã§ãããæè¿ã¯æ£è
ãšã³ã²ãŒãžã¡ã³ãããŒã ãšããæ£è
æ§ã«æäŸãããµãŒãã¹ãéçºããããŒã ã§äž»ã« iOS ã®ä»äºãæ
åœããããšãå€ãã§ãã ããŠå»å¹Žã® 12 æã«ãªããŸããã CLINICS ã¢ã㪠㯠UI ã®ãã«ãªãã¥ãŒã¢ã« ãè¡ããŸããã ä»åã¯ãªãã¥ãŒã¢ã«ã®è£è©± (iOS ã«ã€ããŠ) ãããŠãããããšæããŸãã ãããŸã§ã® CLINICS ã¢ããªã«ã€ã㊠æ¬é¡ãæžãåã«ãCLINICS ã¢ããªã®æŽå²ã玹ä»ããŸãã ãã¡ãŒã¹ãã³ããããèŠãŠã¿ããšãã¢ããªã®éçºã¯ 2016 幎 2 æããããã¹ã¿ãŒããããã¡ãŒã¹ããªãªãŒã¹ãè¡ãããã®ã 2016 幎 5 æã§ããã åœåãæ
åœããŠãããšã³ãžãã¢ã¯ iOS ã®çµéšãè±å¯ãªæ¹ã¯ããããå
šå¡ã§è©Šè¡é¯èª€ããªããéçºãé²ããŠããããã§ãã ãã°ããã®éã¯æ©èœã®è¿œå ãªã©ãè¡ãããŠããŸãããã CLINICS ã«ã«ã ã®éçºã«æ³šåããããã«å€§ããªéçºã¯ã¹ããããã Pharms ãšã®é£æºãéå§ããã 2020 幎 5 æé ãŸã§æ©èœãèšèšã«é¢ããèŠçŽããã»ãšãã©è¡ãããŠããŸããã§ããã iOS ã«è©³ãããšã³ãžãã¢ãããªãã£ãã«ãé¢ããããããªãã®ã¹ããŒãæã§ãªãªãŒã¹ããŠããããšã¯ãããã®éçºåãšããäžèšã«å°œããã®ã§ãããPharms ãšã®é£æºããè¬æåž³ãšãã£ãæ©èœã远å ãããããä»åŸã®éçºãèŠæ®ããéã«æ¢åæ©èœãèšèšã®èŠçŽããè¡ããããšæãããã«ãªã£ãŠããŸããã æ¹åãããéšåã¯ãããããã£ãã®ã§ããã察å¿å·¥æ°ãèžãŸãä»åã®ãªãã¥ãŒã¢ã«ã§ã¯ä»¥äžã® 2 ç¹ã®æ¹åã«æ³šåããããšã«ããŸããã Storyboard ã«ãã View ã®ç®¡ç View ãšããžãã¯ã®åé¢ ãã® 2 ç¹ã«ã€ããŠãããã詳ãã説æããŸãã 1. Storyboard ã«ãã View ã®ç®¡ç åŸæ¥ã®éçºã§ã¯ Storyboard ãå©çšã㊠View ãäœæããŠããŸããã Storyboard ã䜿ããšã¬ã€ã¢ãŠããç»é¢é·ç§»ãç°¡åã«å®è£
ããããšãã§ããŸãããéçºãç¶ããŠãããã¡ã«ä»¥äžã®ãããªåé¡ãç®ç«ã€ããã«ãªã£ãŠããŸããã Storyboard ã巚倧åããŠãããè€æ°äººéçºãè¡ãéã«æ¯éãã§ã ã¬ã€ã¢ãŠãã«è¿œå ã»å€æŽãè¡ãããå Žåã« AutoLayout ã®åèšå®ã«æéãããã ã³ã³ããŒãã³ãèªäœã«ãµã€ãºãèšå®ãããŠããããšããããã³ã³ããŒãã³ããåå©çšã§ããªãããšããã èª²é¡ ãã¡ãã¯å®éã«ãã£ã Storyboard ã®ãã£ããã£ã§ãããè€æ°ã®ç»é¢ã 1 ã€ã® Storyboard å
ã«è©°ã蟌ãŸããç¶æ
ãšãªã£ãŠããŸããã Storyboard 㯠Xcode ã®ããŒãžã§ã³ã«ãã埮åŠãªå·®åãçºçããŠããŸã£ãããAutoLayout ã®èª¿æŽãå¿
èŠã«ãªãå ŽåããããŸãã ãã¡ãã¯å€ã Storyboard ã®ç»é¢ãéããåŸã®å·®åãªã®ã§ããããã®å€æŽãã·ã¹ãã ã«ãã£ãŠå ãããã倿Žãªã®ããä»äººã®æ¹ä¿®ã«ãã倿Žãªã®ããåŸããèŠãæã«ãããã¥ãããšããåé¡ããããŸããã ä»®ã«åé¡ãçºçããå Žåã¯ä¿®æ£ã詊ã¿ãã®ã§ãããç¬èªã® XML ã«ãã£ãŠè¡šçŸãããŠãããããiOS ã®çµéšãæµ
ãåã«ãšã£ãŠã¯ä¿®æ£ãéåžžã«é£ããã£ãã§ãã ãŸããè€æ°äººã§äžŠè¡ããŠéçºããéã«ãã³ã³ããªã¯ããèµ·ãããããªã£ãŠããŸãè§£æ¶ã«æéãããããšããåé¡ãšãªã£ãŠããŸããã ããã«åŸæ¥ã® CLINICS ã¢ããªã¯ DLS ãå©çšããŠã¬ã€ã¢ãŠããäœæããŠããã®ã§ãããã³ã³ããŒãã³ãã«çŽæ¥ãµã€ãºãèšå®ãããŠãããã®ããããããç»é¢ã§ã¯åŸ®åŠã«ãµã€ãºã調æŽãããâŠãšãã£ãèŠä»¶ã«å¯Ÿå¿ã§ããããã£ããã®ã³ã³ããŒãã³ããåå©çšã§ããªãã±ãŒã¹ããããŸããã è§£æ±ºæ¡ èª²é¡ã«å¯Ÿãã解決æ¡ã¯è²ã
ãšèããããŸãããåŒç€Ÿã®éçºã¹ã¿ã€ã«ããšã³ãžãã¢ã®ã¹ãã«ãèæ
®ã以äžã®ãããªæ¹éãç«ãŠãŸããã Storyboard ãšåç»é¢ã®å®è£
㯠1 : 1 ã®é¢ä¿ãšãã ç»é¢é·ç§»ã®è²¬åã Storyboard ããåãé¢ã ã³ã³ããŒãã³ãã«ã¢ãããã¯ãã¶ã€ã³ãé©çšãã Storyboard ã®åå²ã¯ä»¥äžã®ãããªã¹ãããã§è¡ã£ãŠããŸããã Refactor to Storyboard ã䜿ã£ãŠå·šå€§ãª Storyboard ãåå²ãã SwiftGen ãå©çšãç»é¢çæã®ã³ãŒããèªåäœæãã 2 ã§çæãããã®ãå©çšããŠç»é¢é·ç§»ãè¡ã æ¢åã® Segue ãåé€ãã ãŸãæåã« Xcode 7 ããå©çšå¯èœãšãªã£ããRefactor to Storyboardãã䜿ã£ãŠç»é¢ãåå²ãããšããããå§ããŸãã ãã®æ©èœãå©çšãããšéžæãã View ãæ°ãã Storyboard ã«åãåºãããå
ã® Storyboard ã«ã¯åãåºãã Storyboard ãžã®ãªãã¡ã¬ã³ã¹ã Segue çã®æ¥ç¶ãä¿æãããç¶æ
ã«ãªããŸãã æ¬¡ã«åç»é¢éã®é·ç§»ã Segue ã䜿ããã«è¡ãããã«ããŸãã Segue ã¯äŸ¿å©ãªã®ã§ãããIdentifier ãåãªãæååã§ãã£ãããStoryboard ãåå²ããŠããªãã¡ã¬ã³ã¹ã¯ä¿æããŠããå¿
èŠãããç¹ã埮åŠã«æããŠããŸãå©çšããªãããšã«ããŸããã Segue ã䜿ããã«ç»é¢é·ç§»ãè¡ãå¿
èŠããããããç»é¢çæãšç»é¢é·ç§»ã®æ¹æ³ãèªåã§å®è£
ããå¿
èŠããããŸãã ä»åã¯ç»é¢çæã®åŠçã SwiftGen ãå©çšããŠèªåçæå¯èœã«ããVIPER ãšããã¢ãŒããã¯ãã£ã® Router ãåèã«ããŠç»é¢é·ç§»ã Storyboard ããåãé¢ãããšã«ããŸããã â» SwiftGen ã®å©ç𿹿³ã¯ SwiftGen#interface-builder ãåç
§ãã ããã Router ã®å®è£
ã¯ä»¥äžã®éãã§ãã å®è£
ããããããã³ã«ãé·ç§»å
ã® VC ã«ç¶æ¿ããç»é¢é·ç§»ã®ã³ãŒããåŒã³åºãã ãã§ç»é¢é·ç§»ãè¡ãããšãã§ããŸãã protocol ClinicWireframe : AnyObject { var viewController: UIViewController { get } func presentClinic ( clinicId : String ) func pushClinic ( clinicId : String ) } extension ClinicWireframe { func presentClinic ( clinicId : String ) { let vc = StoryboardScene. Clinic . initialScene . instantiate { ClinicViewController ( coder : $0 , isHeaderEnabled : true ) } let presenter = ClinicPresenter ( view : vc) presenter. setClinicId ( clinicId : clinicId) vc. inject ( presenter : presenter) vc. modalPresentationStyle = . pageSheet let nc = UINavigationController ( rootViewController : vc) viewController. present (nc, animated : true ) } func pushClinic ( clinicId : String ) { let vc = StoryboardScene. Clinic . initialScene . instantiate { ClinicViewController ( coder : $0 , isHeaderEnabled : false ) } let presenter = ClinicPresenter ( view : vc) presenter. setClinicId ( clinicId : clinicId) vc. inject ( presenter : presenter) viewController. navigationController ?. pushViewController (vc, animated : true ) } æåŸã«ã³ã³ããŒãã³ãã®èª¿æŽã«ã€ããŠã§ãããCLINICS ã¢ããªã§ã¯ã¢ãããã¯ãã¶ã€ã³ãç°¡ç¥åãã以äžã®ãããªåºæºã§ã³ã³ããŒãã³ããå®è£
ããŠããŸãã Block: UI ã®æå°åäœ (ä»ã® PJT ã«ãæã¡èŸŒããããªã¬ãã«ãŸã§åè§£ããããã®) Partial: CLINICS ã® PJT åºæã®ã³ã³ããŒãã³ã Layout: ãã«ãçšã®ã¢ãŒãã«ããšã©ãŒç»é¢ãªã©ä»ã®ç»é¢ããåŒã³åºãããããšã§åããŠæå³ããªãç»é¢ãªã© Page: å ViewController ãšããã«çŽã¥ã Storyboard ãã®ç®¡çæ¹æ³èªäœã¯ åŒç€Ÿã®å¥ãããã¯ãã®éçºãæ
åœããŠãããšã³ãžãã¢ã«ãã£ãŠèæ¡ããããã®ã§ãã åŒç€Ÿã§ã¯ãµãŒããŒã»ããã³ãåãéãŠãªãéçºãä»»ãããããšãå€ããå³å¯ãªã¢ãããã¯ãã¶ã€ã³ã ãšã³ã³ããŒãã³ãã®åé¡ã«å°ãããšãå€ãã£ããããã®ãããªç®¡çæ¹æ³ããšã£ãŠããããã§ãã ä»åã®ãªãã¥ãŒã¢ã«ã«éã㊠CLINICS ã¢ããªã§ããããåèã«ããããšã«ããŸããã ãããŸã§ DLS ãšããŠç®¡çãããŠããã³ã³ããŒãã³ã㯠Block ã§å®è£
ããªãããWidth / Height ãšãã£ããµã€ãºã®èšå®ãè¡ããªãããã«ããŸããã ãã®ããã«ã³ã³ããŒãã³ãã®å®è£
ã¬ãã«ãæç¢ºã«ããããšã§ãå®è£
ã«äžå®ã®æéãçãŸã䜿ãåãã®å¹ãã³ã³ããŒãã³ããäœæãããããªããŸããã 2. View ãšããžãã¯ã®åé¢ ã¹ããŒãéçºãæ±ããããèæ¯ãèãããšä»æ¹ã®ãªãããšã§ã¯ããã®ã§ãããåŸæ¥ã® CLINICS ã¢ããªã§ã¯ ViewController ã«ããžãã¯ãèšè¿°ãããŠãããä¿ã«ãã Fat ViewController ã®ç¶æ
ã«ãªã£ãŠããŸã£ãŠããŸããã Fat ViewController ã®åé¡ç¹ã«ã€ããŠã¯æ¢ã«ããŸããŸãªæ¹ãåãäžããŠããŸããã以äžã®éšåãåé¡ãšæããŠããŸãã UI ãšããžãã¯ãåé¢ãããŠããªãããããã¹ããæžãããšãé£ãã å¯èªæ§ãäœããªããã¡ ããžãã¯ãåãåºãããŠããªããã䌌ããããªå®è£
ãç¹åšããå Žåããã èª²é¡ ãã¡ãã¯å®éã«ãã£ã ViewController ã®äžéšã§ãã ãã®ã³ãŒãã«é¢ããŠã¯ä»¥äžã®éšåãåé¡ãšæããŠããŸããã éä¿¡åŠçã®åŒã³åºãã ViewController ã®è²¬åã«ãªã£ãŠããããš éä¿¡çµæãæŽåœ¢ããããžãã¯ã ViewController ã®è²¬åã«ãªã£ãŠããããš ç»é¢æç»ã®ããã® State 管çã ViewController ã®è²¬åã«ãªã£ãŠããããš è§£æ±ºæ¡ UI ãšããžãã¯ãåé¢ããããã®ææ³ã¯ããŸããŸãªãã®ããããŸãããåŒç€Ÿã®ã¢ããªã«ã¯ä»¥äžã®ãããªç¹åŸŽããããŸãã iOS 以å€ã«ãè€æ°ã®ãã©ãããã©ãŒã ããµããŒãããŠããããããã³ããšã³ãã§ä¿æããããŒã¿ãè€éãªããžãã¯èªäœã¯å°ãªã (ãµãŒããŒåŽã§ãªãã¹ãæ
ä¿ããŠãã) å®è£
æã QA æã«æããéåæã«ã€ããŠçްãããã£ã¬ã¯ã¿ãŒãšæã¡åãããããã®çµææ¬¡ç¬¬ã§ã¯ä»æ§ã倿Žããããšããã ããããèæ
®ãããšããããžã§ã¯ãã®æéçã«åæã®å°å
¥ã³ã¹ããäœããããŒã¿ãããŒãã·ã³ãã«ãªãã®ã«çããããšããããã«èãããŸãšãŸã£ãŠããŸããã ããããèæ
®ããCLINICS ã¢ããªã§ã¯ MVP ãšããã¢ãŒããã¯ãã£ãæ¡çšããããšã«ããŸããã ãã詳现ã«ã¯ MVP ã® Passive View æ¹åŒãæ¡çšããŠããã以äžã®ãããªåœ¢ã§å®è£
ããŠããŸãã View ã¯åºæ¬çã«ãã¹ãŠã®å
¥åã€ãã³ãã«å¯Ÿå¿ãã Presenter ã®åŠçãåŒã³åºã Presenter ã¯å
¥åã«å¿ããŠéä¿¡åŠçãªã©ã®å€éšèŠå ãšãªãåŠçãåŒã³åºããçµæãæŽåœ¢ãã ãã¬ãŒã³ããŒã·ã§ã³ããžãã¯ã®çµæãæç»ããããã« View ã«æç€ºãåºã View 㯠Presenter ã®æç€ºã«ãã£ãŠã®ã¿æç»åŠçãè¡ããèªèº«ãèµ·ç¹ãšããæç»åŠçã¯è¡ããªã Modelâviewâpresenter - Wikipedia æ¢ã« Router ã¯å°å
¥ããŠããããè€éãªåŠçãããŒãå®è£
ãããå Žå㯠Interactor ãå°å
¥ããã ãã§ VIPER ã¢ãŒããã¯ãã£ãžãšçºå±ãããããšãç°¡åã«ã§ããç¹ãé
åã§ããã CLINICS ã¢ããªã§ã® ViewController / Presenter ã®å®è£
ãç°¡åã«ãŸãšãããã®ã¯ä»¥äžã®ããã«ãªã£ãŠããŸãã final class ClinicViewController : UIViewController { private lazy var presenter: ClinicPresenterInput = { fatalError (âFailed to inject presenterâ) }() override func viewDidLoad () { super . viewDidLoad () presenter?. refresh () } func inject ( presenter : ClinicPresenterInput) { self . presenter = presenter } // ã¿ãããããéã«åŒã³åºã func onTapServiceCell ( _ service : ServiceEntity, isTelemedicine : Bool ) { presenter?. didTapServiceButton (service, isTelemedicine : isTelemedicine) } } // MARK: - ClinicPresenterOutput extension ClinicViewController : ClinicPresenterOutput { func reloadData ( clinic : ClinicEntity?) { clinicViewStore. clinic = clinic } func openCreateAppointmentView ( clinic : ClinicEntity, service : ServiceEntity, isTelemedicine : Bool ) // äºçŽãžé²ã } func showErrorAlert ( _ error : Error ) { // ãšã©ãŒè¡šç€ºãè¡ã } } protocol ClinicPresenterInput : AnyObject { func refresh () func didTapServiceButton ( _ service : ServiceEntity, isTelemedicine : Bool ) } protocol ClinicPresenterOutput : AnyObject { func reloadData ( clinic : ClinicEntity?) func openCreateAppointmentView ( clinic : ClinicEntity, service : ServiceEntity, isTelemedicine : Bool ) func showErrorAlert ( _ error : Error ) } final class ClinicPresenter { private let clinicRepository: ClinicRepository private var clinic: ClinicEntity? private var cancellables: Set <AnyCancellable> = . init () init ( view : ClinicPresenterOutput, container : DIContainer) { self . view = view clinicRepository = container. resolve () } private func reloadView () { view?. reloadData ( clinic : clinic) } } // MARK: - PresenterInput extension ClinicPresenter : ClinicPresenterInput { func refresh () { guard let clinicId = clinicId else { return } clinicRepository. getClinic ( clinicId : clinicId) . sink ( receiveCompletion : { [ weak self ] completion in guard let self = self else { return } guard case let . failure (error) = completion else { return } self . view ?. showErrorAlert (error) } }, receiveValue : { [ weak self ] response in guard let self = self else { return } self . clinic = response. data self . reloadView () } ) . store ( in : &cancellables) } func didTapServiceButton ( _ service : ClinicsServiceEntity, isTelemedicine : Bool ) { guard let clinic = clinic else { return } view?. openCreateAppointmentView ( clinic : clinic, service : service, isTelemedicine : isTelemedicine) } } ViewController ãš Presenter ã¯ä»¥äžã®ããã« Router ã®å
éšã§ DI ããããã«ããŠããŸãã protocol ClinicWireframe : AnyObject { var viewController: UIViewController { get } func pushClinic ( clinicId : String ) } extension ClinicWireframe { func pushClinic ( clinicId : String ) { let vc = StoryboardScene. Clinic . initialScene . instantiate { ClinicViewController ( coder : $0 , isHeaderEnabled : false ) } let presenter = ClinicPresenter ( view : vc, container : DIContainer ()) presenter. setClinicId ( clinicId : clinicId) vc. inject ( presenter : presenter) viewController. navigationController ?. pushViewController (vc, animated : true ) } } ããã«ãã£ãŠãããšããš ViewController ã«ãã£ãåŠçã¯ä»¥äžã®ããã«åé¢ãããŸããã ãŸããView ãš Presenter ã¯ã€ã³ã¿ãŒãã§ãŒã¹ãä»ããŠãããäºããç¥ããªããããå®è£
ã®äº€æãç°¡åã«ã§ããããã«ãªããŸããã Presenter ã亀æããããšã§ 1 ã€ã® View ã§å¥ã
ã®åŠçã衚çŸããããšãå¯èœãšãªã£ãããView ããã¹ãã³ãŒãã亀æããããšã§ Presenter ã®å
¥åºåå€ããã¹ãããããšãã§ããããã«ãªã£ãŠããŸãã ãŸãšã CLINICS ã¢ããªã¯æŽå²ã®ãããããžã§ã¯ãã§ãããä»åã®ãããžã§ã¯ããéã㊠UI ã ãã§ãªãè£åŽã®å®è£
ãå·æ°ããŠããŸãã 巚倧㪠Storyboard ãåè§£ããããšã§ã¡ã³ããããªãã£ãåäžããMVP (+ Router) ã®å°å
¥ã«ãã£ãŠ View ãšããžãã¯ã®äº€æãç°¡åã«ãªãããã¹ããªã©ã®å®è£
ãåãå
¥ãããããªããŸããã ãããã« ããã°ã®æ¬ç·šã«ã¯æžããªãã£ãã®ã§ãããä»åãªãã¥ãŒã¢ã«ãããç»é¢ã«é¢ããŠã¯ SwiftUI ãå©çšããŠãã«ã¹ã¯ã©ããã§å®è£
ããŠãããã Asset ã®ç®¡çæ¹æ³ã«ã€ããŠã倧ããªèŠçŽããè¡ããŸããã ãŸãã¢ãŒããã¯ãã£ã®éžå®ã«ããããã iOS ã¢ããªèšèšãã¿ãŒã³å
¥é ãã倧å€åèã«ãªããŸãããiOS ã®éçºãè¡ãæ¹ã¯ãã²äžèªããŠã»ãããšæããŸãã çŽå幎ã»ã©ããã£ã倧ããªãããžã§ã¯ãã§ããããæ£è
ãšã³ã²ãŒãžã¡ã³ãããŒã ã®ã¡ã³ããŒå
šå¡ã§åãçµã¿ç¡äºã«ãªãªãŒã¹ãŸã§æŒãçããããšãã§ããŸããããŸã ãŸã ææ¢ããªéšåããããŸãããä»åŸãæ£è
ããã«ãšã£ãŠããå®å¿ããŠäœ¿ãããµãŒãã¹ãšãªãããã«éçºãç¶ããŠãããã°ãšæã£ãŠããŸãã é·ããªããŸããããæåŸãŸã§ãèªã¿ããã ãããããšãããããŸããã åéã®äžèЧ | æ ªåŒäŒç€Ÿã¡ãã¬ãŒ ã¡ãã¬ãŒã®æ¡çšæ
å ±ã¯ãã¡ãããã確èªãã ããã www.medley.jp
ããã«ã¡ã¯ãå»çãã©ãããã©ãŒã æ¬éš/ãããã¯ãéçºå®€/第äžéçºã°ã«ãŒãæå±ã®äžåè¯ã§ãã ã¡ãã¬ãŒã«ã¯ 2018 幎ã®é ã«å
¥ç€ŸããŠãããä»å¹Žã§ 4 幎ç®ã«ãªããŸãã åœåã¯ãµãŒããŒãµã€ããäžå¿ã«éçºãæ
åœããŠããã®ã§ãããæè¿ã¯æ£è
ãšã³ã²ãŒãžã¡ã³ãããŒã ãšããæ£è
æ§ã«æäŸãããµãŒãã¹ãéçºããããŒã ã§äž»ã« iOS ã®ä»äºãæ
åœããããšãå€ãã§ãã ããŠå»å¹Žã® 12 æã«ãªããŸããã CLINICS ã¢ã㪠㯠UI ã®ãã«ãªãã¥ãŒã¢ã« ãè¡ããŸããã ä»åã¯ãªãã¥ãŒã¢ã«ã®è£è©± (iOS ã«ã€ããŠ) ãããŠãããããšæããŸãã ãããŸã§ã® CLINICS ã¢ããªã«ã€ã㊠æ¬é¡ãæžãåã«ãCLINICS ã¢ããªã®æŽå²ã玹ä»ããŸãã ãã¡ãŒã¹ãã³ããããèŠãŠã¿ããšãã¢ããªã®éçºã¯ 2016 幎 2 æããããã¹ã¿ãŒããããã¡ãŒã¹ããªãªãŒã¹ãè¡ãããã®ã 2016 幎 5 æã§ããã åœåãæ
åœããŠãããšã³ãžãã¢ã¯ iOS ã®çµéšãè±å¯ãªæ¹ã¯ããããå
šå¡ã§è©Šè¡é¯èª€ããªããéçºãé²ããŠããããã§ãã ãã°ããã®éã¯æ©èœã®è¿œå ãªã©ãè¡ãããŠããŸãããã CLINICS ã«ã«ã ã®éçºã«æ³šåããããã«å€§ããªéçºã¯ã¹ããããã Pharms ãšã®é£æºãéå§ããã 2020 幎 5 æé ãŸã§æ©èœãèšèšã«é¢ããèŠçŽããã»ãšãã©è¡ãããŠããŸããã§ããã iOS ã«è©³ãããšã³ãžãã¢ãããªãã£ãã«ãé¢ããããããªãã®ã¹ããŒãæã§ãªãªãŒã¹ããŠããããšã¯ãããã®éçºåãšããäžèšã«å°œããã®ã§ãããPharms ãšã®é£æºããè¬æåž³ãšãã£ãæ©èœã远å ãããããä»åŸã®éçºãèŠæ®ããéã«æ¢åæ©èœãèšèšã®èŠçŽããè¡ããããšæãããã«ãªã£ãŠããŸããã æ¹åãããéšåã¯ãããããã£ãã®ã§ããã察å¿å·¥æ°ãèžãŸãä»åã®ãªãã¥ãŒã¢ã«ã§ã¯ä»¥äžã® 2 ç¹ã®æ¹åã«æ³šåããããšã«ããŸããã Storyboard ã«ãã View ã®ç®¡ç View ãšããžãã¯ã®åé¢ ãã® 2 ç¹ã«ã€ããŠãããã詳ãã説æããŸãã 1. Storyboard ã«ãã View ã®ç®¡ç åŸæ¥ã®éçºã§ã¯ Storyboard ãå©çšã㊠View ãäœæããŠããŸããã Storyboard ã䜿ããšã¬ã€ã¢ãŠããç»é¢é·ç§»ãç°¡åã«å®è£
ããããšãã§ããŸãããéçºãç¶ããŠãããã¡ã«ä»¥äžã®ãããªåé¡ãç®ç«ã€ããã«ãªã£ãŠããŸããã Storyboard ã巚倧åããŠãããè€æ°äººéçºãè¡ãéã«æ¯éãã§ã ã¬ã€ã¢ãŠãã«è¿œå ã»å€æŽãè¡ãããå Žåã« AutoLayout ã®åèšå®ã«æéãããã ã³ã³ããŒãã³ãèªäœã«ãµã€ãºãèšå®ãããŠããããšããããã³ã³ããŒãã³ããåå©çšã§ããªãããšããã èª²é¡ ãã¡ãã¯å®éã«ãã£ã Storyboard ã®ãã£ããã£ã§ãããè€æ°ã®ç»é¢ã 1 ã€ã® Storyboard å
ã«è©°ã蟌ãŸããç¶æ
ãšãªã£ãŠããŸããã Storyboard 㯠Xcode ã®ããŒãžã§ã³ã«ãã埮åŠãªå·®åãçºçããŠããŸã£ãããAutoLayout ã®èª¿æŽãå¿
èŠã«ãªãå ŽåããããŸãã ãã¡ãã¯å€ã Storyboard ã®ç»é¢ãéããåŸã®å·®åãªã®ã§ããããã®å€æŽãã·ã¹ãã ã«ãã£ãŠå ãããã倿Žãªã®ããä»äººã®æ¹ä¿®ã«ãã倿Žãªã®ããåŸããèŠãæã«ãããã¥ãããšããåé¡ããããŸããã ä»®ã«åé¡ãçºçããå Žåã¯ä¿®æ£ã詊ã¿ãã®ã§ãããç¬èªã® XML ã«ãã£ãŠè¡šçŸãããŠãããããiOS ã®çµéšãæµ
ãåã«ãšã£ãŠã¯ä¿®æ£ãéåžžã«é£ããã£ãã§ãã ãŸããè€æ°äººã§äžŠè¡ããŠéçºããéã«ãã³ã³ããªã¯ããèµ·ãããããªã£ãŠããŸãè§£æ¶ã«æéãããããšããåé¡ãšãªã£ãŠããŸããã ããã«åŸæ¥ã® CLINICS ã¢ããªã¯ DLS ãå©çšããŠã¬ã€ã¢ãŠããäœæããŠããã®ã§ãããã³ã³ããŒãã³ãã«çŽæ¥ãµã€ãºãèšå®ãããŠãããã®ããããããç»é¢ã§ã¯åŸ®åŠã«ãµã€ãºã調æŽãããâŠãšãã£ãèŠä»¶ã«å¯Ÿå¿ã§ããããã£ããã®ã³ã³ããŒãã³ããåå©çšã§ããªãã±ãŒã¹ããããŸããã è§£æ±ºæ¡ èª²é¡ã«å¯Ÿãã解決æ¡ã¯è²ã
ãšèããããŸãããåŒç€Ÿã®éçºã¹ã¿ã€ã«ããšã³ãžãã¢ã®ã¹ãã«ãèæ
®ã以äžã®ãããªæ¹éãç«ãŠãŸããã Storyboard ãšåç»é¢ã®å®è£
㯠1 : 1 ã®é¢ä¿ãšãã ç»é¢é·ç§»ã®è²¬åã Storyboard ããåãé¢ã ã³ã³ããŒãã³ãã«ã¢ãããã¯ãã¶ã€ã³ãé©çšãã Storyboard ã®åå²ã¯ä»¥äžã®ãããªã¹ãããã§è¡ã£ãŠããŸããã Refactor to Storyboard ã䜿ã£ãŠå·šå€§ãª Storyboard ãåå²ãã SwiftGen ãå©çšãç»é¢çæã®ã³ãŒããèªåäœæãã 2 ã§çæãããã®ãå©çšããŠç»é¢é·ç§»ãè¡ã æ¢åã® Segue ãåé€ãã ãŸãæåã« Xcode 7 ããå©çšå¯èœãšãªã£ããRefactor to Storyboardãã䜿ã£ãŠç»é¢ãåå²ãããšããããå§ããŸãã ãã®æ©èœãå©çšãããšéžæãã View ãæ°ãã Storyboard ã«åãåºãããå
ã® Storyboard ã«ã¯åãåºãã Storyboard ãžã®ãªãã¡ã¬ã³ã¹ã Segue çã®æ¥ç¶ãä¿æãããç¶æ
ã«ãªããŸãã æ¬¡ã«åç»é¢éã®é·ç§»ã Segue ã䜿ããã«è¡ãããã«ããŸãã Segue ã¯äŸ¿å©ãªã®ã§ãããIdentifier ãåãªãæååã§ãã£ãããStoryboard ãåå²ããŠããªãã¡ã¬ã³ã¹ã¯ä¿æããŠããå¿
èŠãããç¹ã埮åŠã«æããŠããŸãå©çšããªãããšã«ããŸããã Segue ã䜿ããã«ç»é¢é·ç§»ãè¡ãå¿
èŠããããããç»é¢çæãšç»é¢é·ç§»ã®æ¹æ³ãèªåã§å®è£
ããå¿
èŠããããŸãã ä»åã¯ç»é¢çæã®åŠçã SwiftGen ãå©çšããŠèªåçæå¯èœã«ããVIPER ãšããã¢ãŒããã¯ãã£ã® Router ãåèã«ããŠç»é¢é·ç§»ã Storyboard ããåãé¢ãããšã«ããŸããã â» SwiftGen ã®å©ç𿹿³ã¯ SwiftGen#interface-builder ãåç
§ãã ããã Router ã®å®è£
ã¯ä»¥äžã®éãã§ãã å®è£
ããããããã³ã«ãé·ç§»å
ã® VC ã«ç¶æ¿ããç»é¢é·ç§»ã®ã³ãŒããåŒã³åºãã ãã§ç»é¢é·ç§»ãè¡ãããšãã§ããŸãã protocol ClinicWireframe : AnyObject { var viewController: UIViewController { get } func presentClinic ( clinicId : String ) func pushClinic ( clinicId : String ) } extension ClinicWireframe { func presentClinic ( clinicId : String ) { let vc = StoryboardScene. Clinic . initialScene . instantiate { ClinicViewController ( coder : $0 , isHeaderEnabled : true ) } let presenter = ClinicPresenter ( view : vc) presenter. setClinicId ( clinicId : clinicId) vc. inject ( presenter : presenter) vc. modalPresentationStyle = . pageSheet let nc = UINavigationController ( rootViewController : vc) viewController. present (nc, animated : true ) } func pushClinic ( clinicId : String ) { let vc = StoryboardScene. Clinic . initialScene . instantiate { ClinicViewController ( coder : $0 , isHeaderEnabled : false ) } let presenter = ClinicPresenter ( view : vc) presenter. setClinicId ( clinicId : clinicId) vc. inject ( presenter : presenter) viewController. navigationController ?. pushViewController (vc, animated : true ) } æåŸã«ã³ã³ããŒãã³ãã®èª¿æŽã«ã€ããŠã§ãããCLINICS ã¢ããªã§ã¯ã¢ãããã¯ãã¶ã€ã³ãç°¡ç¥åãã以äžã®ãããªåºæºã§ã³ã³ããŒãã³ããå®è£
ããŠããŸãã Block: UI ã®æå°åäœ (ä»ã® PJT ã«ãæã¡èŸŒããããªã¬ãã«ãŸã§åè§£ããããã®) Partial: CLINICS ã® PJT åºæã®ã³ã³ããŒãã³ã Layout: ãã«ãçšã®ã¢ãŒãã«ããšã©ãŒç»é¢ãªã©ä»ã®ç»é¢ããåŒã³åºãããããšã§åããŠæå³ããªãç»é¢ãªã© Page: å ViewController ãšããã«çŽã¥ã Storyboard ãã®ç®¡çæ¹æ³èªäœã¯ åŒç€Ÿã®å¥ãããã¯ãã®éçºãæ
åœããŠãããšã³ãžãã¢ã«ãã£ãŠèæ¡ããããã®ã§ãã åŒç€Ÿã§ã¯ãµãŒããŒã»ããã³ãåãéãŠãªãéçºãä»»ãããããšãå€ããå³å¯ãªã¢ãããã¯ãã¶ã€ã³ã ãšã³ã³ããŒãã³ãã®åé¡ã«å°ãããšãå€ãã£ããããã®ãããªç®¡çæ¹æ³ããšã£ãŠããããã§ãã ä»åã®ãªãã¥ãŒã¢ã«ã«éã㊠CLINICS ã¢ããªã§ããããåèã«ããããšã«ããŸããã ãããŸã§ DLS ãšããŠç®¡çãããŠããã³ã³ããŒãã³ã㯠Block ã§å®è£
ããªãããWidth / Height ãšãã£ããµã€ãºã®èšå®ãè¡ããªãããã«ããŸããã ãã®ããã«ã³ã³ããŒãã³ãã®å®è£
ã¬ãã«ãæç¢ºã«ããããšã§ãå®è£
ã«äžå®ã®æéãçãŸã䜿ãåãã®å¹ãã³ã³ããŒãã³ããäœæãããããªããŸããã 2. View ãšããžãã¯ã®åé¢ ã¹ããŒãéçºãæ±ããããèæ¯ãèãããšä»æ¹ã®ãªãããšã§ã¯ããã®ã§ãããåŸæ¥ã® CLINICS ã¢ããªã§ã¯ ViewController ã«ããžãã¯ãèšè¿°ãããŠãããä¿ã«ãã Fat ViewController ã®ç¶æ
ã«ãªã£ãŠããŸã£ãŠããŸããã Fat ViewController ã®åé¡ç¹ã«ã€ããŠã¯æ¢ã«ããŸããŸãªæ¹ãåãäžããŠããŸããã以äžã®éšåãåé¡ãšæããŠããŸãã UI ãšããžãã¯ãåé¢ãããŠããªãããããã¹ããæžãããšãé£ãã å¯èªæ§ãäœããªããã¡ ããžãã¯ãåãåºãããŠããªããã䌌ããããªå®è£
ãç¹åšããå Žåããã èª²é¡ ãã¡ãã¯å®éã«ãã£ã ViewController ã®äžéšã§ãã ãã®ã³ãŒãã«é¢ããŠã¯ä»¥äžã®éšåãåé¡ãšæããŠããŸããã éä¿¡åŠçã®åŒã³åºãã ViewController ã®è²¬åã«ãªã£ãŠããããš éä¿¡çµæãæŽåœ¢ããããžãã¯ã ViewController ã®è²¬åã«ãªã£ãŠããããš ç»é¢æç»ã®ããã® State 管çã ViewController ã®è²¬åã«ãªã£ãŠããããš è§£æ±ºæ¡ UI ãšããžãã¯ãåé¢ããããã®ææ³ã¯ããŸããŸãªãã®ããããŸãããåŒç€Ÿã®ã¢ããªã«ã¯ä»¥äžã®ãããªç¹åŸŽããããŸãã iOS 以å€ã«ãè€æ°ã®ãã©ãããã©ãŒã ããµããŒãããŠããããããã³ããšã³ãã§ä¿æããããŒã¿ãè€éãªããžãã¯èªäœã¯å°ãªã (ãµãŒããŒåŽã§ãªãã¹ãæ
ä¿ããŠãã) å®è£
æã QA æã«æããéåæã«ã€ããŠçްãããã£ã¬ã¯ã¿ãŒãšæã¡åãããããã®çµææ¬¡ç¬¬ã§ã¯ä»æ§ã倿Žããããšããã ããããèæ
®ãããšããããžã§ã¯ãã®æéçã«åæã®å°å
¥ã³ã¹ããäœããããŒã¿ãããŒãã·ã³ãã«ãªãã®ã«çããããšããããã«èãããŸãšãŸã£ãŠããŸããã ããããèæ
®ããCLINICS ã¢ããªã§ã¯ MVP ãšããã¢ãŒããã¯ãã£ãæ¡çšããããšã«ããŸããã ãã詳现ã«ã¯ MVP ã® Passive View æ¹åŒãæ¡çšããŠããã以äžã®ãããªåœ¢ã§å®è£
ããŠããŸãã View ã¯åºæ¬çã«ãã¹ãŠã®å
¥åã€ãã³ãã«å¯Ÿå¿ãã Presenter ã®åŠçãåŒã³åºã Presenter ã¯å
¥åã«å¿ããŠéä¿¡åŠçãªã©ã®å€éšèŠå ãšãªãåŠçãåŒã³åºããçµæãæŽåœ¢ãã ãã¬ãŒã³ããŒã·ã§ã³ããžãã¯ã®çµæãæç»ããããã« View ã«æç€ºãåºã View 㯠Presenter ã®æç€ºã«ãã£ãŠã®ã¿æç»åŠçãè¡ããèªèº«ãèµ·ç¹ãšããæç»åŠçã¯è¡ããªã Modelâviewâpresenter - Wikipedia æ¢ã« Router ã¯å°å
¥ããŠããããè€éãªåŠçãããŒãå®è£
ãããå Žå㯠Interactor ãå°å
¥ããã ãã§ VIPER ã¢ãŒããã¯ãã£ãžãšçºå±ãããããšãç°¡åã«ã§ããç¹ãé
åã§ããã CLINICS ã¢ããªã§ã® ViewController / Presenter ã®å®è£
ãç°¡åã«ãŸãšãããã®ã¯ä»¥äžã®ããã«ãªã£ãŠããŸãã final class ClinicViewController : UIViewController { private lazy var presenter: ClinicPresenterInput = { fatalError (âFailed to inject presenterâ) }() override func viewDidLoad () { super . viewDidLoad () presenter?. refresh () } func inject ( presenter : ClinicPresenterInput) { self . presenter = presenter } // ã¿ãããããéã«åŒã³åºã func onTapServiceCell ( _ service : ServiceEntity, isTelemedicine : Bool ) { presenter?. didTapServiceButton (service, isTelemedicine : isTelemedicine) } } // MARK: - ClinicPresenterOutput extension ClinicViewController : ClinicPresenterOutput { func reloadData ( clinic : ClinicEntity?) { clinicViewStore. clinic = clinic } func openCreateAppointmentView ( clinic : ClinicEntity, service : ServiceEntity, isTelemedicine : Bool ) // äºçŽãžé²ã } func showErrorAlert ( _ error : Error ) { // ãšã©ãŒè¡šç€ºãè¡ã } } protocol ClinicPresenterInput : AnyObject { func refresh () func didTapServiceButton ( _ service : ServiceEntity, isTelemedicine : Bool ) } protocol ClinicPresenterOutput : AnyObject { func reloadData ( clinic : ClinicEntity?) func openCreateAppointmentView ( clinic : ClinicEntity, service : ServiceEntity, isTelemedicine : Bool ) func showErrorAlert ( _ error : Error ) } final class ClinicPresenter { private let clinicRepository: ClinicRepository private var clinic: ClinicEntity? private var cancellables: Set <AnyCancellable> = . init () init ( view : ClinicPresenterOutput, container : DIContainer) { self . view = view clinicRepository = container. resolve () } private func reloadView () { view?. reloadData ( clinic : clinic) } } // MARK: - PresenterInput extension ClinicPresenter : ClinicPresenterInput { func refresh () { guard let clinicId = clinicId else { return } clinicRepository. getClinic ( clinicId : clinicId) . sink ( receiveCompletion : { [ weak self ] completion in guard let self = self else { return } guard case let . failure (error) = completion else { return } self . view ?. showErrorAlert (error) } }, receiveValue : { [ weak self ] response in guard let self = self else { return } self . clinic = response. data self . reloadView () } ) . store ( in : &cancellables) } func didTapServiceButton ( _ service : ClinicsServiceEntity, isTelemedicine : Bool ) { guard let clinic = clinic else { return } view?. openCreateAppointmentView ( clinic : clinic, service : service, isTelemedicine : isTelemedicine) } } ViewController ãš Presenter ã¯ä»¥äžã®ããã« Router ã®å
éšã§ DI ããããã«ããŠããŸãã protocol ClinicWireframe : AnyObject { var viewController: UIViewController { get } func pushClinic ( clinicId : String ) } extension ClinicWireframe { func pushClinic ( clinicId : String ) { let vc = StoryboardScene. Clinic . initialScene . instantiate { ClinicViewController ( coder : $0 , isHeaderEnabled : false ) } let presenter = ClinicPresenter ( view : vc, container : DIContainer ()) presenter. setClinicId ( clinicId : clinicId) vc. inject ( presenter : presenter) viewController. navigationController ?. pushViewController (vc, animated : true ) } } ããã«ãã£ãŠãããšããš ViewController ã«ãã£ãåŠçã¯ä»¥äžã®ããã«åé¢ãããŸããã ãŸããView ãš Presenter ã¯ã€ã³ã¿ãŒãã§ãŒã¹ãä»ããŠãããäºããç¥ããªããããå®è£
ã®äº€æãç°¡åã«ã§ããããã«ãªããŸããã Presenter ã亀æããããšã§ 1 ã€ã® View ã§å¥ã
ã®åŠçã衚çŸããããšãå¯èœãšãªã£ãããView ããã¹ãã³ãŒãã亀æããããšã§ Presenter ã®å
¥åºåå€ããã¹ãããããšãã§ããããã«ãªã£ãŠããŸãã ãŸãšã CLINICS ã¢ããªã¯æŽå²ã®ãããããžã§ã¯ãã§ãããä»åã®ãããžã§ã¯ããéã㊠UI ã ãã§ãªãè£åŽã®å®è£
ãå·æ°ããŠããŸãã 巚倧㪠Storyboard ãåè§£ããããšã§ã¡ã³ããããªãã£ãåäžããMVP (+ Router) ã®å°å
¥ã«ãã£ãŠ View ãšããžãã¯ã®äº€æãç°¡åã«ãªãããã¹ããªã©ã®å®è£
ãåãå
¥ãããããªããŸããã ãããã« ããã°ã®æ¬ç·šã«ã¯æžããªãã£ãã®ã§ãããä»åãªãã¥ãŒã¢ã«ãããç»é¢ã«é¢ããŠã¯ SwiftUI ãå©çšããŠãã«ã¹ã¯ã©ããã§å®è£
ããŠãããã Asset ã®ç®¡çæ¹æ³ã«ã€ããŠã倧ããªèŠçŽããè¡ããŸããã ãŸãã¢ãŒããã¯ãã£ã®éžå®ã«ããããã iOS ã¢ããªèšèšãã¿ãŒã³å
¥é ãã倧å€åèã«ãªããŸãããiOS ã®éçºãè¡ãæ¹ã¯ãã²äžèªããŠã»ãããšæããŸãã çŽå幎ã»ã©ããã£ã倧ããªãããžã§ã¯ãã§ããããæ£è
ãšã³ã²ãŒãžã¡ã³ãããŒã ã®ã¡ã³ããŒå
šå¡ã§åãçµã¿ç¡äºã«ãªãªãŒã¹ãŸã§æŒãçããããšãã§ããŸããããŸã ãŸã ææ¢ããªéšåããããŸãããä»åŸãæ£è
ããã«ãšã£ãŠããå®å¿ããŠäœ¿ãããµãŒãã¹ãšãªãããã«éçºãç¶ããŠãããã°ãšæã£ãŠããŸãã é·ããªããŸããããæåŸãŸã§ãèªã¿ããã ãããããšãããããŸããã åéã®äžèЧ | æ ªåŒäŒç€Ÿã¡ãã¬ãŒ ã¡ãã¬ãŒã®æ¡çšæ
å ±ã¯ãã¡ãããã確èªãã ããã www.medley.jp
ããã«ã¡ã¯ãå»çãã©ãããã©ãŒã æ¬éš/ãããã¯ãéçºå®€/第äžéçºã°ã«ãŒãæå±ã®äžåè¯ã§ãã ã¡ãã¬ãŒã«ã¯ 2018 幎ã®é ã«å
¥ç€ŸããŠãããä»å¹Žã§ 4 幎ç®ã«ãªããŸãã åœåã¯ãµãŒããŒãµã€ããäžå¿ã«éçºãæ
åœããŠããã®ã§ãããæè¿ã¯æ£è
ãšã³ã²ãŒãžã¡ã³ãããŒã ãšããæ£è
æ§ã«æäŸãããµãŒãã¹ãéçºããããŒã ã§äž»ã« iOS ã®ä»äºãæ
åœããããšãå€ãã§ãã ããŠå»å¹Žã® 12 æã«ãªããŸããã CLINICS ã¢ã㪠㯠UI ã®ãã«ãªãã¥ãŒã¢ã« ãè¡ããŸããã ä»åã¯ãªãã¥ãŒã¢ã«ã®è£è©± (iOS ã«ã€ããŠ) ãããŠãããããšæããŸãã ãããŸã§ã® CLINICS ã¢ããªã«ã€ã㊠æ¬é¡ãæžãåã«ãCLINICS ã¢ããªã®æŽå²ã玹ä»ããŸãã ãã¡ãŒã¹ãã³ããããèŠãŠã¿ããšãã¢ããªã®éçºã¯ 2016 幎 2 æããããã¹ã¿ãŒããããã¡ãŒã¹ããªãªãŒã¹ãè¡ãããã®ã 2016 幎 5 æã§ããã åœåãæ
åœããŠãããšã³ãžãã¢ã¯ iOS ã®çµéšãè±å¯ãªæ¹ã¯ããããå
šå¡ã§è©Šè¡é¯èª€ããªããéçºãé²ããŠããããã§ãã ãã°ããã®éã¯æ©èœã®è¿œå ãªã©ãè¡ãããŠããŸãããã CLINICS ã«ã«ã ã®éçºã«æ³šåããããã«å€§ããªéçºã¯ã¹ããããã Pharms ãšã®é£æºãéå§ããã 2020 幎 5 æé ãŸã§æ©èœãèšèšã«é¢ããèŠçŽããã»ãšãã©è¡ãããŠããŸããã§ããã iOS ã«è©³ãããšã³ãžãã¢ãããªãã£ãã«ãé¢ããããããªãã®ã¹ããŒãæã§ãªãªãŒã¹ããŠããããšã¯ãããã®éçºåãšããäžèšã«å°œããã®ã§ãããPharms ãšã®é£æºããè¬æåž³ãšãã£ãæ©èœã远å ãããããä»åŸã®éçºãèŠæ®ããéã«æ¢åæ©èœãèšèšã®èŠçŽããè¡ããããšæãããã«ãªã£ãŠããŸããã æ¹åãããéšåã¯ãããããã£ãã®ã§ããã察å¿å·¥æ°ãèžãŸãä»åã®ãªãã¥ãŒã¢ã«ã§ã¯ä»¥äžã® 2 ç¹ã®æ¹åã«æ³šåããããšã«ããŸããã Storyboard ã«ãã View ã®ç®¡ç View ãšããžãã¯ã®åé¢ ãã® 2 ç¹ã«ã€ããŠãããã詳ãã説æããŸãã 1. Storyboard ã«ãã View ã®ç®¡ç åŸæ¥ã®éçºã§ã¯ Storyboard ãå©çšã㊠View ãäœæããŠããŸããã Storyboard ã䜿ããšã¬ã€ã¢ãŠããç»é¢é·ç§»ãç°¡åã«å®è£
ããããšãã§ããŸãããéçºãç¶ããŠãããã¡ã«ä»¥äžã®ãããªåé¡ãç®ç«ã€ããã«ãªã£ãŠããŸããã Storyboard ã巚倧åããŠãããè€æ°äººéçºãè¡ãéã«æ¯éãã§ã ã¬ã€ã¢ãŠãã«è¿œå ã»å€æŽãè¡ãããå Žåã« AutoLayout ã®åèšå®ã«æéãããã ã³ã³ããŒãã³ãèªäœã«ãµã€ãºãèšå®ãããŠããããšããããã³ã³ããŒãã³ããåå©çšã§ããªãããšããã èª²é¡ ãã¡ãã¯å®éã«ãã£ã Storyboard ã®ãã£ããã£ã§ãããè€æ°ã®ç»é¢ã 1 ã€ã® Storyboard å
ã«è©°ã蟌ãŸããç¶æ
ãšãªã£ãŠããŸããã Storyboard 㯠Xcode ã®ããŒãžã§ã³ã«ãã埮åŠãªå·®åãçºçããŠããŸã£ãããAutoLayout ã®èª¿æŽãå¿
èŠã«ãªãå ŽåããããŸãã ãã¡ãã¯å€ã Storyboard ã®ç»é¢ãéããåŸã®å·®åãªã®ã§ããããã®å€æŽãã·ã¹ãã ã«ãã£ãŠå ãããã倿Žãªã®ããä»äººã®æ¹ä¿®ã«ãã倿Žãªã®ããåŸããèŠãæã«ãããã¥ãããšããåé¡ããããŸããã ä»®ã«åé¡ãçºçããå Žåã¯ä¿®æ£ã詊ã¿ãã®ã§ãããç¬èªã® XML ã«ãã£ãŠè¡šçŸãããŠãããããiOS ã®çµéšãæµ
ãåã«ãšã£ãŠã¯ä¿®æ£ãéåžžã«é£ããã£ãã§ãã ãŸããè€æ°äººã§äžŠè¡ããŠéçºããéã«ãã³ã³ããªã¯ããèµ·ãããããªã£ãŠããŸãè§£æ¶ã«æéãããããšããåé¡ãšãªã£ãŠããŸããã ããã«åŸæ¥ã® CLINICS ã¢ããªã¯ DLS ãå©çšããŠã¬ã€ã¢ãŠããäœæããŠããã®ã§ãããã³ã³ããŒãã³ãã«çŽæ¥ãµã€ãºãèšå®ãããŠãããã®ããããããç»é¢ã§ã¯åŸ®åŠã«ãµã€ãºã調æŽãããâŠãšãã£ãèŠä»¶ã«å¯Ÿå¿ã§ããããã£ããã®ã³ã³ããŒãã³ããåå©çšã§ããªãã±ãŒã¹ããããŸããã è§£æ±ºæ¡ èª²é¡ã«å¯Ÿãã解決æ¡ã¯è²ã
ãšèããããŸãããåŒç€Ÿã®éçºã¹ã¿ã€ã«ããšã³ãžãã¢ã®ã¹ãã«ãèæ
®ã以äžã®ãããªæ¹éãç«ãŠãŸããã Storyboard ãšåç»é¢ã®å®è£
㯠1 : 1 ã®é¢ä¿ãšãã ç»é¢é·ç§»ã®è²¬åã Storyboard ããåãé¢ã ã³ã³ããŒãã³ãã«ã¢ãããã¯ãã¶ã€ã³ãé©çšãã Storyboard ã®åå²ã¯ä»¥äžã®ãããªã¹ãããã§è¡ã£ãŠããŸããã Refactor to Storyboard ã䜿ã£ãŠå·šå€§ãª Storyboard ãåå²ãã SwiftGen ãå©çšãç»é¢çæã®ã³ãŒããèªåäœæãã 2 ã§çæãããã®ãå©çšããŠç»é¢é·ç§»ãè¡ã æ¢åã® Segue ãåé€ãã ãŸãæåã« Xcode 7 ããå©çšå¯èœãšãªã£ããRefactor to Storyboardãã䜿ã£ãŠç»é¢ãåå²ãããšããããå§ããŸãã ãã®æ©èœãå©çšãããšéžæãã View ãæ°ãã Storyboard ã«åãåºãããå
ã® Storyboard ã«ã¯åãåºãã Storyboard ãžã®ãªãã¡ã¬ã³ã¹ã Segue çã®æ¥ç¶ãä¿æãããç¶æ
ã«ãªããŸãã æ¬¡ã«åç»é¢éã®é·ç§»ã Segue ã䜿ããã«è¡ãããã«ããŸãã Segue ã¯äŸ¿å©ãªã®ã§ãããIdentifier ãåãªãæååã§ãã£ãããStoryboard ãåå²ããŠããªãã¡ã¬ã³ã¹ã¯ä¿æããŠããå¿
èŠãããç¹ã埮åŠã«æããŠããŸãå©çšããªãããšã«ããŸããã Segue ã䜿ããã«ç»é¢é·ç§»ãè¡ãå¿
èŠããããããç»é¢çæãšç»é¢é·ç§»ã®æ¹æ³ãèªåã§å®è£
ããå¿
èŠããããŸãã ä»åã¯ç»é¢çæã®åŠçã SwiftGen ãå©çšããŠèªåçæå¯èœã«ããVIPER ãšããã¢ãŒããã¯ãã£ã® Router ãåèã«ããŠç»é¢é·ç§»ã Storyboard ããåãé¢ãããšã«ããŸããã â» SwiftGen ã®å©ç𿹿³ã¯ SwiftGen#interface-builder ãåç
§ãã ããã Router ã®å®è£
ã¯ä»¥äžã®éãã§ãã å®è£
ããããããã³ã«ãé·ç§»å
ã® VC ã«ç¶æ¿ããç»é¢é·ç§»ã®ã³ãŒããåŒã³åºãã ãã§ç»é¢é·ç§»ãè¡ãããšãã§ããŸãã protocol ClinicWireframe : AnyObject { var viewController: UIViewController { get } func presentClinic ( clinicId : String ) func pushClinic ( clinicId : String ) } extension ClinicWireframe { func presentClinic ( clinicId : String ) { let vc = StoryboardScene. Clinic . initialScene . instantiate { ClinicViewController ( coder : $0 , isHeaderEnabled : true ) } let presenter = ClinicPresenter ( view : vc) presenter. setClinicId ( clinicId : clinicId) vc. inject ( presenter : presenter) vc. modalPresentationStyle = . pageSheet let nc = UINavigationController ( rootViewController : vc) viewController. present (nc, animated : true ) } func pushClinic ( clinicId : String ) { let vc = StoryboardScene. Clinic . initialScene . instantiate { ClinicViewController ( coder : $0 , isHeaderEnabled : false ) } let presenter = ClinicPresenter ( view : vc) presenter. setClinicId ( clinicId : clinicId) vc. inject ( presenter : presenter) viewController. navigationController ?. pushViewController (vc, animated : true ) } æåŸã«ã³ã³ããŒãã³ãã®èª¿æŽã«ã€ããŠã§ãããCLINICS ã¢ããªã§ã¯ã¢ãããã¯ãã¶ã€ã³ãç°¡ç¥åãã以äžã®ãããªåºæºã§ã³ã³ããŒãã³ããå®è£
ããŠããŸãã Block: UI ã®æå°åäœ (ä»ã® PJT ã«ãæã¡èŸŒããããªã¬ãã«ãŸã§åè§£ããããã®) Partial: CLINICS ã® PJT åºæã®ã³ã³ããŒãã³ã Layout: ãã«ãçšã®ã¢ãŒãã«ããšã©ãŒç»é¢ãªã©ä»ã®ç»é¢ããåŒã³åºãããããšã§åããŠæå³ããªãç»é¢ãªã© Page: å ViewController ãšããã«çŽã¥ã Storyboard ãã®ç®¡çæ¹æ³èªäœã¯ åŒç€Ÿã®å¥ãããã¯ãã®éçºãæ
åœããŠãããšã³ãžãã¢ã«ãã£ãŠèæ¡ããããã®ã§ãã åŒç€Ÿã§ã¯ãµãŒããŒã»ããã³ãåãéãŠãªãéçºãä»»ãããããšãå€ããå³å¯ãªã¢ãããã¯ãã¶ã€ã³ã ãšã³ã³ããŒãã³ãã®åé¡ã«å°ãããšãå€ãã£ããããã®ãããªç®¡çæ¹æ³ããšã£ãŠããããã§ãã ä»åã®ãªãã¥ãŒã¢ã«ã«éã㊠CLINICS ã¢ããªã§ããããåèã«ããããšã«ããŸããã ãããŸã§ DLS ãšããŠç®¡çãããŠããã³ã³ããŒãã³ã㯠Block ã§å®è£
ããªãããWidth / Height ãšãã£ããµã€ãºã®èšå®ãè¡ããªãããã«ããŸããã ãã®ããã«ã³ã³ããŒãã³ãã®å®è£
ã¬ãã«ãæç¢ºã«ããããšã§ãå®è£
ã«äžå®ã®æéãçãŸã䜿ãåãã®å¹ãã³ã³ããŒãã³ããäœæãããããªããŸããã 2. View ãšããžãã¯ã®åé¢ ã¹ããŒãéçºãæ±ããããèæ¯ãèãããšä»æ¹ã®ãªãããšã§ã¯ããã®ã§ãããåŸæ¥ã® CLINICS ã¢ããªã§ã¯ ViewController ã«ããžãã¯ãèšè¿°ãããŠãããä¿ã«ãã Fat ViewController ã®ç¶æ
ã«ãªã£ãŠããŸã£ãŠããŸããã Fat ViewController ã®åé¡ç¹ã«ã€ããŠã¯æ¢ã«ããŸããŸãªæ¹ãåãäžããŠããŸããã以äžã®éšåãåé¡ãšæããŠããŸãã UI ãšããžãã¯ãåé¢ãããŠããªãããããã¹ããæžãããšãé£ãã å¯èªæ§ãäœããªããã¡ ããžãã¯ãåãåºãããŠããªããã䌌ããããªå®è£
ãç¹åšããå Žåããã èª²é¡ ãã¡ãã¯å®éã«ãã£ã ViewController ã®äžéšã§ãã ãã®ã³ãŒãã«é¢ããŠã¯ä»¥äžã®éšåãåé¡ãšæããŠããŸããã éä¿¡åŠçã®åŒã³åºãã ViewController ã®è²¬åã«ãªã£ãŠããããš éä¿¡çµæãæŽåœ¢ããããžãã¯ã ViewController ã®è²¬åã«ãªã£ãŠããããš ç»é¢æç»ã®ããã® State 管çã ViewController ã®è²¬åã«ãªã£ãŠããããš è§£æ±ºæ¡ UI ãšããžãã¯ãåé¢ããããã®ææ³ã¯ããŸããŸãªãã®ããããŸãããåŒç€Ÿã®ã¢ããªã«ã¯ä»¥äžã®ãããªç¹åŸŽããããŸãã iOS 以å€ã«ãè€æ°ã®ãã©ãããã©ãŒã ããµããŒãããŠããããããã³ããšã³ãã§ä¿æããããŒã¿ãè€éãªããžãã¯èªäœã¯å°ãªã (ãµãŒããŒåŽã§ãªãã¹ãæ
ä¿ããŠãã) å®è£
æã QA æã«æããéåæã«ã€ããŠçްãããã£ã¬ã¯ã¿ãŒãšæã¡åãããããã®çµææ¬¡ç¬¬ã§ã¯ä»æ§ã倿Žããããšããã ããããèæ
®ãããšããããžã§ã¯ãã®æéçã«åæã®å°å
¥ã³ã¹ããäœããããŒã¿ãããŒãã·ã³ãã«ãªãã®ã«çããããšããããã«èãããŸãšãŸã£ãŠããŸããã ããããèæ
®ããCLINICS ã¢ããªã§ã¯ MVP ãšããã¢ãŒããã¯ãã£ãæ¡çšããããšã«ããŸããã ãã詳现ã«ã¯ MVP ã® Passive View æ¹åŒãæ¡çšããŠããã以äžã®ãããªåœ¢ã§å®è£
ããŠããŸãã View ã¯åºæ¬çã«ãã¹ãŠã®å
¥åã€ãã³ãã«å¯Ÿå¿ãã Presenter ã®åŠçãåŒã³åºã Presenter ã¯å
¥åã«å¿ããŠéä¿¡åŠçãªã©ã®å€éšèŠå ãšãªãåŠçãåŒã³åºããçµæãæŽåœ¢ãã ãã¬ãŒã³ããŒã·ã§ã³ããžãã¯ã®çµæãæç»ããããã« View ã«æç€ºãåºã View 㯠Presenter ã®æç€ºã«ãã£ãŠã®ã¿æç»åŠçãè¡ããèªèº«ãèµ·ç¹ãšããæç»åŠçã¯è¡ããªã Modelâviewâpresenter - Wikipedia æ¢ã« Router ã¯å°å
¥ããŠããããè€éãªåŠçãããŒãå®è£
ãããå Žå㯠Interactor ãå°å
¥ããã ãã§ VIPER ã¢ãŒããã¯ãã£ãžãšçºå±ãããããšãç°¡åã«ã§ããç¹ãé
åã§ããã CLINICS ã¢ããªã§ã® ViewController / Presenter ã®å®è£
ãç°¡åã«ãŸãšãããã®ã¯ä»¥äžã®ããã«ãªã£ãŠããŸãã final class ClinicViewController : UIViewController { private lazy var presenter: ClinicPresenterInput = { fatalError (âFailed to inject presenterâ) }() override func viewDidLoad () { super . viewDidLoad () presenter?. refresh () } func inject ( presenter : ClinicPresenterInput) { self . presenter = presenter } // ã¿ãããããéã«åŒã³åºã func onTapServiceCell ( _ service : ServiceEntity, isTelemedicine : Bool ) { presenter?. didTapServiceButton (service, isTelemedicine : isTelemedicine) } } // MARK: - ClinicPresenterOutput extension ClinicViewController : ClinicPresenterOutput { func reloadData ( clinic : ClinicEntity?) { clinicViewStore. clinic = clinic } func openCreateAppointmentView ( clinic : ClinicEntity, service : ServiceEntity, isTelemedicine : Bool ) // äºçŽãžé²ã } func showErrorAlert ( _ error : Error ) { // ãšã©ãŒè¡šç€ºãè¡ã } } protocol ClinicPresenterInput : AnyObject { func refresh () func didTapServiceButton ( _ service : ServiceEntity, isTelemedicine : Bool ) } protocol ClinicPresenterOutput : AnyObject { func reloadData ( clinic : ClinicEntity?) func openCreateAppointmentView ( clinic : ClinicEntity, service : ServiceEntity, isTelemedicine : Bool ) func showErrorAlert ( _ error : Error ) } final class ClinicPresenter { private let clinicRepository: ClinicRepository private var clinic: ClinicEntity? private var cancellables: Set <AnyCancellable> = . init () init ( view : ClinicPresenterOutput, container : DIContainer) { self . view = view clinicRepository = container. resolve () } private func reloadView () { view?. reloadData ( clinic : clinic) } } // MARK: - PresenterInput extension ClinicPresenter : ClinicPresenterInput { func refresh () { guard let clinicId = clinicId else { return } clinicRepository. getClinic ( clinicId : clinicId) . sink ( receiveCompletion : { [ weak self ] completion in guard let self = self else { return } guard case let . failure (error) = completion else { return } self . view ?. showErrorAlert (error) } }, receiveValue : { [ weak self ] response in guard let self = self else { return } self . clinic = response. data self . reloadView () } ) . store ( in : &cancellables) } func didTapServiceButton ( _ service : ClinicsServiceEntity, isTelemedicine : Bool ) { guard let clinic = clinic else { return } view?. openCreateAppointmentView ( clinic : clinic, service : service, isTelemedicine : isTelemedicine) } } ViewController ãš Presenter ã¯ä»¥äžã®ããã« Router ã®å
éšã§ DI ããããã«ããŠããŸãã protocol ClinicWireframe : AnyObject { var viewController: UIViewController { get } func pushClinic ( clinicId : String ) } extension ClinicWireframe { func pushClinic ( clinicId : String ) { let vc = StoryboardScene. Clinic . initialScene . instantiate { ClinicViewController ( coder : $0 , isHeaderEnabled : false ) } let presenter = ClinicPresenter ( view : vc, container : DIContainer ()) presenter. setClinicId ( clinicId : clinicId) vc. inject ( presenter : presenter) viewController. navigationController ?. pushViewController (vc, animated : true ) } } ããã«ãã£ãŠãããšããš ViewController ã«ãã£ãåŠçã¯ä»¥äžã®ããã«åé¢ãããŸããã ãŸããView ãš Presenter ã¯ã€ã³ã¿ãŒãã§ãŒã¹ãä»ããŠãããäºããç¥ããªããããå®è£
ã®äº€æãç°¡åã«ã§ããããã«ãªããŸããã Presenter ã亀æããããšã§ 1 ã€ã® View ã§å¥ã
ã®åŠçã衚çŸããããšãå¯èœãšãªã£ãããView ããã¹ãã³ãŒãã亀æããããšã§ Presenter ã®å
¥åºåå€ããã¹ãããããšãã§ããããã«ãªã£ãŠããŸãã ãŸãšã CLINICS ã¢ããªã¯æŽå²ã®ãããããžã§ã¯ãã§ãããä»åã®ãããžã§ã¯ããéã㊠UI ã ãã§ãªãè£åŽã®å®è£
ãå·æ°ããŠããŸãã 巚倧㪠Storyboard ãåè§£ããããšã§ã¡ã³ããããªãã£ãåäžããMVP (+ Router) ã®å°å
¥ã«ãã£ãŠ View ãšããžãã¯ã®äº€æãç°¡åã«ãªãããã¹ããªã©ã®å®è£
ãåãå
¥ãããããªããŸããã ãããã« ããã°ã®æ¬ç·šã«ã¯æžããªãã£ãã®ã§ãããä»åãªãã¥ãŒã¢ã«ãããç»é¢ã«é¢ããŠã¯ SwiftUI ãå©çšããŠãã«ã¹ã¯ã©ããã§å®è£
ããŠãããã Asset ã®ç®¡çæ¹æ³ã«ã€ããŠã倧ããªèŠçŽããè¡ããŸããã ãŸãã¢ãŒããã¯ãã£ã®éžå®ã«ããããã iOS ã¢ããªèšèšãã¿ãŒã³å
¥é ãã倧å€åèã«ãªããŸãããiOS ã®éçºãè¡ãæ¹ã¯ãã²äžèªããŠã»ãããšæããŸãã çŽå幎ã»ã©ããã£ã倧ããªãããžã§ã¯ãã§ããããæ£è
ãšã³ã²ãŒãžã¡ã³ãããŒã ã®ã¡ã³ããŒå
šå¡ã§åãçµã¿ç¡äºã«ãªãªãŒã¹ãŸã§æŒãçããããšãã§ããŸããããŸã ãŸã ææ¢ããªéšåããããŸãããä»åŸãæ£è
ããã«ãšã£ãŠããå®å¿ããŠäœ¿ãããµãŒãã¹ãšãªãããã«éçºãç¶ããŠãããã°ãšæã£ãŠããŸãã é·ããªããŸããããæåŸãŸã§ãèªã¿ããã ãããããšãããããŸããã https://www.medley.jp/jobs/
ããã«ã¡ã¯ãå»çãã©ãããã©ãŒã æ¬éš/ãããã¯ãéçºå®€/第äžéçºã°ã«ãŒãæå±ã®äžåè¯ã§ãã ã¡ãã¬ãŒã«ã¯ 2018 幎ã®é ã«å
¥ç€ŸããŠãããä»å¹Žã§ 4 幎ç®ã«ãªããŸãã åœåã¯ãµãŒããŒãµã€ããäžå¿ã«éçºãæ
åœããŠããã®ã§ãããæè¿ã¯æ£è
ãšã³ã²ãŒãžã¡ã³ãããŒã ãšããæ£è
æ§ã«æäŸãããµãŒãã¹ãéçºããããŒã ã§äž»ã« iOS ã®ä»äºãæ
åœããããšãå€ãã§ãã ããŠå»å¹Žã® 12 æã«ãªããŸããã CLINICS ã¢ã㪠㯠UI ã®ãã«ãªãã¥ãŒã¢ã« ãè¡ããŸããã ä»åã¯ãªãã¥ãŒã¢ã«ã®è£è©± (iOS ã«ã€ããŠ) ãããŠãããããšæããŸãã ãããŸã§ã® CLINICS ã¢ããªã«ã€ã㊠æ¬é¡ãæžãåã«ãCLINICS ã¢ããªã®æŽå²ã玹ä»ããŸãã ãã¡ãŒã¹ãã³ããããèŠãŠã¿ããšãã¢ããªã®éçºã¯ 2016 幎 2 æããããã¹ã¿ãŒããããã¡ãŒã¹ããªãªãŒã¹ãè¡ãããã®ã 2016 幎 5 æã§ããã åœåãæ
åœããŠãããšã³ãžãã¢ã¯ iOS ã®çµéšãè±å¯ãªæ¹ã¯ããããå
šå¡ã§è©Šè¡é¯èª€ããªããéçºãé²ããŠããããã§ãã ãã°ããã®éã¯æ©èœã®è¿œå ãªã©ãè¡ãããŠããŸãããã CLINICS ã«ã«ã ã®éçºã«æ³šåããããã«å€§ããªéçºã¯ã¹ããããã Pharms ãšã®é£æºãéå§ããã 2020 幎 5 æé ãŸã§æ©èœãèšèšã«é¢ããèŠçŽããã»ãšãã©è¡ãããŠããŸããã§ããã iOS ã«è©³ãããšã³ãžãã¢ãããªãã£ãã«ãé¢ããããããªãã®ã¹ããŒãæã§ãªãªãŒã¹ããŠããããšã¯ãããã®éçºåãšããäžèšã«å°œããã®ã§ãããPharms ãšã®é£æºããè¬æåž³ãšãã£ãæ©èœã远å ãããããä»åŸã®éçºãèŠæ®ããéã«æ¢åæ©èœãèšèšã®èŠçŽããè¡ããããšæãããã«ãªã£ãŠããŸããã æ¹åãããéšåã¯ãããããã£ãã®ã§ããã察å¿å·¥æ°ãèžãŸãä»åã®ãªãã¥ãŒã¢ã«ã§ã¯ä»¥äžã® 2 ç¹ã®æ¹åã«æ³šåããããšã«ããŸããã Storyboard ã«ãã View ã®ç®¡ç View ãšããžãã¯ã®åé¢ ãã® 2 ç¹ã«ã€ããŠãããã詳ãã説æããŸãã 1. Storyboard ã«ãã View ã®ç®¡ç åŸæ¥ã®éçºã§ã¯ Storyboard ãå©çšã㊠View ãäœæããŠããŸããã Storyboard ã䜿ããšã¬ã€ã¢ãŠããç»é¢é·ç§»ãç°¡åã«å®è£
ããããšãã§ããŸãããéçºãç¶ããŠãããã¡ã«ä»¥äžã®ãããªåé¡ãç®ç«ã€ããã«ãªã£ãŠããŸããã Storyboard ã巚倧åããŠãããè€æ°äººéçºãè¡ãéã«æ¯éãã§ã ã¬ã€ã¢ãŠãã«è¿œå ã»å€æŽãè¡ãããå Žåã« AutoLayout ã®åèšå®ã«æéãããã ã³ã³ããŒãã³ãèªäœã«ãµã€ãºãèšå®ãããŠããããšããããã³ã³ããŒãã³ããåå©çšã§ããªãããšããã èª²é¡ ãã¡ãã¯å®éã«ãã£ã Storyboard ã®ãã£ããã£ã§ãããè€æ°ã®ç»é¢ã 1 ã€ã® Storyboard å
ã«è©°ã蟌ãŸããç¶æ
ãšãªã£ãŠããŸããã Storyboard 㯠Xcode ã®ããŒãžã§ã³ã«ãã埮åŠãªå·®åãçºçããŠããŸã£ãããAutoLayout ã®èª¿æŽãå¿
èŠã«ãªãå ŽåããããŸãã ãã¡ãã¯å€ã Storyboard ã®ç»é¢ãéããåŸã®å·®åãªã®ã§ããããã®å€æŽãã·ã¹ãã ã«ãã£ãŠå ãããã倿Žãªã®ããä»äººã®æ¹ä¿®ã«ãã倿Žãªã®ããåŸããèŠãæã«ãããã¥ãããšããåé¡ããããŸããã ä»®ã«åé¡ãçºçããå Žåã¯ä¿®æ£ã詊ã¿ãã®ã§ãããç¬èªã® XML ã«ãã£ãŠè¡šçŸãããŠãããããiOS ã®çµéšãæµ
ãåã«ãšã£ãŠã¯ä¿®æ£ãéåžžã«é£ããã£ãã§ãã ãŸããè€æ°äººã§äžŠè¡ããŠéçºããéã«ãã³ã³ããªã¯ããèµ·ãããããªã£ãŠããŸãè§£æ¶ã«æéãããããšããåé¡ãšãªã£ãŠããŸããã ããã«åŸæ¥ã® CLINICS ã¢ããªã¯ DLS ãå©çšããŠã¬ã€ã¢ãŠããäœæããŠããã®ã§ãããã³ã³ããŒãã³ãã«çŽæ¥ãµã€ãºãèšå®ãããŠãããã®ããããããç»é¢ã§ã¯åŸ®åŠã«ãµã€ãºã調æŽãããâŠãšãã£ãèŠä»¶ã«å¯Ÿå¿ã§ããããã£ããã®ã³ã³ããŒãã³ããåå©çšã§ããªãã±ãŒã¹ããããŸããã è§£æ±ºæ¡ èª²é¡ã«å¯Ÿãã解決æ¡ã¯è²ã
ãšèããããŸãããåŒç€Ÿã®éçºã¹ã¿ã€ã«ããšã³ãžãã¢ã®ã¹ãã«ãèæ
®ã以äžã®ãããªæ¹éãç«ãŠãŸããã Storyboard ãšåç»é¢ã®å®è£
㯠1 : 1 ã®é¢ä¿ãšãã ç»é¢é·ç§»ã®è²¬åã Storyboard ããåãé¢ã ã³ã³ããŒãã³ãã«ã¢ãããã¯ãã¶ã€ã³ãé©çšãã Storyboard ã®åå²ã¯ä»¥äžã®ãããªã¹ãããã§è¡ã£ãŠããŸããã Refactor to Storyboard ã䜿ã£ãŠå·šå€§ãª Storyboard ãåå²ãã SwiftGen ãå©çšãç»é¢çæã®ã³ãŒããèªåäœæãã 2 ã§çæãããã®ãå©çšããŠç»é¢é·ç§»ãè¡ã æ¢åã® Segue ãåé€ãã ãŸãæåã« Xcode 7 ããå©çšå¯èœãšãªã£ããRefactor to Storyboardãã䜿ã£ãŠç»é¢ãåå²ãããšããããå§ããŸãã ãã®æ©èœãå©çšãããšéžæãã View ãæ°ãã Storyboard ã«åãåºãããå
ã® Storyboard ã«ã¯åãåºãã Storyboard ãžã®ãªãã¡ã¬ã³ã¹ã Segue çã®æ¥ç¶ãä¿æãããç¶æ
ã«ãªããŸãã æ¬¡ã«åç»é¢éã®é·ç§»ã Segue ã䜿ããã«è¡ãããã«ããŸãã Segue ã¯äŸ¿å©ãªã®ã§ãããIdentifier ãåãªãæååã§ãã£ãããStoryboard ãåå²ããŠããªãã¡ã¬ã³ã¹ã¯ä¿æããŠããå¿
èŠãããç¹ã埮åŠã«æããŠããŸãå©çšããªãããšã«ããŸããã Segue ã䜿ããã«ç»é¢é·ç§»ãè¡ãå¿
èŠããããããç»é¢çæãšç»é¢é·ç§»ã®æ¹æ³ãèªåã§å®è£
ããå¿
èŠããããŸãã ä»åã¯ç»é¢çæã®åŠçã SwiftGen ãå©çšããŠèªåçæå¯èœã«ããVIPER ãšããã¢ãŒããã¯ãã£ã® Router ãåèã«ããŠç»é¢é·ç§»ã Storyboard ããåãé¢ãããšã«ããŸããã â» SwiftGen ã®å©ç𿹿³ã¯ SwiftGen#interface-builder ãåç
§ãã ããã Router ã®å®è£
ã¯ä»¥äžã®éãã§ãã å®è£
ããããããã³ã«ãé·ç§»å
ã® VC ã«ç¶æ¿ããç»é¢é·ç§»ã®ã³ãŒããåŒã³åºãã ãã§ç»é¢é·ç§»ãè¡ãããšãã§ããŸãã protocol ClinicWireframe : AnyObject { var viewController: UIViewController { get } func presentClinic ( clinicId : String ) func pushClinic ( clinicId : String ) } extension ClinicWireframe { func presentClinic ( clinicId : String ) { let vc = StoryboardScene. Clinic . initialScene . instantiate { ClinicViewController ( coder : $0 , isHeaderEnabled : true ) } let presenter = ClinicPresenter ( view : vc) presenter. setClinicId ( clinicId : clinicId) vc. inject ( presenter : presenter) vc. modalPresentationStyle = . pageSheet let nc = UINavigationController ( rootViewController : vc) viewController. present (nc, animated : true ) } func pushClinic ( clinicId : String ) { let vc = StoryboardScene. Clinic . initialScene . instantiate { ClinicViewController ( coder : $0 , isHeaderEnabled : false ) } let presenter = ClinicPresenter ( view : vc) presenter. setClinicId ( clinicId : clinicId) vc. inject ( presenter : presenter) viewController. navigationController ?. pushViewController (vc, animated : true ) } æåŸã«ã³ã³ããŒãã³ãã®èª¿æŽã«ã€ããŠã§ãããCLINICS ã¢ããªã§ã¯ã¢ãããã¯ãã¶ã€ã³ãç°¡ç¥åãã以äžã®ãããªåºæºã§ã³ã³ããŒãã³ããå®è£
ããŠããŸãã Block: UI ã®æå°åäœ (ä»ã® PJT ã«ãæã¡èŸŒããããªã¬ãã«ãŸã§åè§£ããããã®) Partial: CLINICS ã® PJT åºæã®ã³ã³ããŒãã³ã Layout: ãã«ãçšã®ã¢ãŒãã«ããšã©ãŒç»é¢ãªã©ä»ã®ç»é¢ããåŒã³åºãããããšã§åããŠæå³ããªãç»é¢ãªã© Page: å ViewController ãšããã«çŽã¥ã Storyboard ãã®ç®¡çæ¹æ³èªäœã¯ åŒç€Ÿã®å¥ãããã¯ãã®éçºãæ
åœããŠãããšã³ãžãã¢ã«ãã£ãŠèæ¡ããããã®ã§ãã åŒç€Ÿã§ã¯ãµãŒããŒã»ããã³ãåãéãŠãªãéçºãä»»ãããããšãå€ããå³å¯ãªã¢ãããã¯ãã¶ã€ã³ã ãšã³ã³ããŒãã³ãã®åé¡ã«å°ãããšãå€ãã£ããããã®ãããªç®¡çæ¹æ³ããšã£ãŠããããã§ãã ä»åã®ãªãã¥ãŒã¢ã«ã«éã㊠CLINICS ã¢ããªã§ããããåèã«ããããšã«ããŸããã ãããŸã§ DLS ãšããŠç®¡çãããŠããã³ã³ããŒãã³ã㯠Block ã§å®è£
ããªãããWidth / Height ãšãã£ããµã€ãºã®èšå®ãè¡ããªãããã«ããŸããã ãã®ããã«ã³ã³ããŒãã³ãã®å®è£
ã¬ãã«ãæç¢ºã«ããããšã§ãå®è£
ã«äžå®ã®æéãçãŸã䜿ãåãã®å¹ãã³ã³ããŒãã³ããäœæãããããªããŸããã 2. View ãšããžãã¯ã®åé¢ ã¹ããŒãéçºãæ±ããããèæ¯ãèãããšä»æ¹ã®ãªãããšã§ã¯ããã®ã§ãããåŸæ¥ã® CLINICS ã¢ããªã§ã¯ ViewController ã«ããžãã¯ãèšè¿°ãããŠãããä¿ã«ãã Fat ViewController ã®ç¶æ
ã«ãªã£ãŠããŸã£ãŠããŸããã Fat ViewController ã®åé¡ç¹ã«ã€ããŠã¯æ¢ã«ããŸããŸãªæ¹ãåãäžããŠããŸããã以äžã®éšåãåé¡ãšæããŠããŸãã UI ãšããžãã¯ãåé¢ãããŠããªãããããã¹ããæžãããšãé£ãã å¯èªæ§ãäœããªããã¡ ããžãã¯ãåãåºãããŠããªããã䌌ããããªå®è£
ãç¹åšããå Žåããã èª²é¡ ãã¡ãã¯å®éã«ãã£ã ViewController ã®äžéšã§ãã ãã®ã³ãŒãã«é¢ããŠã¯ä»¥äžã®éšåãåé¡ãšæããŠããŸããã éä¿¡åŠçã®åŒã³åºãã ViewController ã®è²¬åã«ãªã£ãŠããããš éä¿¡çµæãæŽåœ¢ããããžãã¯ã ViewController ã®è²¬åã«ãªã£ãŠããããš ç»é¢æç»ã®ããã® State 管çã ViewController ã®è²¬åã«ãªã£ãŠããããš è§£æ±ºæ¡ UI ãšããžãã¯ãåé¢ããããã®ææ³ã¯ããŸããŸãªãã®ããããŸãããåŒç€Ÿã®ã¢ããªã«ã¯ä»¥äžã®ãããªç¹åŸŽããããŸãã iOS 以å€ã«ãè€æ°ã®ãã©ãããã©ãŒã ããµããŒãããŠããããããã³ããšã³ãã§ä¿æããããŒã¿ãè€éãªããžãã¯èªäœã¯å°ãªã (ãµãŒããŒåŽã§ãªãã¹ãæ
ä¿ããŠãã) å®è£
æã QA æã«æããéåæã«ã€ããŠçްãããã£ã¬ã¯ã¿ãŒãšæã¡åãããããã®çµææ¬¡ç¬¬ã§ã¯ä»æ§ã倿Žããããšããã ããããèæ
®ãããšããããžã§ã¯ãã®æéçã«åæã®å°å
¥ã³ã¹ããäœããããŒã¿ãããŒãã·ã³ãã«ãªãã®ã«çããããšããããã«èãããŸãšãŸã£ãŠããŸããã ããããèæ
®ããCLINICS ã¢ããªã§ã¯ MVP ãšããã¢ãŒããã¯ãã£ãæ¡çšããããšã«ããŸããã ãã詳现ã«ã¯ MVP ã® Passive View æ¹åŒãæ¡çšããŠããã以äžã®ãããªåœ¢ã§å®è£
ããŠããŸãã View ã¯åºæ¬çã«ãã¹ãŠã®å
¥åã€ãã³ãã«å¯Ÿå¿ãã Presenter ã®åŠçãåŒã³åºã Presenter ã¯å
¥åã«å¿ããŠéä¿¡åŠçãªã©ã®å€éšèŠå ãšãªãåŠçãåŒã³åºããçµæãæŽåœ¢ãã ãã¬ãŒã³ããŒã·ã§ã³ããžãã¯ã®çµæãæç»ããããã« View ã«æç€ºãåºã View 㯠Presenter ã®æç€ºã«ãã£ãŠã®ã¿æç»åŠçãè¡ããèªèº«ãèµ·ç¹ãšããæç»åŠçã¯è¡ããªã Modelâviewâpresenter - Wikipedia æ¢ã« Router ã¯å°å
¥ããŠããããè€éãªåŠçãããŒãå®è£
ãããå Žå㯠Interactor ãå°å
¥ããã ãã§ VIPER ã¢ãŒããã¯ãã£ãžãšçºå±ãããããšãç°¡åã«ã§ããç¹ãé
åã§ããã CLINICS ã¢ããªã§ã® ViewController / Presenter ã®å®è£
ãç°¡åã«ãŸãšãããã®ã¯ä»¥äžã®ããã«ãªã£ãŠããŸãã final class ClinicViewController : UIViewController { private lazy var presenter: ClinicPresenterInput = { fatalError (âFailed to inject presenterâ) }() override func viewDidLoad () { super . viewDidLoad () presenter?. refresh () } func inject ( presenter : ClinicPresenterInput) { self . presenter = presenter } // ã¿ãããããéã«åŒã³åºã func onTapServiceCell ( _ service : ServiceEntity, isTelemedicine : Bool ) { presenter?. didTapServiceButton (service, isTelemedicine : isTelemedicine) } } // MARK: - ClinicPresenterOutput extension ClinicViewController : ClinicPresenterOutput { func reloadData ( clinic : ClinicEntity?) { clinicViewStore. clinic = clinic } func openCreateAppointmentView ( clinic : ClinicEntity, service : ServiceEntity, isTelemedicine : Bool ) // äºçŽãžé²ã } func showErrorAlert ( _ error : Error ) { // ãšã©ãŒè¡šç€ºãè¡ã } } protocol ClinicPresenterInput : AnyObject { func refresh () func didTapServiceButton ( _ service : ServiceEntity, isTelemedicine : Bool ) } protocol ClinicPresenterOutput : AnyObject { func reloadData ( clinic : ClinicEntity?) func openCreateAppointmentView ( clinic : ClinicEntity, service : ServiceEntity, isTelemedicine : Bool ) func showErrorAlert ( _ error : Error ) } final class ClinicPresenter { private let clinicRepository: ClinicRepository private var clinic: ClinicEntity? private var cancellables: Set <AnyCancellable> = . init () init ( view : ClinicPresenterOutput, container : DIContainer) { self . view = view clinicRepository = container. resolve () } private func reloadView () { view?. reloadData ( clinic : clinic) } } // MARK: - PresenterInput extension ClinicPresenter : ClinicPresenterInput { func refresh () { guard let clinicId = clinicId else { return } clinicRepository. getClinic ( clinicId : clinicId) . sink ( receiveCompletion : { [ weak self ] completion in guard let self = self else { return } guard case let . failure (error) = completion else { return } self . view ?. showErrorAlert (error) } }, receiveValue : { [ weak self ] response in guard let self = self else { return } self . clinic = response. data self . reloadView () } ) . store ( in : &cancellables) } func didTapServiceButton ( _ service : ClinicsServiceEntity, isTelemedicine : Bool ) { guard let clinic = clinic else { return } view?. openCreateAppointmentView ( clinic : clinic, service : service, isTelemedicine : isTelemedicine) } } ViewController ãš Presenter ã¯ä»¥äžã®ããã« Router ã®å
éšã§ DI ããããã«ããŠããŸãã protocol ClinicWireframe : AnyObject { var viewController: UIViewController { get } func pushClinic ( clinicId : String ) } extension ClinicWireframe { func pushClinic ( clinicId : String ) { let vc = StoryboardScene. Clinic . initialScene . instantiate { ClinicViewController ( coder : $0 , isHeaderEnabled : false ) } let presenter = ClinicPresenter ( view : vc, container : DIContainer ()) presenter. setClinicId ( clinicId : clinicId) vc. inject ( presenter : presenter) viewController. navigationController ?. pushViewController (vc, animated : true ) } } ããã«ãã£ãŠãããšããš ViewController ã«ãã£ãåŠçã¯ä»¥äžã®ããã«åé¢ãããŸããã ãŸããView ãš Presenter ã¯ã€ã³ã¿ãŒãã§ãŒã¹ãä»ããŠãããäºããç¥ããªããããå®è£
ã®äº€æãç°¡åã«ã§ããããã«ãªããŸããã Presenter ã亀æããããšã§ 1 ã€ã® View ã§å¥ã
ã®åŠçã衚çŸããããšãå¯èœãšãªã£ãããView ããã¹ãã³ãŒãã亀æããããšã§ Presenter ã®å
¥åºåå€ããã¹ãããããšãã§ããããã«ãªã£ãŠããŸãã ãŸãšã CLINICS ã¢ããªã¯æŽå²ã®ãããããžã§ã¯ãã§ãããä»åã®ãããžã§ã¯ããéã㊠UI ã ãã§ãªãè£åŽã®å®è£
ãå·æ°ããŠããŸãã 巚倧㪠Storyboard ãåè§£ããããšã§ã¡ã³ããããªãã£ãåäžããMVP (+ Router) ã®å°å
¥ã«ãã£ãŠ View ãšããžãã¯ã®äº€æãç°¡åã«ãªãããã¹ããªã©ã®å®è£
ãåãå
¥ãããããªããŸããã ãããã« ããã°ã®æ¬ç·šã«ã¯æžããªãã£ãã®ã§ãããä»åãªãã¥ãŒã¢ã«ãããç»é¢ã«é¢ããŠã¯ SwiftUI ãå©çšããŠãã«ã¹ã¯ã©ããã§å®è£
ããŠãããã Asset ã®ç®¡çæ¹æ³ã«ã€ããŠã倧ããªèŠçŽããè¡ããŸããã ãŸãã¢ãŒããã¯ãã£ã®éžå®ã«ããããã iOS ã¢ããªèšèšãã¿ãŒã³å
¥é ãã倧å€åèã«ãªããŸãããiOS ã®éçºãè¡ãæ¹ã¯ãã²äžèªããŠã»ãããšæããŸãã çŽå幎ã»ã©ããã£ã倧ããªãããžã§ã¯ãã§ããããæ£è
ãšã³ã²ãŒãžã¡ã³ãããŒã ã®ã¡ã³ããŒå
šå¡ã§åãçµã¿ç¡äºã«ãªãªãŒã¹ãŸã§æŒãçããããšãã§ããŸããããŸã ãŸã ææ¢ããªéšåããããŸãããä»åŸãæ£è
ããã«ãšã£ãŠããå®å¿ããŠäœ¿ãããµãŒãã¹ãšãªãããã«éçºãç¶ããŠãããã°ãšæã£ãŠããŸãã é·ããªããŸããããæåŸãŸã§ãèªã¿ããã ãããããšãããããŸããã åéã®äžèЧ | æ ªåŒäŒç€Ÿã¡ãã¬ãŒ ã¡ãã¬ãŒã®æ¡çšæ
å ±ã¯ãã¡ãããã確èªãã ããã www.medley.jp
ããã«ã¡ã¯ãå»çãã©ãããã©ãŒã æ¬éš/ãããã¯ãéçºå®€/第äžéçºã°ã«ãŒãæå±ã®äžåè¯ã§ãã ã¡ãã¬ãŒã«ã¯ 2018 幎ã®é ã«å
¥ç€ŸããŠãããä»å¹Žã§ 4 幎ç®ã«ãªããŸãã åœåã¯ãµãŒããŒãµã€ããäžå¿ã«éçºãæ
åœããŠããã®ã§ãããæè¿ã¯æ£è
ãšã³ã²ãŒãžã¡ã³ãããŒã ãšããæ£è
æ§ã«æäŸãããµãŒãã¹ãéçºããããŒã ã§äž»ã« iOS ã®ä»äºãæ
åœããããšãå€ãã§ãã ããŠå»å¹Žã® 12 æã«ãªããŸããã CLINICS ã¢ã㪠㯠UI ã®ãã«ãªãã¥ãŒã¢ã« ãè¡ããŸããã ä»åã¯ãªãã¥ãŒã¢ã«ã®è£è©± (iOS ã«ã€ããŠ) ãããŠãããããšæããŸãã ãããŸã§ã® CLINICS ã¢ããªã«ã€ã㊠æ¬é¡ãæžãåã«ãCLINICS ã¢ããªã®æŽå²ã玹ä»ããŸãã ãã¡ãŒã¹ãã³ããããèŠãŠã¿ããšãã¢ããªã®éçºã¯ 2016 幎 2 æããããã¹ã¿ãŒããããã¡ãŒã¹ããªãªãŒã¹ãè¡ãããã®ã 2016 幎 5 æã§ããã åœåãæ
åœããŠãããšã³ãžãã¢ã¯ iOS ã®çµéšãè±å¯ãªæ¹ã¯ããããå
šå¡ã§è©Šè¡é¯èª€ããªããéçºãé²ããŠããããã§ãã ãã°ããã®éã¯æ©èœã®è¿œå ãªã©ãè¡ãããŠããŸãããã CLINICS ã«ã«ã ã®éçºã«æ³šåããããã«å€§ããªéçºã¯ã¹ããããã Pharms ãšã®é£æºãéå§ããã 2020 幎 5 æé ãŸã§æ©èœãèšèšã«é¢ããèŠçŽããã»ãšãã©è¡ãããŠããŸããã§ããã iOS ã«è©³ãããšã³ãžãã¢ãããªãã£ãã«ãé¢ããããããªãã®ã¹ããŒãæã§ãªãªãŒã¹ããŠããããšã¯ãããã®éçºåãšããäžèšã«å°œããã®ã§ãããPharms ãšã®é£æºããè¬æåž³ãšãã£ãæ©èœã远å ãããããä»åŸã®éçºãèŠæ®ããéã«æ¢åæ©èœãèšèšã®èŠçŽããè¡ããããšæãããã«ãªã£ãŠããŸããã æ¹åãããéšåã¯ãããããã£ãã®ã§ããã察å¿å·¥æ°ãèžãŸãä»åã®ãªãã¥ãŒã¢ã«ã§ã¯ä»¥äžã® 2 ç¹ã®æ¹åã«æ³šåããããšã«ããŸããã Storyboard ã«ãã View ã®ç®¡ç View ãšããžãã¯ã®åé¢ ãã® 2 ç¹ã«ã€ããŠãããã詳ãã説æããŸãã 1. Storyboard ã«ãã View ã®ç®¡ç åŸæ¥ã®éçºã§ã¯ Storyboard ãå©çšã㊠View ãäœæããŠããŸããã Storyboard ã䜿ããšã¬ã€ã¢ãŠããç»é¢é·ç§»ãç°¡åã«å®è£
ããããšãã§ããŸãããéçºãç¶ããŠãããã¡ã«ä»¥äžã®ãããªåé¡ãç®ç«ã€ããã«ãªã£ãŠããŸããã Storyboard ã巚倧åããŠãããè€æ°äººéçºãè¡ãéã«æ¯éãã§ã ã¬ã€ã¢ãŠãã«è¿œå ã»å€æŽãè¡ãããå Žåã« AutoLayout ã®åèšå®ã«æéãããã ã³ã³ããŒãã³ãèªäœã«ãµã€ãºãèšå®ãããŠããããšããããã³ã³ããŒãã³ããåå©çšã§ããªãããšããã èª²é¡ ãã¡ãã¯å®éã«ãã£ã Storyboard ã®ãã£ããã£ã§ãããè€æ°ã®ç»é¢ã 1 ã€ã® Storyboard å
ã«è©°ã蟌ãŸããç¶æ
ãšãªã£ãŠããŸããã Storyboard 㯠Xcode ã®ããŒãžã§ã³ã«ãã埮åŠãªå·®åãçºçããŠããŸã£ãããAutoLayout ã®èª¿æŽãå¿
èŠã«ãªãå ŽåããããŸãã ãã¡ãã¯å€ã Storyboard ã®ç»é¢ãéããåŸã®å·®åãªã®ã§ããããã®å€æŽãã·ã¹ãã ã«ãã£ãŠå ãããã倿Žãªã®ããä»äººã®æ¹ä¿®ã«ãã倿Žãªã®ããåŸããèŠãæã«ãããã¥ãããšããåé¡ããããŸããã ä»®ã«åé¡ãçºçããå Žåã¯ä¿®æ£ã詊ã¿ãã®ã§ãããç¬èªã® XML ã«ãã£ãŠè¡šçŸãããŠãããããiOS ã®çµéšãæµ
ãåã«ãšã£ãŠã¯ä¿®æ£ãéåžžã«é£ããã£ãã§ãã ãŸããè€æ°äººã§äžŠè¡ããŠéçºããéã«ãã³ã³ããªã¯ããèµ·ãããããªã£ãŠããŸãè§£æ¶ã«æéãããããšããåé¡ãšãªã£ãŠããŸããã ããã«åŸæ¥ã® CLINICS ã¢ããªã¯ DLS ãå©çšããŠã¬ã€ã¢ãŠããäœæããŠããã®ã§ãããã³ã³ããŒãã³ãã«çŽæ¥ãµã€ãºãèšå®ãããŠãããã®ããããããç»é¢ã§ã¯åŸ®åŠã«ãµã€ãºã調æŽãããâŠãšãã£ãèŠä»¶ã«å¯Ÿå¿ã§ããããã£ããã®ã³ã³ããŒãã³ããåå©çšã§ããªãã±ãŒã¹ããããŸããã è§£æ±ºæ¡ èª²é¡ã«å¯Ÿãã解決æ¡ã¯è²ã
ãšèããããŸãããåŒç€Ÿã®éçºã¹ã¿ã€ã«ããšã³ãžãã¢ã®ã¹ãã«ãèæ
®ã以äžã®ãããªæ¹éãç«ãŠãŸããã Storyboard ãšåç»é¢ã®å®è£
㯠1 : 1 ã®é¢ä¿ãšãã ç»é¢é·ç§»ã®è²¬åã Storyboard ããåãé¢ã ã³ã³ããŒãã³ãã«ã¢ãããã¯ãã¶ã€ã³ãé©çšãã Storyboard ã®åå²ã¯ä»¥äžã®ãããªã¹ãããã§è¡ã£ãŠããŸããã Refactor to Storyboard ã䜿ã£ãŠå·šå€§ãª Storyboard ãåå²ãã SwiftGen ãå©çšãç»é¢çæã®ã³ãŒããèªåäœæãã 2 ã§çæãããã®ãå©çšããŠç»é¢é·ç§»ãè¡ã æ¢åã® Segue ãåé€ãã ãŸãæåã« Xcode 7 ããå©çšå¯èœãšãªã£ããRefactor to Storyboardãã䜿ã£ãŠç»é¢ãåå²ãããšããããå§ããŸãã ãã®æ©èœãå©çšãããšéžæãã View ãæ°ãã Storyboard ã«åãåºãããå
ã® Storyboard ã«ã¯åãåºãã Storyboard ãžã®ãªãã¡ã¬ã³ã¹ã Segue çã®æ¥ç¶ãä¿æãããç¶æ
ã«ãªããŸãã æ¬¡ã«åç»é¢éã®é·ç§»ã Segue ã䜿ããã«è¡ãããã«ããŸãã Segue ã¯äŸ¿å©ãªã®ã§ãããIdentifier ãåãªãæååã§ãã£ãããStoryboard ãåå²ããŠããªãã¡ã¬ã³ã¹ã¯ä¿æããŠããå¿
èŠãããç¹ã埮åŠã«æããŠããŸãå©çšããªãããšã«ããŸããã Segue ã䜿ããã«ç»é¢é·ç§»ãè¡ãå¿
èŠããããããç»é¢çæãšç»é¢é·ç§»ã®æ¹æ³ãèªåã§å®è£
ããå¿
èŠããããŸãã ä»åã¯ç»é¢çæã®åŠçã SwiftGen ãå©çšããŠèªåçæå¯èœã«ããVIPER ãšããã¢ãŒããã¯ãã£ã® Router ãåèã«ããŠç»é¢é·ç§»ã Storyboard ããåãé¢ãããšã«ããŸããã â» SwiftGen ã®å©ç𿹿³ã¯ SwiftGen#interface-builder ãåç
§ãã ããã Router ã®å®è£
ã¯ä»¥äžã®éãã§ãã å®è£
ããããããã³ã«ãé·ç§»å
ã® VC ã«ç¶æ¿ããç»é¢é·ç§»ã®ã³ãŒããåŒã³åºãã ãã§ç»é¢é·ç§»ãè¡ãããšãã§ããŸãã protocol ClinicWireframe : AnyObject { var viewController: UIViewController { get } func presentClinic ( clinicId : String ) func pushClinic ( clinicId : String ) } extension ClinicWireframe { func presentClinic ( clinicId : String ) { let vc = StoryboardScene. Clinic . initialScene . instantiate { ClinicViewController ( coder : $0 , isHeaderEnabled : true ) } let presenter = ClinicPresenter ( view : vc) presenter. setClinicId ( clinicId : clinicId) vc. inject ( presenter : presenter) vc. modalPresentationStyle = . pageSheet let nc = UINavigationController ( rootViewController : vc) viewController. present (nc, animated : true ) } func pushClinic ( clinicId : String ) { let vc = StoryboardScene. Clinic . initialScene . instantiate { ClinicViewController ( coder : $0 , isHeaderEnabled : false ) } let presenter = ClinicPresenter ( view : vc) presenter. setClinicId ( clinicId : clinicId) vc. inject ( presenter : presenter) viewController. navigationController ?. pushViewController (vc, animated : true ) } æåŸã«ã³ã³ããŒãã³ãã®èª¿æŽã«ã€ããŠã§ãããCLINICS ã¢ããªã§ã¯ã¢ãããã¯ãã¶ã€ã³ãç°¡ç¥åãã以äžã®ãããªåºæºã§ã³ã³ããŒãã³ããå®è£
ããŠããŸãã Block: UI ã®æå°åäœ (ä»ã® PJT ã«ãæã¡èŸŒããããªã¬ãã«ãŸã§åè§£ããããã®) Partial: CLINICS ã® PJT åºæã®ã³ã³ããŒãã³ã Layout: ãã«ãçšã®ã¢ãŒãã«ããšã©ãŒç»é¢ãªã©ä»ã®ç»é¢ããåŒã³åºãããããšã§åããŠæå³ããªãç»é¢ãªã© Page: å ViewController ãšããã«çŽã¥ã Storyboard ãã®ç®¡çæ¹æ³èªäœã¯ åŒç€Ÿã®å¥ãããã¯ãã®éçºãæ
åœããŠãããšã³ãžãã¢ã«ãã£ãŠèæ¡ããããã®ã§ãã åŒç€Ÿã§ã¯ãµãŒããŒã»ããã³ãåãéãŠãªãéçºãä»»ãããããšãå€ããå³å¯ãªã¢ãããã¯ãã¶ã€ã³ã ãšã³ã³ããŒãã³ãã®åé¡ã«å°ãããšãå€ãã£ããããã®ãããªç®¡çæ¹æ³ããšã£ãŠããããã§ãã ä»åã®ãªãã¥ãŒã¢ã«ã«éã㊠CLINICS ã¢ããªã§ããããåèã«ããããšã«ããŸããã ãããŸã§ DLS ãšããŠç®¡çãããŠããã³ã³ããŒãã³ã㯠Block ã§å®è£
ããªãããWidth / Height ãšãã£ããµã€ãºã®èšå®ãè¡ããªãããã«ããŸããã ãã®ããã«ã³ã³ããŒãã³ãã®å®è£
ã¬ãã«ãæç¢ºã«ããããšã§ãå®è£
ã«äžå®ã®æéãçãŸã䜿ãåãã®å¹ãã³ã³ããŒãã³ããäœæãããããªããŸããã 2. View ãšããžãã¯ã®åé¢ ã¹ããŒãéçºãæ±ããããèæ¯ãèãããšä»æ¹ã®ãªãããšã§ã¯ããã®ã§ãããåŸæ¥ã® CLINICS ã¢ããªã§ã¯ ViewController ã«ããžãã¯ãèšè¿°ãããŠãããä¿ã«ãã Fat ViewController ã®ç¶æ
ã«ãªã£ãŠããŸã£ãŠããŸããã Fat ViewController ã®åé¡ç¹ã«ã€ããŠã¯æ¢ã«ããŸããŸãªæ¹ãåãäžããŠããŸããã以äžã®éšåãåé¡ãšæããŠããŸãã UI ãšããžãã¯ãåé¢ãããŠããªãããããã¹ããæžãããšãé£ãã å¯èªæ§ãäœããªããã¡ ããžãã¯ãåãåºãããŠããªããã䌌ããããªå®è£
ãç¹åšããå Žåããã èª²é¡ ãã¡ãã¯å®éã«ãã£ã ViewController ã®äžéšã§ãã ãã®ã³ãŒãã«é¢ããŠã¯ä»¥äžã®éšåãåé¡ãšæããŠããŸããã éä¿¡åŠçã®åŒã³åºãã ViewController ã®è²¬åã«ãªã£ãŠããããš éä¿¡çµæãæŽåœ¢ããããžãã¯ã ViewController ã®è²¬åã«ãªã£ãŠããããš ç»é¢æç»ã®ããã® State 管çã ViewController ã®è²¬åã«ãªã£ãŠããããš è§£æ±ºæ¡ UI ãšããžãã¯ãåé¢ããããã®ææ³ã¯ããŸããŸãªãã®ããããŸãããåŒç€Ÿã®ã¢ããªã«ã¯ä»¥äžã®ãããªç¹åŸŽããããŸãã iOS 以å€ã«ãè€æ°ã®ãã©ãããã©ãŒã ããµããŒãããŠããããããã³ããšã³ãã§ä¿æããããŒã¿ãè€éãªããžãã¯èªäœã¯å°ãªã (ãµãŒããŒåŽã§ãªãã¹ãæ
ä¿ããŠãã) å®è£
æã QA æã«æããéåæã«ã€ããŠçްãããã£ã¬ã¯ã¿ãŒãšæã¡åãããããã®çµææ¬¡ç¬¬ã§ã¯ä»æ§ã倿Žããããšããã ããããèæ
®ãããšããããžã§ã¯ãã®æéçã«åæã®å°å
¥ã³ã¹ããäœããããŒã¿ãããŒãã·ã³ãã«ãªãã®ã«çããããšããããã«èãããŸãšãŸã£ãŠããŸããã ããããèæ
®ããCLINICS ã¢ããªã§ã¯ MVP ãšããã¢ãŒããã¯ãã£ãæ¡çšããããšã«ããŸããã ãã詳现ã«ã¯ MVP ã® Passive View æ¹åŒãæ¡çšããŠããã以äžã®ãããªåœ¢ã§å®è£
ããŠããŸãã View ã¯åºæ¬çã«ãã¹ãŠã®å
¥åã€ãã³ãã«å¯Ÿå¿ãã Presenter ã®åŠçãåŒã³åºã Presenter ã¯å
¥åã«å¿ããŠéä¿¡åŠçãªã©ã®å€éšèŠå ãšãªãåŠçãåŒã³åºããçµæãæŽåœ¢ãã ãã¬ãŒã³ããŒã·ã§ã³ããžãã¯ã®çµæãæç»ããããã« View ã«æç€ºãåºã View 㯠Presenter ã®æç€ºã«ãã£ãŠã®ã¿æç»åŠçãè¡ããèªèº«ãèµ·ç¹ãšããæç»åŠçã¯è¡ããªã Modelâviewâpresenter - Wikipedia æ¢ã« Router ã¯å°å
¥ããŠããããè€éãªåŠçãããŒãå®è£
ãããå Žå㯠Interactor ãå°å
¥ããã ãã§ VIPER ã¢ãŒããã¯ãã£ãžãšçºå±ãããããšãç°¡åã«ã§ããç¹ãé
åã§ããã CLINICS ã¢ããªã§ã® ViewController / Presenter ã®å®è£
ãç°¡åã«ãŸãšãããã®ã¯ä»¥äžã®ããã«ãªã£ãŠããŸãã final class ClinicViewController : UIViewController { private lazy var presenter: ClinicPresenterInput = { fatalError (âFailed to inject presenterâ) }() override func viewDidLoad () { super . viewDidLoad () presenter?. refresh () } func inject ( presenter : ClinicPresenterInput) { self . presenter = presenter } // ã¿ãããããéã«åŒã³åºã func onTapServiceCell ( _ service : ServiceEntity, isTelemedicine : Bool ) { presenter?. didTapServiceButton (service, isTelemedicine : isTelemedicine) } } // MARK: - ClinicPresenterOutput extension ClinicViewController : ClinicPresenterOutput { func reloadData ( clinic : ClinicEntity?) { clinicViewStore. clinic = clinic } func openCreateAppointmentView ( clinic : ClinicEntity, service : ServiceEntity, isTelemedicine : Bool ) // äºçŽãžé²ã } func showErrorAlert ( _ error : Error ) { // ãšã©ãŒè¡šç€ºãè¡ã } } protocol ClinicPresenterInput : AnyObject { func refresh () func didTapServiceButton ( _ service : ServiceEntity, isTelemedicine : Bool ) } protocol ClinicPresenterOutput : AnyObject { func reloadData ( clinic : ClinicEntity?) func openCreateAppointmentView ( clinic : ClinicEntity, service : ServiceEntity, isTelemedicine : Bool ) func showErrorAlert ( _ error : Error ) } final class ClinicPresenter { private let clinicRepository: ClinicRepository private var clinic: ClinicEntity? private var cancellables: Set <AnyCancellable> = . init () init ( view : ClinicPresenterOutput, container : DIContainer) { self . view = view clinicRepository = container. resolve () } private func reloadView () { view?. reloadData ( clinic : clinic) } } // MARK: - PresenterInput extension ClinicPresenter : ClinicPresenterInput { func refresh () { guard let clinicId = clinicId else { return } clinicRepository. getClinic ( clinicId : clinicId) . sink ( receiveCompletion : { [ weak self ] completion in guard let self = self else { return } guard case let . failure (error) = completion else { return } self . view ?. showErrorAlert (error) } }, receiveValue : { [ weak self ] response in guard let self = self else { return } self . clinic = response. data self . reloadView () } ) . store ( in : &cancellables) } func didTapServiceButton ( _ service : ClinicsServiceEntity, isTelemedicine : Bool ) { guard let clinic = clinic else { return } view?. openCreateAppointmentView ( clinic : clinic, service : service, isTelemedicine : isTelemedicine) } } ViewController ãš Presenter ã¯ä»¥äžã®ããã« Router ã®å
éšã§ DI ããããã«ããŠããŸãã protocol ClinicWireframe : AnyObject { var viewController: UIViewController { get } func pushClinic ( clinicId : String ) } extension ClinicWireframe { func pushClinic ( clinicId : String ) { let vc = StoryboardScene. Clinic . initialScene . instantiate { ClinicViewController ( coder : $0 , isHeaderEnabled : false ) } let presenter = ClinicPresenter ( view : vc, container : DIContainer ()) presenter. setClinicId ( clinicId : clinicId) vc. inject ( presenter : presenter) viewController. navigationController ?. pushViewController (vc, animated : true ) } } ããã«ãã£ãŠãããšããš ViewController ã«ãã£ãåŠçã¯ä»¥äžã®ããã«åé¢ãããŸããã ãŸããView ãš Presenter ã¯ã€ã³ã¿ãŒãã§ãŒã¹ãä»ããŠãããäºããç¥ããªããããå®è£
ã®äº€æãç°¡åã«ã§ããããã«ãªããŸããã Presenter ã亀æããããšã§ 1 ã€ã® View ã§å¥ã
ã®åŠçã衚çŸããããšãå¯èœãšãªã£ãããView ããã¹ãã³ãŒãã亀æããããšã§ Presenter ã®å
¥åºåå€ããã¹ãããããšãã§ããããã«ãªã£ãŠããŸãã ãŸãšã CLINICS ã¢ããªã¯æŽå²ã®ãããããžã§ã¯ãã§ãããä»åã®ãããžã§ã¯ããéã㊠UI ã ãã§ãªãè£åŽã®å®è£
ãå·æ°ããŠããŸãã 巚倧㪠Storyboard ãåè§£ããããšã§ã¡ã³ããããªãã£ãåäžããMVP (+ Router) ã®å°å
¥ã«ãã£ãŠ View ãšããžãã¯ã®äº€æãç°¡åã«ãªãããã¹ããªã©ã®å®è£
ãåãå
¥ãããããªããŸããã ãããã« ããã°ã®æ¬ç·šã«ã¯æžããªãã£ãã®ã§ãããä»åãªãã¥ãŒã¢ã«ãããç»é¢ã«é¢ããŠã¯ SwiftUI ãå©çšããŠãã«ã¹ã¯ã©ããã§å®è£
ããŠãããã Asset ã®ç®¡çæ¹æ³ã«ã€ããŠã倧ããªèŠçŽããè¡ããŸããã ãŸãã¢ãŒããã¯ãã£ã®éžå®ã«ããããã iOS ã¢ããªèšèšãã¿ãŒã³å
¥é ãã倧å€åèã«ãªããŸãããiOS ã®éçºãè¡ãæ¹ã¯ãã²äžèªããŠã»ãããšæããŸãã çŽå幎ã»ã©ããã£ã倧ããªãããžã§ã¯ãã§ããããæ£è
ãšã³ã²ãŒãžã¡ã³ãããŒã ã®ã¡ã³ããŒå
šå¡ã§åãçµã¿ç¡äºã«ãªãªãŒã¹ãŸã§æŒãçããããšãã§ããŸããããŸã ãŸã ææ¢ããªéšåããããŸãããä»åŸãæ£è
ããã«ãšã£ãŠããå®å¿ããŠäœ¿ãããµãŒãã¹ãšãªãããã«éçºãç¶ããŠãããã°ãšæã£ãŠããŸãã é·ããªããŸããããæåŸãŸã§ãèªã¿ããã ãããããšãããããŸããã åéã®äžèЧ | æ ªåŒäŒç€Ÿã¡ãã¬ãŒ ã¡ãã¬ãŒã®æ¡çšæ
å ±ã¯ãã¡ãããã確èªãã ããã www.medley.jp
ããã«ã¡ã¯ãå»çãã©ãããã©ãŒã æ¬éš/ãããã¯ãéçºå®€/第äžéçºã°ã«ãŒãæå±ã®äžåè¯ã§ãã ã¡ãã¬ãŒã«ã¯ 2018 幎ã®é ã«å
¥ç€ŸããŠãããä»å¹Žã§ 4 幎ç®ã«ãªããŸãã åœåã¯ãµãŒããŒãµã€ããäžå¿ã«éçºãæ
åœããŠããã®ã§ãããæè¿ã¯æ£è
ãšã³ã²ãŒãžã¡ã³ãããŒã ãšããæ£è
æ§ã«æäŸãããµãŒãã¹ãéçºããããŒã ã§äž»ã« iOS ã®ä»äºãæ
åœããããšãå€ãã§ãã ããŠå»å¹Žã® 12 æã«ãªããŸããã CLINICS ã¢ã㪠㯠UI ã®ãã«ãªãã¥ãŒã¢ã« ãè¡ããŸããã ä»åã¯ãªãã¥ãŒã¢ã«ã®è£è©± (iOS ã«ã€ããŠ) ãããŠãããããšæããŸãã ãããŸã§ã® CLINICS ã¢ããªã«ã€ã㊠æ¬é¡ãæžãåã«ãCLINICS ã¢ããªã®æŽå²ã玹ä»ããŸãã ãã¡ãŒã¹ãã³ããããèŠãŠã¿ããšãã¢ããªã®éçºã¯ 2016 幎 2 æããããã¹ã¿ãŒããããã¡ãŒã¹ããªãªãŒã¹ãè¡ãããã®ã 2016 幎 5 æã§ããã åœåãæ
åœããŠãããšã³ãžãã¢ã¯ iOS ã®çµéšãè±å¯ãªæ¹ã¯ããããå
šå¡ã§è©Šè¡é¯èª€ããªããéçºãé²ããŠããããã§ãã ãã°ããã®éã¯æ©èœã®è¿œå ãªã©ãè¡ãããŠããŸãããã CLINICS ã«ã«ã ã®éçºã«æ³šåããããã«å€§ããªéçºã¯ã¹ããããã Pharms ãšã®é£æºãéå§ããã 2020 幎 5 æé ãŸã§æ©èœãèšèšã«é¢ããèŠçŽããã»ãšãã©è¡ãããŠããŸããã§ããã iOS ã«è©³ãããšã³ãžãã¢ãããªãã£ãã«ãé¢ããããããªãã®ã¹ããŒãæã§ãªãªãŒã¹ããŠããããšã¯ãããã®éçºåãšããäžèšã«å°œããã®ã§ãããPharms ãšã®é£æºããè¬æåž³ãšãã£ãæ©èœã远å ãããããä»åŸã®éçºãèŠæ®ããéã«æ¢åæ©èœãèšèšã®èŠçŽããè¡ããããšæãããã«ãªã£ãŠããŸããã æ¹åãããéšåã¯ãããããã£ãã®ã§ããã察å¿å·¥æ°ãèžãŸãä»åã®ãªãã¥ãŒã¢ã«ã§ã¯ä»¥äžã® 2 ç¹ã®æ¹åã«æ³šåããããšã«ããŸããã Storyboard ã«ãã View ã®ç®¡ç View ãšããžãã¯ã®åé¢ ãã® 2 ç¹ã«ã€ããŠãããã詳ãã説æããŸãã 1. Storyboard ã«ãã View ã®ç®¡ç åŸæ¥ã®éçºã§ã¯ Storyboard ãå©çšã㊠View ãäœæããŠããŸããã Storyboard ã䜿ããšã¬ã€ã¢ãŠããç»é¢é·ç§»ãç°¡åã«å®è£
ããããšãã§ããŸãããéçºãç¶ããŠãããã¡ã«ä»¥äžã®ãããªåé¡ãç®ç«ã€ããã«ãªã£ãŠããŸããã Storyboard ã巚倧åããŠãããè€æ°äººéçºãè¡ãéã«æ¯éãã§ã ã¬ã€ã¢ãŠãã«è¿œå ã»å€æŽãè¡ãããå Žåã« AutoLayout ã®åèšå®ã«æéãããã ã³ã³ããŒãã³ãèªäœã«ãµã€ãºãèšå®ãããŠããããšããããã³ã³ããŒãã³ããåå©çšã§ããªãããšããã èª²é¡ ãã¡ãã¯å®éã«ãã£ã Storyboard ã®ãã£ããã£ã§ãããè€æ°ã®ç»é¢ã 1 ã€ã® Storyboard å
ã«è©°ã蟌ãŸããç¶æ
ãšãªã£ãŠããŸããã Storyboard 㯠Xcode ã®ããŒãžã§ã³ã«ãã埮åŠãªå·®åãçºçããŠããŸã£ãããAutoLayout ã®èª¿æŽãå¿
èŠã«ãªãå ŽåããããŸãã ãã¡ãã¯å€ã Storyboard ã®ç»é¢ãéããåŸã®å·®åãªã®ã§ããããã®å€æŽãã·ã¹ãã ã«ãã£ãŠå ãããã倿Žãªã®ããä»äººã®æ¹ä¿®ã«ãã倿Žãªã®ããåŸããèŠãæã«ãããã¥ãããšããåé¡ããããŸããã ä»®ã«åé¡ãçºçããå Žåã¯ä¿®æ£ã詊ã¿ãã®ã§ãããç¬èªã® XML ã«ãã£ãŠè¡šçŸãããŠãããããiOS ã®çµéšãæµ
ãåã«ãšã£ãŠã¯ä¿®æ£ãéåžžã«é£ããã£ãã§ãã ãŸããè€æ°äººã§äžŠè¡ããŠéçºããéã«ãã³ã³ããªã¯ããèµ·ãããããªã£ãŠããŸãè§£æ¶ã«æéãããããšããåé¡ãšãªã£ãŠããŸããã ããã«åŸæ¥ã® CLINICS ã¢ããªã¯ DLS ãå©çšããŠã¬ã€ã¢ãŠããäœæããŠããã®ã§ãããã³ã³ããŒãã³ãã«çŽæ¥ãµã€ãºãèšå®ãããŠãããã®ããããããç»é¢ã§ã¯åŸ®åŠã«ãµã€ãºã調æŽãããâŠãšãã£ãèŠä»¶ã«å¯Ÿå¿ã§ããããã£ããã®ã³ã³ããŒãã³ããåå©çšã§ããªãã±ãŒã¹ããããŸããã è§£æ±ºæ¡ èª²é¡ã«å¯Ÿãã解決æ¡ã¯è²ã
ãšèããããŸãããåŒç€Ÿã®éçºã¹ã¿ã€ã«ããšã³ãžãã¢ã®ã¹ãã«ãèæ
®ã以äžã®ãããªæ¹éãç«ãŠãŸããã Storyboard ãšåç»é¢ã®å®è£
㯠1 : 1 ã®é¢ä¿ãšãã ç»é¢é·ç§»ã®è²¬åã Storyboard ããåãé¢ã ã³ã³ããŒãã³ãã«ã¢ãããã¯ãã¶ã€ã³ãé©çšãã Storyboard ã®åå²ã¯ä»¥äžã®ãããªã¹ãããã§è¡ã£ãŠããŸããã Refactor to Storyboard ã䜿ã£ãŠå·šå€§ãª Storyboard ãåå²ãã SwiftGen ãå©çšãç»é¢çæã®ã³ãŒããèªåäœæãã 2 ã§çæãããã®ãå©çšããŠç»é¢é·ç§»ãè¡ã æ¢åã® Segue ãåé€ãã ãŸãæåã« Xcode 7 ããå©çšå¯èœãšãªã£ããRefactor to Storyboardãã䜿ã£ãŠç»é¢ãåå²ãããšããããå§ããŸãã ãã®æ©èœãå©çšãããšéžæãã View ãæ°ãã Storyboard ã«åãåºãããå
ã® Storyboard ã«ã¯åãåºãã Storyboard ãžã®ãªãã¡ã¬ã³ã¹ã Segue çã®æ¥ç¶ãä¿æãããç¶æ
ã«ãªããŸãã æ¬¡ã«åç»é¢éã®é·ç§»ã Segue ã䜿ããã«è¡ãããã«ããŸãã Segue ã¯äŸ¿å©ãªã®ã§ãããIdentifier ãåãªãæååã§ãã£ãããStoryboard ãåå²ããŠããªãã¡ã¬ã³ã¹ã¯ä¿æããŠããå¿
èŠãããç¹ã埮åŠã«æããŠããŸãå©çšããªãããšã«ããŸããã Segue ã䜿ããã«ç»é¢é·ç§»ãè¡ãå¿
èŠããããããç»é¢çæãšç»é¢é·ç§»ã®æ¹æ³ãèªåã§å®è£
ããå¿
èŠããããŸãã ä»åã¯ç»é¢çæã®åŠçã SwiftGen ãå©çšããŠèªåçæå¯èœã«ããVIPER ãšããã¢ãŒããã¯ãã£ã® Router ãåèã«ããŠç»é¢é·ç§»ã Storyboard ããåãé¢ãããšã«ããŸããã â» SwiftGen ã®å©ç𿹿³ã¯ SwiftGen#interface-builder ãåç
§ãã ããã Router ã®å®è£
ã¯ä»¥äžã®éãã§ãã å®è£
ããããããã³ã«ãé·ç§»å
ã® VC ã«ç¶æ¿ããç»é¢é·ç§»ã®ã³ãŒããåŒã³åºãã ãã§ç»é¢é·ç§»ãè¡ãããšãã§ããŸãã protocol ClinicWireframe : AnyObject { var viewController: UIViewController { get } func presentClinic ( clinicId : String ) func pushClinic ( clinicId : String ) } extension ClinicWireframe { func presentClinic ( clinicId : String ) { let vc = StoryboardScene. Clinic . initialScene . instantiate { ClinicViewController ( coder : $0 , isHeaderEnabled : true ) } let presenter = ClinicPresenter ( view : vc) presenter. setClinicId ( clinicId : clinicId) vc. inject ( presenter : presenter) vc. modalPresentationStyle = . pageSheet let nc = UINavigationController ( rootViewController : vc) viewController. present (nc, animated : true ) } func pushClinic ( clinicId : String ) { let vc = StoryboardScene. Clinic . initialScene . instantiate { ClinicViewController ( coder : $0 , isHeaderEnabled : false ) } let presenter = ClinicPresenter ( view : vc) presenter. setClinicId ( clinicId : clinicId) vc. inject ( presenter : presenter) viewController. navigationController ?. pushViewController (vc, animated : true ) } æåŸã«ã³ã³ããŒãã³ãã®èª¿æŽã«ã€ããŠã§ãããCLINICS ã¢ããªã§ã¯ã¢ãããã¯ãã¶ã€ã³ãç°¡ç¥åãã以äžã®ãããªåºæºã§ã³ã³ããŒãã³ããå®è£
ããŠããŸãã Block: UI ã®æå°åäœ (ä»ã® PJT ã«ãæã¡èŸŒããããªã¬ãã«ãŸã§åè§£ããããã®) Partial: CLINICS ã® PJT åºæã®ã³ã³ããŒãã³ã Layout: ãã«ãçšã®ã¢ãŒãã«ããšã©ãŒç»é¢ãªã©ä»ã®ç»é¢ããåŒã³åºãããããšã§åããŠæå³ããªãç»é¢ãªã© Page: å ViewController ãšããã«çŽã¥ã Storyboard ãã®ç®¡çæ¹æ³èªäœã¯ åŒç€Ÿã®å¥ãããã¯ãã®éçºãæ
åœããŠãããšã³ãžãã¢ã«ãã£ãŠèæ¡ããããã®ã§ãã åŒç€Ÿã§ã¯ãµãŒããŒã»ããã³ãåãéãŠãªãéçºãä»»ãããããšãå€ããå³å¯ãªã¢ãããã¯ãã¶ã€ã³ã ãšã³ã³ããŒãã³ãã®åé¡ã«å°ãããšãå€ãã£ããããã®ãããªç®¡çæ¹æ³ããšã£ãŠããããã§ãã ä»åã®ãªãã¥ãŒã¢ã«ã«éã㊠CLINICS ã¢ããªã§ããããåèã«ããããšã«ããŸããã ãããŸã§ DLS ãšããŠç®¡çãããŠããã³ã³ããŒãã³ã㯠Block ã§å®è£
ããªãããWidth / Height ãšãã£ããµã€ãºã®èšå®ãè¡ããªãããã«ããŸããã ãã®ããã«ã³ã³ããŒãã³ãã®å®è£
ã¬ãã«ãæç¢ºã«ããããšã§ãå®è£
ã«äžå®ã®æéãçãŸã䜿ãåãã®å¹ãã³ã³ããŒãã³ããäœæãããããªããŸããã 2. View ãšããžãã¯ã®åé¢ ã¹ããŒãéçºãæ±ããããèæ¯ãèãããšä»æ¹ã®ãªãããšã§ã¯ããã®ã§ãããåŸæ¥ã® CLINICS ã¢ããªã§ã¯ ViewController ã«ããžãã¯ãèšè¿°ãããŠãããä¿ã«ãã Fat ViewController ã®ç¶æ
ã«ãªã£ãŠããŸã£ãŠããŸããã Fat ViewController ã®åé¡ç¹ã«ã€ããŠã¯æ¢ã«ããŸããŸãªæ¹ãåãäžããŠããŸããã以äžã®éšåãåé¡ãšæããŠããŸãã UI ãšããžãã¯ãåé¢ãããŠããªãããããã¹ããæžãããšãé£ãã å¯èªæ§ãäœããªããã¡ ããžãã¯ãåãåºãããŠããªããã䌌ããããªå®è£
ãç¹åšããå Žåããã èª²é¡ ãã¡ãã¯å®éã«ãã£ã ViewController ã®äžéšã§ãã ãã®ã³ãŒãã«é¢ããŠã¯ä»¥äžã®éšåãåé¡ãšæããŠããŸããã éä¿¡åŠçã®åŒã³åºãã ViewController ã®è²¬åã«ãªã£ãŠããããš éä¿¡çµæãæŽåœ¢ããããžãã¯ã ViewController ã®è²¬åã«ãªã£ãŠããããš ç»é¢æç»ã®ããã® State 管çã ViewController ã®è²¬åã«ãªã£ãŠããããš è§£æ±ºæ¡ UI ãšããžãã¯ãåé¢ããããã®ææ³ã¯ããŸããŸãªãã®ããããŸãããåŒç€Ÿã®ã¢ããªã«ã¯ä»¥äžã®ãããªç¹åŸŽããããŸãã iOS 以å€ã«ãè€æ°ã®ãã©ãããã©ãŒã ããµããŒãããŠããããããã³ããšã³ãã§ä¿æããããŒã¿ãè€éãªããžãã¯èªäœã¯å°ãªã (ãµãŒããŒåŽã§ãªãã¹ãæ
ä¿ããŠãã) å®è£
æã QA æã«æããéåæã«ã€ããŠçްãããã£ã¬ã¯ã¿ãŒãšæã¡åãããããã®çµææ¬¡ç¬¬ã§ã¯ä»æ§ã倿Žããããšããã ããããèæ
®ãããšããããžã§ã¯ãã®æéçã«åæã®å°å
¥ã³ã¹ããäœããããŒã¿ãããŒãã·ã³ãã«ãªãã®ã«çããããšããããã«èãããŸãšãŸã£ãŠããŸããã ããããèæ
®ããCLINICS ã¢ããªã§ã¯ MVP ãšããã¢ãŒããã¯ãã£ãæ¡çšããããšã«ããŸããã ãã詳现ã«ã¯ MVP ã® Passive View æ¹åŒãæ¡çšããŠããã以äžã®ãããªåœ¢ã§å®è£
ããŠããŸãã View ã¯åºæ¬çã«ãã¹ãŠã®å
¥åã€ãã³ãã«å¯Ÿå¿ãã Presenter ã®åŠçãåŒã³åºã Presenter ã¯å
¥åã«å¿ããŠéä¿¡åŠçãªã©ã®å€éšèŠå ãšãªãåŠçãåŒã³åºããçµæãæŽåœ¢ãã ãã¬ãŒã³ããŒã·ã§ã³ããžãã¯ã®çµæãæç»ããããã« View ã«æç€ºãåºã View 㯠Presenter ã®æç€ºã«ãã£ãŠã®ã¿æç»åŠçãè¡ããèªèº«ãèµ·ç¹ãšããæç»åŠçã¯è¡ããªã Modelâviewâpresenter - Wikipedia æ¢ã« Router ã¯å°å
¥ããŠããããè€éãªåŠçãããŒãå®è£
ãããå Žå㯠Interactor ãå°å
¥ããã ãã§ VIPER ã¢ãŒããã¯ãã£ãžãšçºå±ãããããšãç°¡åã«ã§ããç¹ãé
åã§ããã CLINICS ã¢ããªã§ã® ViewController / Presenter ã®å®è£
ãç°¡åã«ãŸãšãããã®ã¯ä»¥äžã®ããã«ãªã£ãŠããŸãã final class ClinicViewController : UIViewController { private lazy var presenter: ClinicPresenterInput = { fatalError (âFailed to inject presenterâ) }() override func viewDidLoad () { super . viewDidLoad () presenter?. refresh () } func inject ( presenter : ClinicPresenterInput) { self . presenter = presenter } // ã¿ãããããéã«åŒã³åºã func onTapServiceCell ( _ service : ServiceEntity, isTelemedicine : Bool ) { presenter?. didTapServiceButton (service, isTelemedicine : isTelemedicine) } } // MARK: - ClinicPresenterOutput extension ClinicViewController : ClinicPresenterOutput { func reloadData ( clinic : ClinicEntity?) { clinicViewStore. clinic = clinic } func openCreateAppointmentView ( clinic : ClinicEntity, service : ServiceEntity, isTelemedicine : Bool ) // äºçŽãžé²ã } func showErrorAlert ( _ error : Error ) { // ãšã©ãŒè¡šç€ºãè¡ã } } protocol ClinicPresenterInput : AnyObject { func refresh () func didTapServiceButton ( _ service : ServiceEntity, isTelemedicine : Bool ) } protocol ClinicPresenterOutput : AnyObject { func reloadData ( clinic : ClinicEntity?) func openCreateAppointmentView ( clinic : ClinicEntity, service : ServiceEntity, isTelemedicine : Bool ) func showErrorAlert ( _ error : Error ) } final class ClinicPresenter { private let clinicRepository: ClinicRepository private var clinic: ClinicEntity? private var cancellables: Set <AnyCancellable> = . init () init ( view : ClinicPresenterOutput, container : DIContainer) { self . view = view clinicRepository = container. resolve () } private func reloadView () { view?. reloadData ( clinic : clinic) } } // MARK: - PresenterInput extension ClinicPresenter : ClinicPresenterInput { func refresh () { guard let clinicId = clinicId else { return } clinicRepository. getClinic ( clinicId : clinicId) . sink ( receiveCompletion : { [ weak self ] completion in guard let self = self else { return } guard case let . failure (error) = completion else { return } self . view ?. showErrorAlert (error) } }, receiveValue : { [ weak self ] response in guard let self = self else { return } self . clinic = response. data self . reloadView () } ) . store ( in : &cancellables) } func didTapServiceButton ( _ service : ClinicsServiceEntity, isTelemedicine : Bool ) { guard let clinic = clinic else { return } view?. openCreateAppointmentView ( clinic : clinic, service : service, isTelemedicine : isTelemedicine) } } ViewController ãš Presenter ã¯ä»¥äžã®ããã« Router ã®å
éšã§ DI ããããã«ããŠããŸãã protocol ClinicWireframe : AnyObject { var viewController: UIViewController { get } func pushClinic ( clinicId : String ) } extension ClinicWireframe { func pushClinic ( clinicId : String ) { let vc = StoryboardScene. Clinic . initialScene . instantiate { ClinicViewController ( coder : $0 , isHeaderEnabled : false ) } let presenter = ClinicPresenter ( view : vc, container : DIContainer ()) presenter. setClinicId ( clinicId : clinicId) vc. inject ( presenter : presenter) viewController. navigationController ?. pushViewController (vc, animated : true ) } } ããã«ãã£ãŠãããšããš ViewController ã«ãã£ãåŠçã¯ä»¥äžã®ããã«åé¢ãããŸããã ãŸããView ãš Presenter ã¯ã€ã³ã¿ãŒãã§ãŒã¹ãä»ããŠãããäºããç¥ããªããããå®è£
ã®äº€æãç°¡åã«ã§ããããã«ãªããŸããã Presenter ã亀æããããšã§ 1 ã€ã® View ã§å¥ã
ã®åŠçã衚çŸããããšãå¯èœãšãªã£ãããView ããã¹ãã³ãŒãã亀æããããšã§ Presenter ã®å
¥åºåå€ããã¹ãããããšãã§ããããã«ãªã£ãŠããŸãã ãŸãšã CLINICS ã¢ããªã¯æŽå²ã®ãããããžã§ã¯ãã§ãããä»åã®ãããžã§ã¯ããéã㊠UI ã ãã§ãªãè£åŽã®å®è£
ãå·æ°ããŠããŸãã 巚倧㪠Storyboard ãåè§£ããããšã§ã¡ã³ããããªãã£ãåäžããMVP (+ Router) ã®å°å
¥ã«ãã£ãŠ View ãšããžãã¯ã®äº€æãç°¡åã«ãªãããã¹ããªã©ã®å®è£
ãåãå
¥ãããããªããŸããã ãããã« ããã°ã®æ¬ç·šã«ã¯æžããªãã£ãã®ã§ãããä»åãªãã¥ãŒã¢ã«ãããç»é¢ã«é¢ããŠã¯ SwiftUI ãå©çšããŠãã«ã¹ã¯ã©ããã§å®è£
ããŠãããã Asset ã®ç®¡çæ¹æ³ã«ã€ããŠã倧ããªèŠçŽããè¡ããŸããã ãŸãã¢ãŒããã¯ãã£ã®éžå®ã«ããããã iOS ã¢ããªèšèšãã¿ãŒã³å
¥é ãã倧å€åèã«ãªããŸãããiOS ã®éçºãè¡ãæ¹ã¯ãã²äžèªããŠã»ãããšæããŸãã çŽå幎ã»ã©ããã£ã倧ããªãããžã§ã¯ãã§ããããæ£è
ãšã³ã²ãŒãžã¡ã³ãããŒã ã®ã¡ã³ããŒå
šå¡ã§åãçµã¿ç¡äºã«ãªãªãŒã¹ãŸã§æŒãçããããšãã§ããŸããããŸã ãŸã ææ¢ããªéšåããããŸãããä»åŸãæ£è
ããã«ãšã£ãŠããå®å¿ããŠäœ¿ãããµãŒãã¹ãšãªãããã«éçºãç¶ããŠãããã°ãšæã£ãŠããŸãã é·ããªããŸããããæåŸãŸã§ãèªã¿ããã ãããããšãããããŸããã åéã®äžèЧ | æ ªåŒäŒç€Ÿã¡ãã¬ãŒ ã¡ãã¬ãŒã®æ¡çšæ
å ±ã¯ãã¡ãããã確èªãã ããã www.medley.jp