é ããæ©ãããè€éãªãããžã§ã¯ãã«ã¯å€éšãµãŒããŒãè¿œå ãããŸãã ãã ããçç±ã¯ãŸã£ããç°ãªããŸãã ãããã¯ãŒã¯ããè¿œå æ å ±ãããŠã³ããŒããããã®ãã¯ã©ã€ã¢ã³ãããã€ã¹éã§ããŒã¿ãåæãããã®ãã¢ããªã±ãŒã·ã§ã³å®è¡ããžãã¯ããµãŒããŒåŽã«è»¢éãããã®ããããŸãã ååãšããŠãåŸè ã«ã¯ã»ãšãã©ã®ãããžãã¹ãã¢ããªã±ãŒã·ã§ã³ãå«ãŸããŸãã ãã¹ãŠã®ã¢ã¯ã·ã§ã³ããœãŒã¹ã·ã¹ãã ã®ãã¬ãŒã ã¯ãŒã¯å ã§ã®ã¿å®è¡ãããããµã³ãããã¯ã¹ããã©ãã€ã ããé¢ãããšãããã»ã¹ã®ããžãã¯ã絡ã¿åãã絡ã¿åããããŒãã«ãã£ãŠçµã³ä»ãããããããã¢ããªã±ãŒã·ã§ã³ããã»ã¹ãžã®ãšã³ããªã®éå§ç¹ãç解ããããšãé£ãããªããŸãã ãã®æç¹ã§ãæåã®å Žæã¯ãã¢ããªã±ãŒã·ã§ã³èªäœã®æ©èœããããã£ã§ã¯ãªãããã®ã¢ãŒããã¯ãã£ã§ãããçµæãšããŠãæ¡åŒµæ§ã§ãã
æ·èšãããåºç€ã«ããã壮倧ãªå»ºç¯ã¢ã³ãµã³ãã«ããŸãã¯ãããŒããïŒé¶è¶³ã®å°å±ïŒãäœæã§ããŸããé¶ã®è¶³ã®å°å±ã¯ããã®ååšäžã«ãç®ã«èŠããªãããã«èŠããŸããå ã®ãããžã§ã¯ãã§ã¯ãªãããã«ããŒã®ããŒã ã
èšç»ã¯ãããžã§ã¯ãã®æåã®éµã§ãããæå°æéã¯é¡§å®¢ã«ãã£ãŠå²ãåœãŠãããŸãã ãã¿ãŒã³ãæ§ç¯ããããš-éçºè ã®ã¹ãªãŒãã®ãšãŒã¹ã§ãããæéãäžå©ãªå Žåã«å¥œãŸãããªãçµã¿åãããã«ããŒããããšãã決å®çãªèŠå ã§ããããšãå€æããŸããã åºç€ãšãªãå®çšçãªãœãªã¥ãŒã·ã§ã³ã䜿çšãããšã顧客ã«æãé¢é£ããããšæãããã¿ã¹ã¯ïŒãŸã 建èšãããŠããªãå±æ ¹ã«ç çªãã€ããå¡è£ ãããªã©ïŒã«é²ãããã®ã¯ã€ãã¯ã¹ã¿ãŒããå¯èœã«ãªããŸãã
ãã®èšäºã§ã¯ãã¢ãã€ã«ããã€ã¹åãã®ã¹ã±ãŒã©ãã«ãªã·ã¹ãã ãæ§ç¯ããã¯ã©ã€ã¢ã³ããµãŒããŒã¢ããªã±ãŒã·ã§ã³ã®90ã95ïŒ ãã«ããŒããç§è·¡ã®ããã€ããšããžãããã®æ倧è·é¢ãæäŸããåçã説æããŸãã
ãã®èšäºã®ä»äžãã«åãçµãã§ããéã«ãåæ§ã®èšäºãããã§å ¬éãããŸããïŒ http://habrahabr.ru/company/redmadrobot/blog/246551/ ïŒã ç§ã¯èè ã®ãã¹ãŠã®ã¢ã¯ã»ã³ãã«åæããŸããããäžè¬çã«ãç§ã®ããžã§ã³ã¯ããã«æ瀺ãããè³æãšççŸããã亀差ããŸããã èªè ã¯ãã©ã®ã¢ãããŒããããæè»ã§é¢é£æ§ãé«ãããå€æã§ããŸãã
ãµãŒããŒåŽããã®ã¯ã©ã€ã¢ã³ããµãŒããŒã€ã³ã¿ã©ã¯ã·ã§ã³ã®äžè¬çãªæ§é ã¯æ¬¡ã®ãšããã§ãã
ããã§ã¯ã2ã€ã®ããšãç解ããããšãéèŠã§ãã
- 1ã€ã®ã¢ã«ãŠã³ãã䜿çšããŠåãšéä¿¡ããå€ãã®ã¯ã©ã€ã¢ã³ããååšããå ŽåããããŸãã
- ååãšããŠãåã¯ã©ã€ã¢ã³ãã«ã¯ç¬èªã®ããŒã«ã«ã¹ãã¬ãŒãžããããŸãã *
*å Žåã«ãã£ãŠã¯ãããŒã«ã«ã¹ãã¬ãŒãžãã¯ã©ãŠããšåæããããã«å¿ããŠåã¯ã©ã€ã¢ã³ããšåæã§ããŸãã ããã¯ç¹æ®ãªã±ãŒã¹ã§ãããã»ãšãã©ã®å Žåãã¢ããªã±ãŒã·ã§ã³ã®ã¢ãŒããã¯ãã£ã«åœ±é¿ãäžããªããããçç¥ããŸãã
äžéšã®éçºè ã¯ããµãŒããŒåŽããæé€ããããšããŠãããããäžéšã®ã¢ããªã±ãŒã·ã§ã³ã¯ãã¯ã©ãŠããå ã®ã¹ãã¬ãŒãžã®åæãäžå¿ã«æ§ç¯ãããŠããããšã«æ³šæããŠãã ããã ã€ãŸããå®éã«ã¯ã2ãªã³ã¯ã·ã¹ãã ããããŸãããå±éã®ã¢ãŒããã¯ãã£ããªãã¬ãŒãã£ã³ã°ã·ã¹ãã ã®ã¬ãã«ã«ç§»è¡ããŠããŸãã å Žåã«ãã£ãŠã¯ããã®ãããªæ§é ã¯æ£åœåãããŸããããã®ãããªã·ã¹ãã ã¯ããã»ã©ç°¡åã«ã¹ã±ãŒãªã³ã°ãããããã®æ©èœã¯éåžžã«å¶éãããŸãã
äžè¬çãªã¢ããªã±ãŒã·ã§ã³æ§é
æãåºæ¬çãªæœè±¡åã¬ãã«ã§ã¯ããµãŒããŒæåã¢ããªã±ãŒã·ã§ã³ã¯æ¬¡ã®ã¢ãŒããã¯ãã£å±€ã§æ§æãããŸãã
- ã¢ããªã±ãŒã·ã§ã³ã®ã³ã¢ããŠãŒã¶ãŒãšã®å¯Ÿè©±ã«ã¯äœ¿çšã§ããªãã·ã¹ãã ã³ã³ããŒãã³ããå«ãŸããŸãã
- ã°ã©ãã£ã«ã«ãŠãŒã¶ãŒã€ã³ã¿ãŒãã§ã€ã¹
- ã³ã³ããŒãã³ãã®åå©çšïŒã©ã€ãã©ãªãããžã¥ã¢ã«ã³ã³ããŒãã³ããªã©ã
- ç°å¢ãã¡ã€ã«ïŒAppDelegateã.plistãªã©
- ã¢ããªã±ãŒã·ã§ã³ãªãœãŒã¹ïŒã°ã©ãã£ãã¯ãã¡ã€ã«ããµãŠã³ããå¿ èŠãªãã€ããªãã¡ã€ã«ã
ã¹ãã¬ã¹ã«åŒ·ãã¢ãŒããã¯ãã£ãæ§ç¯ããããã®æãéèŠãªæ¡ä»¶ã¯ãã·ã¹ãã ã³ã¢ãGUIããåé¢ããäžæ¹ãä»æ¹ãªãã§æ£åžžã«æ©èœã§ããããã«ããããšã§ãã äžæ¹ãã»ãšãã©ã®RADã·ã¹ãã ã¯å察ã®ã¡ãã»ãŒãžããæ¥ãŠããŸã-åã¯ã·ã¹ãã ã®éªšæ Œã圢æããæ©èœã¯çèãæ§ç¯ããŸãã ååãšããŠãããã¯ã¢ããªã±ãŒã·ã§ã³ããã®ã€ã³ã¿ãŒãã§ãŒã¹ã«ãã£ãŠå¶éãããªãããšãæå³ããŸãã ãŸããã€ã³ã¿ãŒãã§ã€ã¹ã¯ããŠãŒã¶ãŒã®èŠ³ç¹ãšã¯ã©ã¹éå±€ã®èŠ³ç¹ã®äž¡æ¹ããæ確ãªè§£éãè¡ããŸãã
ã³ã¢
ã¢ããªã±ãŒã·ã§ã³ã®ã³ã¢ã¯ã次ã®ã¬ã€ã€ãŒã§æ§æãããŠããŸãã
- ïŒéå§å±€ïŒããã°ã©ã å®è¡ã®éå§ã®ã¯ãŒã¯ãããŒãå®çŸ©ããéå§å±€ã
- ïŒãããã¯ãŒã¯å±€ïŒãã©ã³ã¹ããŒãçžäºäœçšã®ã¡ã«ããºã ãæäŸãããããã¯ãŒã¯å±€ã
- ïŒAPIã¬ã€ã€ãŒïŒã¯ã©ã€ã¢ã³ããšãµãŒããŒéã®å¯Ÿè©±ã®ããã®ã³ãã³ãã®çµ±äžã·ã¹ãã ãæäŸããAPIã¬ã€ã€ãŒã
- ïŒãããã¯ãŒã¯ãã£ãã·ã¥ã¬ã€ã€ãŒïŒã¯ã©ã€ã¢ã³ããšãµãŒããŒã®ãããã¯ãŒã¯çžäºäœçšãå éãããããã¯ãŒã¯ãã£ãã·ã¥ã¬ã€ã€ãŒã
- ïŒæ€èšŒé ç®ã¬ã€ã€ãŒïŒãããã¯ãŒã¯æ€èšŒã¬ã€ã€ãŒ
- ïŒãããã¯ãŒã¯ã¢ã€ãã ã¬ã€ã€ãŒïŒãããã¯ãŒã¯çµç±ã§éä¿¡ãããããŒã¿ãšã³ãã£ãã£ã®ã¬ã€ã€ãŒ
- ïŒããŒã¿ã¢ãã«ïŒããŒã¿ãšã³ãã£ãã£ã®çžäºäœçšãå¯èœã«ããããŒã¿ã¢ãã«ã
- ïŒããŒã«ã«ãã£ãã·ã¥ã¬ã€ã€ãŒïŒæ¢ã«åä¿¡ãããããã¯ãŒã¯ãªãœãŒã¹ãžã®ããŒã«ã«ã¢ã¯ã»ã¹ãæäŸããããŒã«ã«ãã£ãã·ã¥ã®ã¬ã€ã€ãŒã
- ïŒã¯ãŒã¯ãããŒã¬ã€ã€ãŒïŒç¹å®ã®ã¢ããªã±ãŒã·ã§ã³ã«åºæã®ã¯ã©ã¹ãšã¢ã«ãŽãªãºã ãå«ãã¯ãŒã¯ãããŒã¬ã€ã€ãŒã
- ïŒããŒã«ã«ã¹ãã¬ãŒãžïŒããŒã«ã«ã¹ãã¬ãŒãž
ã·ã¹ãã ã®éçºè ãçŽé¢ããäž»ãªã¿ã¹ã¯ã®1ã€ã¯ããããã®ã¬ã€ã€ãŒã®çžäºã«ç¬ç«ããæ©èœãä¿èšŒããããšã§ãã åã¬ã€ã€ãŒã¯ãå²ãåœãŠãããæ©èœã®ããã©ãŒãã³ã¹ã®ã¿ãä¿èšŒããå¿ èŠããããŸãã ååãšããŠãéå±€ã®äžäœã¬ãã«ã«äœçœ®ããã¬ã€ã€ãŒã¯ãä»ã®ã¬ã€ã€ãŒã®å®è£ ã®è©³çŽ°ãææ¡ããŠã¯ãªããŸããã
ãžã¥ãã¢ããã³ã·ãã¢éçºè ã®èŠ³ç¹ããåé¡ã解決ããããã»ã¹ãæ€èšããŠãã ããã
ç®çïŒãããã¯ãŒã¯ããããŒã¿ãåä¿¡ããããã°ã©ã ãé貚èšç®æ©ããäœæããçºæ¿ã¬ãŒãã®ã°ã©ããäœæããŸãã
ãžã¥ãã¢ïŒ
1ïŒåé¡ã®å£°æã«åºã¥ããŠãã¢ããªã±ãŒã·ã§ã³ã¯æ¬¡ã®éšåã§æ§æãããããšãããããŸãã
- æ°åŠæŒç®ïŒå ç®ãæžç®ïŒã®åœ¢åŒ
- ã°ã©ã衚瀺ãã©ãŒã
- è¿œå ã®ãã©ãŒã ïŒã¹ãã©ãã·ã¥ã¹ã¯ãªãŒã³ãçŽã
2ïŒæ¬¡ã®ããã«ãã©ãŒã ã®äŸåé¢ä¿ãäœæããŸããèšç®ã®ãã©ãŒã ã¯ãã¢ããªã±ãŒã·ã§ã³ã®äž»ãªãã®ã§ãã ã¹ãã©ãã·ã¥ãã©ãŒã ãèµ·åããŸããããã¯ãç¹å®ã®ãã¿ã³ãã¯ãªãã¯ããããšã§ãäžå®ã®æéãçµéãããšé衚瀺ã«ãªããŸãã
3ïŒã¹ãã©ãã·ã¥ç»é¢ã®è¡šç€ºæé-ãããã¯ãŒã¯ããããŒã¿ãããŒãããã®ã«ããã£ãæéã«çžåœããŸãã
4ïŒãããã¯ãŒã¯ããã®ããŠã³ããŒãã¯ã¹ãã©ãã·ã¥ãã©ãŒã ã®è¡šç€ºäžã«ã®ã¿å®è¡ããããããããŒã¿ããŒãã³ãŒãã¯ãã©ãŒã å ã«é 眮ããããã©ãŒã ã®å®äºæã«ããã©ãŒã ãšãšãã«ã¡ã¢ãªããåé€ãããŸãã
ãã®ã¢ããªã±ãŒã·ã§ã³ã¯ã©ã®çšåºŠæ©èœããŸããïŒ DelphiãVisual Studioã䜿çšãããšãçŸæç¹ã§ãã®åé¡ã解決ã§ããããšãçã人ã¯ããªããšæããŸãã Xcodeã䜿çšãããšããããå°ãé£ãããªããŸãããããŸãè² æ ããããã«è¡ãããšãã§ããŸãã ãã ãããããã¿ã€ãã®åºçŸã«ãããã¹ã±ãŒã©ããªãã£ã®åé¡ãçºçãå§ããŠããŸãã ã°ã©ãã衚瀺ããã«ã¯ãåã®æéã®ããŒã¿ãä¿åããå¿ èŠãããããšãæããã«ãªããŸãã åé¡ã§ã¯ãããŸãããããã£ãŒããã©ãŒã å ã«ããŒã¿ãŠã§ã¢ããŠã¹ãè¿œå ã§ããŸãã ãã ããããŒã¿ã¯ããŸããŸãªãããã€ããŒãããããŸããŸãªåœ¢åŒã§æäŸãããå ŽåããããŸãã ããã«ãç®è¡æŒç®ã¯ç°ãªãé貚ã§å®è¡ã§ãããããéžæã確å®ã«ããå¿ èŠããããŸãã ã°ã©ãã®åœ¢åŒã§ãã®ãããªéžæãè¡ãããšã¯å€å°éè«ççã§ãããå¯èœã§ãããã°ã©ãã«è¡šç€ºãããã®ã¯ãã®ãããªèšå®ã«äŸåããŸãã ããã¯ãèšå®ãŠã£ã³ããŠã«è¿œå ã®ãã©ã¡ãŒã¿ãŒãå ¥åããå Žåãäœããã®æ¹æ³ã§ããããã¡ã€ã³ãã©ãŒã ããã°ã©ããŠã£ã³ããŠã«è»¢éããå¿ èŠãããããšãæå³ããŸãã ãã®å Žåãæž¡ããããã©ã¡ãŒã¿ãŒãæ ŒçŽããã¡ã€ã³ãã©ãŒã ãä»ããŠ1ã€ã®ãã©ãŒã ããå¥ã®ãã©ãŒã ãžã®ã¢ã¯ã»ã¹ãæäŸããããŒã«ã«å€æ°ãäœæããã®ãè«ççã§ãã ãŸããªã©ã æšè«ã®é£éã¯éåžžã«é·ãéæ§ç¯ããããšãã§ããçžäºäœçšã®è€éããå¢ããŸãã
ã·ãã¢ïŒ
åé¡ã®ã¹ããŒãã¡ã³ãã«ãããå¥ã ã®ã¯ã©ã¹ã§èšè¿°ã§ããããã€ãã®ãµãã¿ã¹ã¯ãåºå¥ã§ããŸãã
1ïŒãããã¯ãŒã¯ããããŒã¿ãããŠã³ããŒãããŸãã
- åä¿¡ããŒã¿ã®æ€èšŒ
- æ°žç¶ã¹ãã¬ãŒãžã«ããŒã¿ãä¿åããŸãã
- ããŒã¿èšç®ã
- å ç®æäœ
- æžç®æŒç®
- æå®ãããåºæºïŒã¢ããªã±ãŒã·ã§ã³èšå®ïŒã«ããããŒã¿ã®ãã£ã«ã¿ãªã³ã°
- ã¢ããªã±ãŒã·ã§ã³éå§ã¯ã©ã¹ã
2ïŒæ¬¡ã®äž»èŠãªåœ¢åŒã§æ§æãããã€ã³ã¿ãŒãã§ã€ã¹ã®é¢é£æäœã確èªããŸãã
- ã¡ã€ã³ã³ã³ãããŒã©ãŒïŒäžå¯èŠã®å ŽåããããŸãïŒ
- èšç®ãã©ãŒã
- ãã£ãŒããã©ãŒã
- ã¹ãã©ãã·ã¥ãšã«ã€ããŠ
- ãªãã·ã§ã³èšå®ãã©ãŒã ã
3ïŒã¢ããªã±ãŒã·ã§ã³ãå®è¡ã®ããã«èµ·åãããåŸãããŒã¿ã®ããŒããæ åœãããªããžã§ã¯ãã®äœæïŒã€ã³ã¹ã¿ã³ã¹ïŒïŒå€§å€æ°ã®å ŽåéåæïŒãå®è¡ãããããã»ã¹ãéå§ãããŸãã ã¢ããªã±ãŒã·ã§ã³ã®ã¡ã€ã³ã³ã³ãããŒã©ãŒã¯ã¹ãã©ãã·ã¥ã¹ã¯ãªãŒã³ã衚瀺ãããã®æç¹ã§ãã¹ãã©ãã·ã¥ãã©ãŒã ãé衚瀺ã«ãã代ããã«ãã©ãŒã ã圢æããŸãã
4ïŒããŒã¿ã®èªã¿èŸŒã¿ãçµäºãããšãæ€èšŒãªããžã§ã¯ããšããŒã«ã«ã¹ãã¬ãŒãžãããã€ããŒãªããžã§ã¯ããäœæãããŸãã ããŒã¿ãå¿ èŠãªæ€èšŒã«åæ Œããå ŽåãããŒã«ã«ã¹ãã¬ãŒãžãããã€ããŒã«è»¢éã§ããŸãã
5ïŒã°ã©ãã衚瀺ããããã«ãããŒã«ã«ã¹ãã¬ãŒãžãªããžã§ã¯ããšããŒã¿èšå®ãªããžã§ã¯ããäœæãããŸãã ããŒã¿èšå®ãããŒã«ã«ã¹ãã¬ãŒãžãããã€ããŒã«è»¢éããããã£ã«ã¿ãŒãã€ã³ã¹ããŒã«ãããããŒã¿ãååŸãããŸãã
6ïŒèšç®ãå®è¡ããããã«ãé»åãªããžã§ã¯ããšæäœãªããžã§ã¯ããäœæãããŸãã ãã©ãŒã ããåãåã£ãããŒã¿ã¯ãèšç®æ©ãªããžã§ã¯ããšãèšç®ã®å®è¡æ¹æ³ãæ£ç¢ºã«ç¥ã£ãŠãã2ã€ã®æäœãªããžã§ã¯ãã®1ã€ã«è»¢éãããŸãã
ãã¡ããããã®ã¢ãããŒãã§ã¯ããå€ãã®ããã°ã©ãã³ã°äœæ¥ãå¿ èŠã«ãªããããæåã¯ããå€ãã®æéãããããŸãã ãã ãããµãã¿ã¹ã¯ã«åºã¥ããŠããŸãããã®äœæ¥ã䞊ååã容æã§ããããšã¯æããã§ã-1人ã®éçºè ãã«ãŒãã«ã®æ§ç¯ã«å¿ããäžæ¹ã§ãä»ã®éçºè ã¯UIãäœæããã³ãããã°ããŸãã ã«ãŒãã«ã¯ã³ã³ãœãŒã«å ã§å®å šã«åäœããããã€ã¹ã§UIãã¯ãªãã¯ããŸããç¹ã«ãç¬ç«ããåäœãã¹ããäž¡æ¹ã®éšåã«ãã蟌ãããšãã§ããŸãã ãã1ã€ã®ééããªãå©ç¹ã¯ã2çªç®ã®ã¢ãããŒããã¯ããã«ã¹ã±ãŒã©ãã«ã§ããããšã§ãã ãããžã§ã¯ãã®æ©èœãä¿®æ£ããå ŽåãèŠèŠçãªè¡šçŸã«å¶éçãªãã¬ãŒã ã¯ãŒã¯ããªããããå€æŽã¯äœåãéããªããŸãã ããžã¥ã¢ã«ãã©ãŒã èªäœïŒGUIïŒã¯ãã«ãŒãã«å ã®æ¢åã®ã¿ã¹ã¯ã«åºã¥ããŠå¿ èŠãªæå°å€ã衚瀺ããŸãã
éå§ã¬ã€ã€ãŒïŒ
iOSã§ã¯ãã¢ããªã±ãŒã·ã§ã³ã¯ããªã²ãŒãã¯ã©ã¹ãªããžã§ã¯ããèµ·åããããšã§èµ·åããŸãã ãã®ç®çã¯ãã·ã¹ãã ã³ãŒã«ãåä¿¡ããŠââã¢ããªã±ãŒã·ã§ã³ã«è»¢éããã¢ããªã±ãŒã·ã§ã³GUIã®åæèšå®ãå®è¡ããããšã§ãã ã¢ããªã±ãŒã·ã§ã³ã®éå§ããŸãã¯ã·ã¹ãã ããã®ã¡ãã»ãŒãžã®åä¿¡ã«é¢ä¿ããªããã¹ãŠã®ã¢ã«ãŽãªãºã ãšã¡ã«ããºã ã¯ãå¥ã ã®ã¯ã©ã¹ã«é 眮ããå¿ èŠããããŸãã åææ§æã®å®äºçŽåŸã«ãå¶åŸ¡ã¯ãæ®ãã®ã¢ããªã±ãŒã·ã§ã³æ§ææäœãå®è¡ããã¯ã©ã¹ã«è»¢éããå¿ èŠããããŸãïŒèš±å¯ãæ¡ä»¶ã«å¿ããã€ã³ã¿ãŒãã§ãŒã¹ã®åæ§æãåæããŒã¿ã®ããŒããå¿ èŠãªããŒã¯ã³ã®ååŸãªã©ã éçºè ãç¯ãå žåçãªééãã¯ãAppDelegateã§ãã¹ãããã巚倧ãªã¹ãã²ããã£ã³ãŒãã§ãã å€éšãã¬ãŒã ã¯ãŒã¯ã®ã»ãšãã©ãã¹ãŠã®äŸã«ã¯ãç解ã容æã«ããããã®ç¬èªã®ã³ãŒãããããŸãã äžéãªããã°ã©ããŒã¯ãªãã¡ã¯ã¿ãªã³ã°ã«æéã浪費ãããåã«ãäœã§ãããã³ããŒããŸãã CoreDataãäœæããããã«çµã¿èŸŒã¿ãã³ãã¬ãŒãã䜿çšããå Žåãç¶æ³ã¯éåžžã«å žåçã§ãã
å€ãã®å Žåã次ã®æ©èœã®å®è£ ã確èªã§ããŸãã
- Facebookã»ãã·ã§ã³ã®ã»ããã¢ãããšç¶æ
- ã¢ããªã±ãŒã·ã§ã³ãUITabbarControllerããµããŒãããå Žåãã¿ããããŒãžã£ãŒãèšå®ããŸãã
- ããã¯ã°ã©ãŠã³ãã«å ¥ããšãã«CoreDataãã¯ãªã¢ããŠããŒã¿ãä¿åããŸãã
- æŽæ°ã®ç¢ºèªãšåæå
- å€éšçµ±èšãµãŒããŒã®éç¥
- ããŒã¿ã¢ãã«ã®åæ
ãããã¯ãŒã¯å±€ïŒ
ã¯ã©ã€ã¢ã³ããããµãŒããŒã«ã¡ãã»ãŒãžãéä¿¡ããããããå¿ èŠãªæ å ±ãååŸãããã©ã³ã¹ããŒãå±€ã®åºæ¬çãªã¢ã«ãŽãªãºã ãæäŸããŸãã ååãšããŠãã¡ãã»ãŒãžã¯JSON圢åŒãšãã«ãããŒã圢åŒã§éä¿¡ã§ããŸãããäžéšã®ãšããŸããã¯ãªã±ãŒã¹ã§ã¯ãäžè¬çã«XMLãŸãã¯ãã€ããªã¹ããªãŒã ã«ãªããŸãã ãŸããåã¡ãã»ãŒãžã«ã¯ããªãŒããŒãããæ å ±ãå«ãããããŒãå«ãŸããå ŽåããããŸãã ããšãã°ãã¢ããªã±ãŒã·ã§ã³ãã£ãã·ã¥å ã®èŠæ±/å¿çã¹ãã¬ãŒãžã®æéãããã«èšè¿°ããããšãã§ããŸãã
ãããã¯ãŒã¯å±€ã¯ãã¢ããªã±ãŒã·ã§ã³ã䜿çšãããµãŒããŒããã®ã³ãã³ãã·ã¹ãã ã«ã€ããŠäœãç¥ããŸããã ãããã¯ãŒã¯æ¥ç¶ãšã©ãŒåŠçã¯ã次ã®ã¢ããªã±ãŒã·ã§ã³ã¬ãã«ã®ä»®æ³ã¡ãœããã«ãã£ãŠå®è¡ãããŸãã ãã®ã¬ã€ã€ãŒã®ã¿ã¹ã¯ã¯ãåŠçã¡ãœãããåŒã³åºããŠããããã¯ãŒã¯ããåä¿¡ããæ å ±ãåŠçã¡ãœããã«è»¢éããããšã ãã§ãã
ããã«ããããã¯ãŒã¯ããçŽæ¥æ å ±ãèŠæ±ããåã«ããããã¯ãŒã¯å±€ã¯ããŒã«ã«ãã£ãã·ã¥ãããŒãªã³ã°ããããã«å¿çãããå Žåãããã«ããããŠãŒã¶ãŒã«è¿ããŸãã
ãã®ã¬ã€ã€ãŒã®ã³ã³ãã³ãã¯ãã©ã®ãã©ã³ã¹ããŒããã¯ãããžãŒãæãè¿ããã«å€§ããäŸåããŸãã éçºè ã®æŠåšã§ã¯ã次ã®ãªãã·ã§ã³ãæãéèŠããããŸãã
- ãœã±ããã¯ãåæèŠæ±ãšéåæèŠæ±ãå«ãæãäœã¬ãã«ã®ã¢ãããŒãã§ãããTCPæ¥ç¶ãšUDPæ¥ç¶ã®äž¡æ¹ã§æ©èœããããšãã§ããŸãã ã»ãšãã©äœã§ãã§ããŸãããã¿ã¹ã¯ã«éäžããå¿ èŠããããå¿èåãããŸããªãã倧éã®ã³ãŒããå¿ èŠã§ãã
- WebSocketã¯ãTCPäžã®ããããŒã®äœ¿çšã«åºã¥ãã¢ãããŒãã§ãã 詳现ã¯ãã¡ããã芧ãã ããïŒ habrahabr.ru/post/79038ã¢ãã€ã«éçºã¯ãååãªæè»æ§ããªããããããµããŒãããããã«ããªã倧éã®ã³ãŒããå¿ èŠãšãããããããŸã䜿çšãããŸããã
- WCFã¯ããããæãå é²çãªã¡ã«ããºã ã§ããããã¹ãŠã®å©ç¹ãäžåãéåžžã«æ·±å»ãªãã€ãã¹ãæã£ãŠããŸãã Microsoftã®è žã§çºæãããã¢ãããŒãã¯ãã¢ããªã±ãŒã·ã§ã³ããžãã¯ãšãªã¢ãŒãããŒã¹ã®éã®é¢ä¿ã仲ä»ãããããã·ã¯ã©ã¹ã®äœæã«äŸåããŠããŸãã WSDLã¹ããŒã ïŒ en.wikipedia.org/wiki/Web_Services_Description_Language ïŒã«åºã¥ããŠãããã·ã¯ã©ã¹ãçæã§ããå Žåãã軜快ã«ãåäœããŸãã ãŸãããã®ã¯ã©ã¹ã¯ããµãŒããŒAPIãæŽæ°ããããã³ã«åçæããå¿ èŠããããŸãã ãŸããVisual Studioéçºè ã«ãšã£ãŠãããZephyrã®äœ¿ããããã§è¡ãããå ŽåãiOSéçºè ã«ãšã£ãŠã¯ãéçºã§MonoTouchã䜿çšããŠãã人ã«ãšã£ãŠããããã¯çµ¶å¯Ÿã«äžå¯èœãªäœæ¥ã§ãã
- RESTã¯ãäžèšã®ãã¹ãŠã®ã¢ãããŒãïŒ en.wikipedia.org/wiki/REST ïŒã®ä¿¡é Œã§ããã å®çžŸã®ãã劥åæ¡ã§ãã ãã¡ãããåã¢ãããŒãã®æ©èœã®äžéšãæŸæ£ããå¿ èŠããããŸãããããã¯æå°éã®åŽåã§è¿ éãã€éåžžã«å¹ççã«è¡ãããŸãã
GitHubã«ã¯RESTæ¥ç¶ã䜿çšã§ããå€ãã®ã©ã€ãã©ãªãå«ãŸããŠããŸããiOSã®å ŽåãAFNetworkingãæã人æ°ããããŸãã
RESTã¯ãGETãPOSTãPUTãHEADãPATCHãããã³DELETEèŠæ±ã®äœ¿çšã«äŸåããŠããŸãã ãã®ãããªåç©åã¯RESTFulïŒ habrahabr.ru/post/144011 ïŒãšåŒã°ããååãšããŠãåäœäžã®ã¢ãã€ã«ã¢ããªã±ãŒã·ã§ã³ãWebãµã€ãããã¹ã¯ããããããã³å®å®ã¹ããŒã·ã§ã³çšã®ãŠãããŒãµã«APIã1ã€ã®ãã³ãã«ã§èšè¿°ãããŠããå Žåã«ã®ã¿äœ¿çšãããŸãã
ã»ãšãã©ã®ã¢ããªã±ãŒã·ã§ã³ã§ã¯ãã³ãã³ãã·ã¹ãã ãGETãšPOSTã®2ã€ã®ã¿ã€ãã«å¶éããŠããŸãããPOSTã ãã§ååã§ãã
GETèŠæ±ã¯ããã©ãŠã¶ãŒã§äœ¿çšããæååãšããŠéä¿¡ãããèŠæ±ã®ãã©ã¡ãŒã¿ãŒã¯ãïŒãæåã§åºåã£ãŠæž¡ãããŸãã POSTèŠæ±ãããã©ãŠã¶æååãã䜿çšããŸããããã©ã¡ãŒã¿ã¯ã¡ãã»ãŒãžã®äžå¯èŠã®æ¬æå ã«é ãããŠããŸãã æåŸã®2ã€ã®ã¹ããŒãã¡ã³ãã¯ã以åã«ãªã¯ãšã¹ãã«åºäŒã£ãããšããªã人ãã¡ã®èœèã«é¥ããŸããå®éã«ã¯ããã®æè¡ã¯éçºè ã«ãšã£ãŠå®å šã«ééçã§ããããã®ãããªãã¥ã¢ã³ã¹ãæãäžããå¿ èŠã¯ãããŸããã
äžèšã§ã¯ããµãŒããŒã«éä¿¡ããããã®ã«ã€ããŠèª¬æããŸããã ãããããµãŒããŒããæ¥ããã®ã¯ã¯ããã«èå³æ·±ãã§ãã AFNetworkingã䜿çšããå ŽåããµãŒããŒåŽã§åä¿¡ããŸãååãšããŠãiOSéçºè ã¯JSONããŒã¹ã®ã·ãªã¢ã«åãããèŸæžãåŒã³åºããŸãããããã¯å®å šã«çå®ã§ã¯ãããŸããã True JââSONã®åœ¢åŒã¯ããè€éã§ãããçŽç²ãªåœ¢åŒã§ã¯äœ¿çšããå¿ èŠã¯ã»ãšãã©ãããŸããã ãã ããç¥ã£ãŠããå¿ èŠãããéãããããŸã-ãã¥ã¢ã³ã¹ããããŸãã
Microsoft Windows Serverã«ã€ã³ã¹ããŒã«ããããµãŒãã¹ã䜿çšããŠããå Žåãã»ãšãã©ã®å Žåãããã§WCFã䜿çšãããŸãã ãã ããWindows Framework 4以éã§ã¯ãRESTãããã³ã«ã®ã¿ããµããŒãããã¯ã©ã€ã¢ã³ãã¯ãã¢ã¯ã»ã¹ãå®å šã«ééçã«å®£èšçã«ããããšãã§ããŸãã APIã«é¢ãã説æãåŸãããã«æéãç¡é§ã«ããå¿ èŠã¯ãããŸãããã³ãã³ãã·ã¹ãã ã«é¢ããããã¥ã¡ã³ãã¯IISïŒMicrosoft WebãµãŒããŒïŒã«ãã£ãŠèªåçã«çæãããŸãã
以äžã¯ãObjective-Cã§AFNetworking 2ã䜿çšããŠãããã¯ãŒã¯å±€ãå®è£ ããããã®æå°ã³ãŒãã§ãã
ãªã¹ã1
ClientBase.h
ClientBase.m
#import "AFHTTPRequestOperationManager.h" NS_ENUM(NSInteger, REQUEST_METHOD) { GET, HEAD, POST, PUT, PATCH, DELETE }; @interface ClientBase : AFHTTPRequestOperationManager @property (nonatomic, strong) NSString *shortEndpoint; - (void)request:(NSDictionary *)data andEndpoint:(NSString *)endpoint andMethod:(enum REQUEST_METHOD)method success:(void(^)(id response))success fail:(void(^)(id response))fail; @end
ClientBase.m
#import "ClientBase.h" @implementation ClientBase - (void)request:(NSDictionary *)data andEndpoint:(NSString *)endpoint andMethod:(enum REQUEST_METHOD)method success:(void(^)(id response))success fail:(void(^)(id response))fail { self.requestSerializer = [AFJSONRequestSerializer serializer]; if(data == nil) data = @{}; AFHTTPRequestOperation *operation = [self requestWithMethod:method path:endpoint parameters:data success:success fail:fail]; [operation start]; } - (AFHTTPRequestOperation *)requestWithMethod:(enum REQUEST_METHOD)method path:endpoint parameters:data success:(void(^)(id response))success fail:(void(^)(id response))fail{ switch (method) { case GET: return [self requestGETMethod:data andEndpoint:endpoint success:success fail:fail]; case POST: return [self requestPOSTMethod:data andEndpoint:endpoint success:success fail:fail]; default: return nil; } } - (AFHTTPRequestOperation *)requestGETMethod:(NSDictionary *)data andEndpoint:(NSString *)endpoint success:(void(^)(id response))success fail:(void(^)(id response))fail { return [self GET:endpoint parameters:data success:^(AFHTTPRequestOperation *operation, id responseObject) { [self callingSuccesses:GET withResponse:responseObject endpoint:endpoint data:data success:success fail:fail]; [KNZHttpCache cacheResponse:responseObject httpResponse:operation.response]; } failure:^(AFHTTPRequestOperation *operation, NSError *error) { NSLog(@"\n\n--- ERROR: %@", operation); NSLog(@"\n--- DATA: %@", data); [self callingFail:fail error:error]; }]; } - (AFHTTPRequestOperation *)requestPOSTMethod:(NSDictionary *)data andEndpoint:(NSString *)endpoint success:(void(^)(id response))success fail:(void(^)(id response))fail { return [self POST:endpoint parameters:data success:^(AFHTTPRequestOperation *operation, id responseObject) { [self callingSuccesses:POST withResponse:responseObject endpoint:endpoint data:data success:success fail:fail]; } failure:^(AFHTTPRequestOperation *operation, NSError *error) { NSLog(@"\n\n--- ERROR: %@", operation); NSLog(@"\n--- DATA: %@", data); [self callingFail:fail error:error]; }]; } - (void)callingSuccesses:(enum REQUEST_METHOD)requestMethod withResponse:(id)responseObject endpoint:(NSString *)endpoint data:(NSDictionary *)data success:(void(^)(id response))success fail:(void(^)(id response))fail { if(success!=nil) success(responseObject); } - (void)callingFail:(void(^)(id response))fail error:(NSError *)error { if(fail!=nil) fail(error); } @end
ããã¯ããããã¯ãŒã¯ã®GETããã³POSTã¡ãã»ãŒãžãéä¿¡ããã®ã«ååã§ãã ã»ãšãã©ã®å Žåããããã®ãã¡ã€ã«ã調æŽããå¿ èŠã¯ãããŸããã
APIã¬ã€ã€ãŒïŒ
RESTã³ãã³ãã«ã€ããŠèª¬æãããã¹ããéžæããŸãã ã¬ã€ã€ãŒAPIã¯ããããã¯ãŒã¯ãããã³ã«ã®å®è£ ãã¢ããªã±ãŒã·ã§ã³ã®ä»ã®æ©èœã«é¢ããç¥èãšã¯å®å šã«åé¢ãããŠããŸãã æè¡çã«ã¯ãã¢ããªã±ãŒã·ã§ã³ã®ä»ã®éšåãå€æŽããã«å®å šã«çœ®ãæããããšãã§ããŸãã
ã¯ã©ã¹ã¯ClientBaseããç¶æ¿ãããŸãã ã¯ã©ã¹ã³ãŒãã¯éåžžã«åçŽãªã®ã§ãã¯ã©ã¹ã³ãŒãå šäœãæäŸããå¿ èŠãããããŸãããAPIã®çµ±äžãããèšè¿°ã§æ§æãããŠããŸãã
ãªã¹ã2
#define LOGIN_FACEBOOK_ENDPOINT @"/api/v1/member/login/facebook/" #define LOGIN_EMAIL_ENDPOINT @"/api/v1/member/login/email/" - (void)loginFacebook:(NSDictionary *)data success:(void(^)(id response))success fail:(void(^)(id response))fail { [self request:data andEndpoint:LOGIN_FACEBOOK_ENDPOINT andMethod:POST success:success fail:fail]; } - (void)loginEmail:(NSDictionary *)data success:(void(^)(id response))success fail:(void(^)(id response))fail { [self request:data andEndpoint:LOGIN_EMAIL_ENDPOINT andMethod:POST success:success fail:fail]; }
sayingã«ãããããã«ãããã以äžã¯ãããŸãããã
ãããã¯ãŒã¯ãã£ãã·ã¥ã¬ã€ã€ãŒïŒ
ãã®ãã£ãã·ã³ã°ã¬ã€ã€ãŒã¯ãiOS SDKã¬ãã«ã§ã¯ã©ã€ã¢ã³ããšãµãŒããŒéã®ãããã¯ãŒã¯äº€æãå éããããã«äœ¿çšãããŸãã åçã®éžæã¯ãã·ã¹ãã ã®å¶åŸ¡å€ã«ããåœäºè ã«ãã£ãŠå®è¡ããããããã¯ãŒã¯ãã©ãã£ãã¯ã®æžå°ãä¿èšŒãããã®ã§ã¯ãªãããããå éããŸãã ã¢ããªã±ãŒã·ã§ã³ãŸãã¯ã·ã¹ãã ããããŒã¿ãŸãã¯å®è£ ã¡ã«ããºã ã«ã¢ã¯ã»ã¹ããããšã¯ã§ããŸããã SQLiteã¹ãã¬ãŒãžã䜿çšããŸãã
ããã«å¿ èŠãªã³ãŒãã¯åçŽãããŠããããã¯ãŒã¯ã«ã¢ã¯ã»ã¹ã§ãããããžã§ã¯ãã§ã¯äœ¿çšã§ããŸããã
ãªã¹ã3
#define memoCache 4 * 1024 * 1024 #define diskCache 20 * 1024 * 1024 #define DISK_CACHES_FILEPATH @"%@/Library/Caches/httpCache" - (void)start { NSURLCache *URLCache = [[NSURLCache alloc] initWithMemoryCapacity:memoCache diskCapacity:diskCache diskPath:nil]; [NSURLCache setSharedURLCache:URLCache]; }
ã¢ããªã±ãŒã·ã§ã³å ã®ã©ãããã§ãäžåºŠåŒã³åºãå¿ èŠããããŸãã ããšãã°ãéå§ã¬ã€ã€ãŒããã
æ€èšŒã¢ã€ãã ã¬ã€ã€ãŒïŒ
ãããã¯ãŒã¯ããåä¿¡ããããŒã¿ã®åœ¢åŒã¯ããµãŒããŒéçºè ã«ããäŸåããŠããŸãã ã¢ããªã±ãŒã·ã§ã³ã¯ãæåã«æå®ããã圢åŒã®äœ¿çšãç©ççã«å¶åŸ¡ã§ããŸããã è€éãªæ§é ã®ããŒã¿ã®å Žåããšã©ãŒä¿®æ£ã¯è€éãã«ãããŠã¢ããªã±ãŒã·ã§ã³èªäœã®éçºã«å¹æµããŸãã ãšã©ãŒã®ååšã¯ãã¢ããªã±ãŒã·ã§ã³ã®ã¯ã©ãã·ã¥ã䌎ããŸãã ããŒã¿æ€èšŒã¡ã«ããºã ã䜿çšãããšãäžæ£ãªåäœã®ãªã¹ã¯ãå€§å¹ ã«åæžãããŸãã æ€èšŒã¬ã€ã€ãŒã¯ããµãŒããŒãžã®ã»ãšãã©ã®ãªã¯ãšã¹ãã®JSONã¹ããŒã ãšãããŒããããã¹ããŒã ã«å¯ŸããŠåä¿¡ããŒã¿ããã§ãã¯ããã¯ã©ã¹ã§æ§æãããŸãã åä¿¡ãããã±ãããã¹ããŒã ãšäžèŽããªãå Žåãã¢ããªã±ãŒã·ã§ã³ã«ãã£ãŠæåŠãããŸãã åŒã³åºãå ã®ã³ãŒãã¯ãšã©ãŒéç¥ãåãåããŸãã åæ§ã®éç¥ãã³ã³ãœãŒã«ãã°ã«èšé²ãããŸãã ããã«ããµãŒããŒã³ãã³ããåŒã³åºããŠããšã©ãŒã«é¢ããã¬ããŒãããµãŒããŒåŽã«éä¿¡ã§ããŸãã äž»ãªããšã¯ããã®ãããªã¡ãã»ãŒãžãéä¿¡ããã³ãã³ããäœããã®ãšã©ãŒïŒ4xxãŸãã¯5xxïŒãåŒãèµ·ããå Žåãååž°ããæãåºãæ¹æ³ãæäŸããããšã§ãã
次ã®ããŒã¿ããµãŒããŒã«éä¿¡ããããšã¯çã«ããªã£ãŠããŸãã
- ãšã©ãŒãçºçããã¢ã«ãŠã³ãã
- ã©ã®ããŒã ããšã©ãŒãåŒãèµ·ãããŸããã
- ãµãŒããŒã«è»¢éãããããŒã¿ã
- ãµãŒããŒããåä¿¡ããå¿çã
- UTCæé*
- ããŒã ã®ã¹ããŒã¿ã¹ã³ãŒãã æ€èšŒãšã©ãŒã®å Žåãåžžã«200ã§ãã
- ãµãŒããŒã®å¿çãæºãããªãã¹ããŒã ã
* UTCæéã¯ãã³ãã³ããåŒã³åºãããæå»ã§ãããå¿çããµãŒããŒã«è¿ãããæå»ã§ã¯ãããŸããã ååãšããŠããããã¯äžèŽããŸãããã¢ããªã±ãŒã·ã§ã³ã«ã¯èŠæ±ãã¥ãŒã¡ã«ããºã ããããããçè«çã«ã¯ã倱æããã³ãã³ãã®åŒã³åºããšãµãŒããŒã«ããã¬ã³ãŒãã®èšé²ã®éã«æãçµéããå¯èœæ§ããããŸãã
JSONèŠæ±ã¹ããŒã ã¯ãæ°ããAPIã³ãã³ããå®è£ ããåŸã«ãµãŒããŒéçºè ã«ãã£ãŠæäŸããããšæ³å®ãããŠããŸãã
åã¹ããŒã ããã³åããŒã ã¯ã以åã«åæããç¹å®ã®åºæºãæºãã矩åããããŸãã äžèšã®äŸã§ã¯ããµãŒããŒå¿çã«ã¯2ã€ã®ã¡ã€ã³ãã£ãŒã«ããš1ã€ã®ãªãã·ã§ã³ãã£ãŒã«ããå«ãŸããŠããå¿ èŠããããŸãã
ãã¹ããŒã¿ã¹ããå¿ èŠã§ãã OKãŸãã¯ERRORèå¥åïŒãŸãã¯ã200ãã¿ã€ãã®HTTPã³ãŒãïŒãå«ãŸããŸãã
ãReasonããå¿ èŠãšã©ãŒãçºçããå Žåããšã©ãŒã®åå ã®èª¬æãå«ãŸããŸãã ãã以å€ã®å Žåããã®ãã£ãŒã«ãã¯ç©ºã§ãã
ãããŒã¿ãã¯ãªãã·ã§ã³ã§ãã ã³ãã³ãã®çµæãå«ãŸããŸãã ãšã©ãŒã®å Žåãæ¬ èœ
åè·¯äŸïŒ
ãªã¹ã4
{ "title": "updateconfig", "description": "/api/v1/member/updateconfig/", "type":"object", "properties": { "reason": { "type":"string", "required": true }, "status": { "type":"string", "required": true }, "data": { "type":"object" } }, "required": ["reason", "status"] }
Maxim Luninã«ãã£ãŠéçºãããã©ã€ãã©ãªã®ãããã§ãéåžžã«ç°¡åã«ãªããŸããã ïŒ habrahabr.ru/post/180923 ïŒ
æ€èšŒã¯ã©ã¹ã³ãŒãã以äžã«ç€ºããŸãã
ãªã¹ã5
ResponseValidator.h
#import "ResponseValidator.h" #import "SVJsonSchema.h" @implementation ResponseValidator + (instancetype)sharedInstance { static ResponseValidator *sharedInstance; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ sharedInstance = [[ResponseValidator alloc] init]; }); return sharedInstance; } #pragma mark - Methods of class + (void)validate:(id)response endpoint:(NSString *)endpoint success:(void(^)())success fail:(void(^)(NSString *error))fail { [[ sharedInstance] validate:response endpoint:endpoint success:success fail:fail]; } + (NSDictionary *)schemeForEndpoint:(NSString *)endpoint { NSString *cmd = [[ResponseValidator sharedInstance] extractCommand:endpoint]; return [[ResponseValidator sharedInstance] validatorByName:cmd]; } #pragma mark - Methods of instance - (void)validate:(id)response endpoint:(NSString *)endpoint success:(void(^)())success fail:(void(^)(NSString *error))fail { NSString *cmd = [self extractCommand:endpoint]; NSDictionary *schema = [self validatorByName:cmd]; SVType *validator = [SVType schemaWithDictionary:schema]; NSError *error; [validator validateJson:response error:&error]; if(error==nil) { if(success!=nil) success(); } else { NSString *result = [NSString stringWithFormat:@"%@ : %@", cmd, error.description]; if(fail!=nil) fail(result); } } - (NSString *)extractCommand:(NSString *)endpoint { NSString *cmd = [endpoint.stringByDeletingLastPathComponent lastPathComponent]; return cmd; } - (NSDictionary *)validatorByName:(NSString *)name { static NSString *ext = @"json"; NSString *filePath = [[NSBundle mainBundle] pathForResource:name ofType:ext]; NSString *schema = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil]; if(schema == nil) return nil; NSData *data = [schema dataUsingEncoding:NSUTF8StringEncoding]; NSError *error; NSDictionary *result = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error]; return result; } @end
æ€èšŒåŒã³åºãã¯éåžžã«ç°¡åã§ãã
ãªã¹ã6
[ResponseValidator validate:responseObject endpoint:endpoint success:^{ /* , */ } fail:^(NSString *error) { /* . - , . . */ }];
ãããã¯ãŒã¯ã¢ã€ãã ã¬ã€ã€ãŒïŒ
JSONãããã·ãªã¢ã©ã€ãºãããè¡šçŸãžã®ããŒã¿ã®ãããã³ã°ãæ åœããã®ã¯ãã®ã¬ã€ã€ãŒäžã§ãã ãã®å±€ã¯ããªããžã§ã¯ããŸãã¯ãªããžã§ã¯ããªã¬ãŒã·ã§ãã«å€æãå®è£ ããã¯ã©ã¹ãèšè¿°ããããã«äœ¿çšãããŸãã ãããã¯ãŒã¯äžã«ã¯ããªããžã§ã¯ããªã¬ãŒã·ã§ãã«å€æãå®è£ ããå€æ°ã®ã©ã€ãã©ãªããããŸãã ããšãã°ãJSONã¢ãã«ïŒ github.com/icanzilb/JSONModel ïŒãŸãã¯åãMaxim Luninã©ã€ãã©ãªã ãããããã¹ãŠãããã»ã©ãã©è²ã§ã¯ãããŸããã ãããã³ã°ã®åé¡ã軜æžããŸããã
ãããã³ã°ãšã¯äœãã説æããŸãããïŒ
æ§é å ã«åäžã®ããŒã¿ãè¿ã2ã€ã®ã¯ãšãªããããšããŸãã ããšãã°ãã¢ããªã±ãŒã·ã§ã³ã®ãŠãŒã¶ãŒãããã³ãèå¥åããããŠãŒã¶ãŒåããªã©ã®ãã£ãŒã«ããæã€ãŠãŒã¶ãŒã®å人ã åé¡ã¯ããµãŒããŒéçºè ã1ã€ã®ãªã¯ãšã¹ãã§ãidãããusernameãã2çªç®ã®ãidentãããuser_nameãã®ãã£ãŒã«ããæž¡ãããšãã§ããããšã§ãã ãã®ãããªäžäžèŽã¯ãäžé£ã®ãã©ãã«ãåŒãèµ·ããå¯èœæ§ããããŸãã
- CoreDataã䜿çšããå ŽåãObjective-Cã®ãã·ãªã¢ã©ã€ãºãããããŒã¿ãªããžã§ã¯ãã¯idãã£ãŒã«ããæã€ããšãã§ããŸãã
- idããã³identãã£ãŒã«ãã®ã·ãªã¢ã«åãããããŒã¿ã«ã¯ãæååãŸãã¯NSNumberãå«ããããšãã§ããŸãã ã³ã³ãœãŒã«ã«è¡šç€ºããå Žåã2ã€ã®æ°åã«éãã¯ãããŸããããéãã¯ãããŸããã ãããã®ããã·ã¥ã³ãŒãã¯ç°ãªããèŸæžã¯ãããã®ãã£ãŒã«ãã®æå³ãç°ãªã£ãŠèªèããŸãã
- ãã£ãŒã«ãåã®éãã¯ãµãŒããŒã®è²¬ä»»ã§ããããµãŒããŒéçºè ã¯ååãã¯ã©ã€ã¢ã³ãéçºè ã«ãšã£ãŠäŸ¿å©ãªçµ±äžãããååã«çœ®ãæããããã«ãåã«é£çµ¡ãåããªãå ŽåããããŸãã
ãããã®åé¡ã«å¯Ÿããæ®éçãªè§£æ±ºçã¯ãããŸããããé倧ãªç¥çåªåãå¿ èŠãšããã»ã©è€éã§ã¯ãããŸããã
ããŒã«ã«ãã£ãã·ã¥ã¬ã€ã€ãŒïŒ
ãã®ã¬ã€ã€ãŒã®ã¿ã¹ã¯ã¯æ¬¡ã®ãšããã§ãã
- ãããã¯ãŒã¯ããããŠã³ããŒãããç»åããã£ãã·ã¥ããŸãã
- ãµãŒããŒã®ãªã¯ãšã¹ã/ã¬ã¹ãã³ã¹ã®ãã£ãã·ã¥
- ãããã¯ãŒã¯ããã³ãªãã©ã€ã³ã®ãŠãŒã¶ãŒäœæ¥ããªãå Žåã«ãèŠæ±ã®ãã¥ãŒã圢æããŸãã
- ãã£ãã·ã¥ãããããŒã¿ãç£èŠããæéåãã®ããŒã¿ãæ¶å»ããŸãã
- æå®ããããªããžã§ã¯ãã«é¢ããæ å ±ããããã¯ãŒã¯ããåä¿¡ã§ããªãããšã«é¢ããã¢ããªã±ãŒã·ã§ã³ã®éç¥ã
äžè¬ã«ããã®ã¬ã€ã€ãŒã¯å¥ã®å€§ããªèšäºã®ãããã¯ã§ãã ããããéçºè ãèæ ®ãã¹ã埮åŠãªéããããã€ããããŸãã
ã¯ãšãªãã£ãã·ã³ã°ã®å Žåããªã¹ã1ã®æé ããããã«ã¢ããã°ã¬ãŒãã§ããŸããããã«ã¯ä»®æ³ã¡ãœããã䜿çšããããšã匷ããå§ãããŸãããç°¡åã«ããããã«ãã¯ã©ã¹ã¡ãœãããžã®çŽæ¥åŒã³åºãã瀺ããŸãã
ãªã¹ã7
- (void)request:(NSDictionary *)data andEndpoint:(NSString *)endpoint andMethod:(enum REQUEST_METHOD)method success:(void(^)(id response))success fail:(void(^)(id response))fail queueAvailable:(BOOL)queueAvailable { self.requestSerializer = [AFJSONRequestSerializer serializer]; if(data == nil) data = @{}; // Returning cache response. NSDictionary *cachedResponse = [HttpCache request:endpoint]; if(cachedResponse !=nil) { [self callingSuccesses:method withResponse:cachedResponse endpoint:endpoint data:data success:success fail:fail]; return; } AFHTTPRequestOperation *operation = [self requestWithMethod:method path:endpoint parameters:data success:success fail:fail]; [self consoleLogRequest:data operation:operation]; [operation start]; } - (AFHTTPRequestOperation *)requestPOSTMethod:(NSDictionary *)data andEndpoint:(NSString *)endpoint success:(void(^)(id response))success fail:(void(^)(id response))fail { return [self POST:endpoint parameters:data success:^(AFHTTPRequestOperation *operation, id responseObject) { [self callingSuccesses:POST withResponse:responseObject endpoint:endpoint data:data success:success fail:fail]; [HttpCache cacheResponse:responseObject httpResponse:operation.response]; } failure:^(AFHTTPRequestOperation *operation, NSError *error) { NSLog(@"\n\n--- ERROR: %@", operation); NSLog(@"\n--- DATA: %@", data); [self callingFail:fail error:error]; }]; }
HttpCacheã¯ã©ã¹ã«ã¯ãã¯ãšãªçµæãä¿åããã¡ãœããã«å ããŠãå¥ã®èå³æ·±ãã¡ãœããããããŸãã
ãªã¹ã8
#define CacheControlParam @"Cache-Control" #define kMaxAge @"max-age=" - (NSInteger)timeLife:(NSHTTPURLResponse *)httpResponse { NSString *cacheControl = httpResponse.allHeaderFields[CacheControlParam]; if(cacheControl.length > 0) { NSRange range = [cacheControl rangeOfString:kMaxAge]; if(range.location!=NSNotFound) { cacheControl = [cacheControl substringFromIndex:range.location + range.length]; return cacheControl.integerValue; } } return 0; }
ããã«ãããåä¿¡ãããã±ããã®æå¹æéïŒæ¥ä»ãæéåãã«ãªãç§æ°ïŒã«é¢ãããµãŒããŒå¿çããããŒããããŒæ å ±ãæœåºã§ããŸãã ãã®æ å ±ã䜿çšããŠãããŒã«ã«ã¹ãã¬ãŒãžã«ããŒã¿ãæžã蟌ãããšãã§ããåããªã¯ãšã¹ããç¹°ãè¿ããå Žåã¯ã以åã«åä¿¡ããããŒã¿ãèªã¿åãã ãã§ãã ã¡ãœããã0ãè¿ãå Žåããã®ãããªããŒã¿ã¯æžã蟌ããŸããã
ãããã£ãŠããµãŒããŒäžã§ãã¯ã©ã€ã¢ã³ãäžã§æ£ç¢ºã«ãã£ãã·ã¥ããããã®ãèŠå¶ããããšãã§ããŸãã æšæºã®ããããŒãã£ãŒã«ãã䜿çšãããŠããããšã«æ³šæããŠãã ããã ãã®ãããæšæºã«é¢ããŠã¯ãèªè»¢è»ã¯çºæãããŠããŸããã
ãªã¹ã1ã«å¥ã®å°ããªå€æŽãå ãããšããã¥ãŒã®åé¡ã¯ç°¡åã«è§£æ±ºãããŸãã
ãªã¹ã9
- (void)request:(NSDictionary *)data andEndpoint:(NSString *)endpoint andMethod:(enum REQUEST_METHOD)method success:(void(^)(id response))success fail:(void(^)(id response))fail queueAvailable:(BOOL)queueAvailable { self.requestSerializer = [AFJSONRequestSerializer serializer]; if(data == nil) data = @{}; if(queueAvailable) { [HttpQueue request:data endpoint:endpoint method:method]; } AFHTTPRequestOperation *operation = [self requestWithMethod:method path:endpoint parameters:data success:success fail:fail]; [operation start]; }
HttpQueueã¯ã©ã¹ã¯ãçŸåšãããã¯ãŒã¯æ¥ç¶ãååšãããã©ããããã§ãã¯ããååšããªãå Žåã¯ããªã¯ãšã¹ããããªç§ãŸã§è¡ãããæéã§ãªã¯ãšã¹ãããªããžããªã«æžã蟌ã¿ãŸãã æ¥ç¶ãåéããããšãããŒã¿ã¯ã¹ãã¬ãŒãžããèªã¿åããããµãŒããŒãã転éãããŸãããèŠæ±ãã¥ãŒã¯ã¯ãªã¢ãããŸãã ããã«ããããããã¯ãŒã¯ã«çŽæ¥æ¥ç¶ããã«ç¹å®ã®ã¯ã©ã€ã¢ã³ã/ãµãŒããŒæäœãæäŸã§ããŸãã
ãããã¯ãŒã¯æ¥ç¶ã®ç¢ºèªã¯ããªãã¶ãŒããŒãã¿ãŒã³ãšçµã¿åãããŠApple AFNetworkReachabilityManagerãŸãã¯Reachabilityã¯ã©ã¹ïŒ developer.apple.com/library/ios/samplecode/Reachability/Introduction/Intro.html ïŒã䜿çšããŠè¡ãããŸãã 圌ã®ããã€ã¹ã¯ãèšäºã§èª¬æããã«ã¯åå§çãããŸãã
ãã ãããã¹ãŠã®èŠæ±ããã¥ãŒã«éä¿¡ããå¿ èŠã¯ãããŸããã ãããã®ããã€ãã¯ããããã¯ãŒã¯ã®åºçŸæã«é¢ä¿ãªãå ŽåããããŸãã ã©ã®ã³ãã³ãããã¥ãŒãã£ãã·ã¥ã«æžã蟌ãããããã³ãã£ãã·ã¥ã¬ã€ã€ãŒã¬ãã«ãšAPIã¬ã€ã€ãŒã¬ãã«ã®äž¡æ¹ã§åŒã³åºãæã«ã®ã¿é¢é£ããã³ãã³ãã決å®ããããšãã§ããŸãã
ãªã¹ã9ã®æåã®ã±ãŒã¹ã§ã¯ããã¥ãŒã§saveã¡ãœãããåŒã³åºã代ããã«ãä»®æ³ã¡ãœãããæ¿å ¥ããApiLayerã¯ã©ã¹ããç¶æ¿ããŠLocalCacheLayerWithQueueããã³LocalCacheLayerWithoutQueueã¯ã©ã¹ãç¶æ¿ããå¿ èŠããããŸãã 次ã«ãLocalCacheLayerWithQueueã¯ã©ã¹ã®æå®ãããä»®æ³ã¡ãœããã§ãåŒã³åºããè¡ããŸã[HttpQueue requestïŒendpointïŒmethodïŒ]
2çªç®ã®ã±ãŒã¹ã§ã¯ãApiLayerã¯ã©ã¹ããã®ãªã¯ãšã¹ãåŒã³åºãã¯ãããã«å€æŽãããŸã
ãªã¹ã10
- (void)trackNotification:(NSDictionary *)data success:(void(^)(id response))success fail:(void(^)(id response))fail { [self request:data andEndpoint:TRACKNOTIFICATION_ENDPOINT andMethod:POST success:success fail:fail queueAvailable:YES]; }
ãªã¹ã9ã¯ãïŒqueueAvailableïŒãæäŸãããŠããå Žåã®ãŸãã«ãã®ã±ãŒã¹ã§ãã
ãŸããå¥ã®åé¡ã¯ç»åãã£ãã·ã¥ã®åé¡ã§ãã äžè¬çã«ã質åã¯è€éã§ã¯ãªããããå®è£ æ°ã¯ç¡éã§ãã ããšãã°ãSDWebImageã©ã€ãã©ãªã¯ãããéåžžã«ããŸãè¡ããŸãïŒïŒ github.com/rs/SDWebImage ïŒã
äžæ¹ã圌女ãè¡ãæ¹æ³ãç¥ããªãããšãããã€ããããŸãã ããšãã°ãæå®ãããåºæºïŒç»åã®æ°ãäœæãããæ¥ä»ãªã©ïŒã«åŸã£ãŠç»åãã£ãã·ã¥ãã¯ãªã¢ããããç¹å®ã®ãšã©ãŒããã°ã«èšé²ãããä¿®æ£ãããããããšã¯ã§ããŸããã
ãããã¯ãŒã¯ããç»åãéåæã§ããŠã³ããŒãããMIMEãšã©ãŒãä¿®æ£ããäŸã瀺ããŸãïŒããšãã°ãAmazonã¯å€ãã®å ŽåãWebãµãŒããŒãç»åãéä¿¡ããçµæãšããŠãç»åä»ãã®ãã€ããªãã¡ã€ã«ã§ã¯ãªãããŒã¿ã¹ããªãŒã ãšããŠééã£ãMIMEã¿ã€ããæäŸããŸãïŒã
ãªã¹ã11
#define LOCAL_CACHES_IMAGES_FILEPATH @"%@/Library/Caches/picture%ld.jpg" - (void)loadImage:(NSString*)link success:(void(^)(UIImage *image))success fail:(void(^)(NSError *error))fail { UIImage *image = [ImagesCache imageFromCache:link.hash]; if(image == nil) { dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ __block NSData *data; __block UIImage *remoteImage; __block NSData *dataImage; __block NSString *imgFilePath = [NSString stringWithFormat:LOCAL_CACHES_IMAGES_FILEPATH, NSHomeDirectory(), (unsigned long)link.hash]; data = [NSData dataWithContentsOfURL: [NSURL URLWithString:link]]; // Reading DATA if(data.length > 0) { remoteImage = [[UIImage alloc] initWithData: data]; // TRANSFORM DATA TO IMAGE if(remoteImage!=nil) { dataImage = [NSData dataWithData:UIImageJPEGRepresentation(remoteImage, 1.0)]; // TRANSFORM IMAGE TO JPEG DATA if(dataImage!=nil && dataImage.length > 0) [dataImage writeToFile:imgFilePath atomically:YES]; // Writing JPEG file } else // try to fix BINARY image type (first method) { [dataImage writeToFile:imgFilePath atomically:YES]; remoteImage = [UIImage imageWithContentsOfFile:imgFilePath]; } } else // try to fix BINARY image type (second method) { NSURLRequest *urlRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:link]]; NSURLResponse *response = nil; NSError *error = nil; data = [NSURLConnection sendSynchronousRequest:urlRequest returningResponse:&response error:&error]; if (error == nil) { remoteImage = [[UIImage alloc] initWithData: data]; // TRANSFORM DATA TO IMAGE if(remoteImage!=nil) { dataImage = [NSData dataWithData:UIImageJPEGRepresentation(remoteImage, 1.0)]; // TRANSFORM IMAGE TO JPEG DATA if(dataImage!=nil && dataImage.length > 0) [dataImage writeToFile:imgFilePath atomically:YES]; // Writing JPEG file } NSLog(@"USED SECONDARY METHOD FOR LOAD OF IMAGE"); } else NSLog(@"DATA WASN'T LOAD %@\nLINK %@", error, link); } dispatch_async(dispatch_get_main_queue(), ^{ if(remoteImage!=nil && success!=nil) { success(remoteImage); [ImagesCache update:link.hash]; } else { if(data.length == 0) NSLog(@"%@", @"\n============================\nDETECTED ERRROR OF DOWNLOAD IMAGE\nFILE CAN'T LOAD\nUSED PLACEHOLDER\n============================\n"); else NSLog(@"%@", @"\n============================\nDETECTED ERRROR OF DOWNLOAD IMAGE\nUSED PLACEHOLDER\n============================\n"); NSLog(@"LINK %@", link); UIImage *placeholder = [LoadImage userPlaceholder]; if (success) success(placeholder); // if(fail!=nil) // fail([NSError errorWithDomain:[NSString stringWithFormat:@"%@ not accessible", link] code:-1 userInfo:nil]); } }); }); } else { success(image); } }
ãã®æ¹æ³ã¯éåžžã«åé·ã«èŠãããããããŸããããéçºè ã®ç¹å®ã®ããŒãºã«åãããŠç°¡åã«å€æŽã§ããŸãã éèŠãªç¹ã®ãã¡ãç»åURLã®ããã·ã¥ããã£ãã·ã¥ã®ããŒãšããŠäœ¿çšãããããšã«æ³šæããå¿ èŠããããŸãã ãã®ã¢ãããŒãã§ã¯ãããã€ã¹ã®ãã¡ã€ã«ã·ã¹ãã å ã§è¡çªãçºçããããšã¯ã»ãšãã©ãããŸããã
ãã¡ã€ã«ããã£ãã·ã¥ããèªã¿åããããã³ã«ãã¢ã¯ã»ã¹æ¥ãå€æŽãããŸãã é·æéåèªã¿èŸŒã¿ãããªããã¡ã€ã«ã¯ãã¢ããªã±ãŒã·ã§ã³ã®èµ·åæã§ãå®å šã«åé€ã§ããŸãã
ã¢ããªã±ãŒã·ã§ã³ãã³ãã«ããã®ãã¡ã€ã«ã®èªã¿åãã«é¢ããŠã¯ãéçºè ãå¿ããŠãããã¥ã¢ã³ã¹ããããŸããiOSSDKã¯ã[UIImage imageNamedïŒ]ã[UIImage imageWithContentsOfFileïŒ]ãªã©ã®ã¡ãœãããæäŸããŸãã æåã®ãã®ã䜿çšããæ¹ãç°¡åã§ãããã¡ã¢ãªã®è² è·ã«å€§ãã圱é¿ããŸããå®éã«ã¯ãããŠã³ããŒãããããã¡ã€ã«ã¯ã¢ããªã±ãŒã·ã§ã³ãå®äºãããŸã§ããã€ã¹ã®ã¡ã¢ãªã«æ®ããŸãã ããã倧容éã®ãã¡ã€ã«ã§ããå Žåãããã¯åé¡ã«ãªãå¯èœæ§ããããŸãã 2çªç®ã®æ¹æ³ãã§ããã ãé »ç¹ã«äœ¿çšããããšããå§ãããŸãã ããã«ãããŒãæ¹æ³ããããã«æ¹åãããšäŸ¿å©ã§ãã
ãªã¹ã12
+ (UIImage *)fromBundlePng:(NSString *)name { return [[LoadImage sharedInstance] fromBundlePng:name]; } - (UIImage *)fromBundle:(NSString *)name { return [self downloadFromBundle:name.stringByDeletingPathExtension ext:name.pathExtension]; } - (UIImage *)downloadFromBundle:(NSString *)name ext:(NSString *)ext { NSString *filePath = [[NSBundle mainBundle] pathForResource:name ofType:ext]; if(filePath == nil) { NSString *filename = [NSString stringWithFormat:@"%@@2x", name]; filePath = [[NSBundle mainBundle] pathForResource:filename ofType:ext]; } return [UIImage imageWithContentsOfFile:filePath]; }
ããã§ããã¡ã€ã«ãã©ã®è§£å床ã§ååšããããæ°ã«ããå¿ èŠããªããªããŸããã
ã¯ãŒã¯ãããŒã¬ã€ã€ãŒïŒ
ã«ãŒãã«ã¬ã€ã€ãŒã«å±ãããGUIãæ§æããªãå®è£ æžã¿ã¢ã«ãŽãªãºã ã¯ãã¹ãŠãç¹å®ã®äžé£ã®ã¯ãŒã¯ããã»ã¹ã®ã¯ã©ã¹ã«é 眮ããå¿ èŠããããŸãã ãããã®ããã»ã¹ã¯ããããç¬èªã®ã¹ã¿ã€ã«ã§èšèšãããŠãããGUIã®å¯Ÿå¿ããã¯ã©ã¹ã®ã€ã³ã¹ã¿ã³ã¹ã«ãªã³ã¯ãè¿œå ããããšã«ãããã¢ããªã±ãŒã·ã§ã³ã®äž»èŠéšåã«æ¥ç¶ããŸãã ã»ãšãã©ã®å Žåããããã®ããã»ã¹ã¯ãã¹ãŠèŠèŠçã§ã¯ãããŸããã ãã ããããšãã°ãæå®ããã衚瀺ã¢ã«ãŽãªãºã ã䜿çšããŠãäºåå®çŸ©ãããã¢ãã¡ãŒã·ã§ã³ãã¬ãŒã ã®é·ãã·ãŒã±ã³ã¹ãå®è£ ããå¿ èŠãããå Žåãªã©ãããã€ãã®äŸå€ããããŸãã
. flow . Google , , .
13
// Analytics [Analytics passedEvent:ANALYTICS_EVENT_PEOPLE_SELECT ForCategory:ANALYTICS_CATEGORY_PEOPLE WithProperties:nil];
, , . . , , , .
, . «» « ». , «» «» .
â â « ». , flow «» , (Network Layer, Validation Items).
(callback), . , .
, , - . , . , , , , . , â , . . . , , .
Local storage:
, , , , . CoreData. , , , Apple , .
. CoreData , . , , CoreData . , , , , , , .
CoreData ( habrahabr.ru/post/191334 ), , , , , .
, . , , .
NSDictionary :
- , .
- , POST (. . , , , POST ).
- .
- .
- ACID : en.wikipedia.org/wiki/ACID
- .
- .
- .
- (1 ).
/ iOS SDK NSDictionary , .
, . , .
, , , , 5, , , , , , , ViewController . () SQL ( ), , , . , , . , .
CoreData.
CoreData . - , . API profile, copyDataFromRemoteJSON, , ( NSManagedObject).
, :
14
[[Client client] profile:@{} success:^(id response) { [[Member getCurrentMember] copyDataFromRemoteJSON:[response valueForKey:@"data"]]; } fail:^(id response) { }];
, callback API , , , .
:
- .
- , . .
- , , .
- ( ) . .
- . (. . , , , , /, , ).
- ,
:
, NSFetchController , . , . . - . . , , , .
:
- , ( ):
- , , SQLite , «» . , - , , CoreData SQLite.
- , .
- . , , . , .
- Database , , , .
- ACID SQLite CoreData. . MagicRecords.
- . , , , , .
- CoreData . , CoreData .
- , , , . , CoreData .
- , . , CoreData .
- , :
- CoreData , .
- , 4S .
- . , MagicalRecords (https://github.com/magicalpanda/MagicalRecord) .
CoreData, , , . â CoreData , , , , NoSQL XML.
MagicalRecords , UITableViewController, NSFetchController CoreData. , , . . . CoreData UI.
, CoreData , , , , :
1
API . , , , .
:
, .
, , .
.
2
: CoreData JSON , . , , , .
:
- « » JSON .
- , . . .
- .
- , .
- SQLite .
- .
çµè«ïŒ
, , , . , , GUI . -, UITabbar, -, , MVC MVVM. , . . , , .
, , .