モバイルアプリ開発の "標準"を探る #CookpadTechConf

9278c3a06b8d8752fb913dea93f959c1?s=47 FUJI Goro
January 23, 2016

モバイルアプリ開発の "標準"を探る #CookpadTechConf

9278c3a06b8d8752fb913dea93f959c1?s=128

FUJI Goro

January 23, 2016
Tweet

Transcript

  1. ϞόΠϧΞϓϦ։ൃͷ ඪ४Λ୳Δ $PPLQBE5FDI$POG SE+BO '6+*(PSPHPSPGVKJ!DPPLQBEDPN

  2. ͸͡Ίʹ • ໊લ • FUJI Goro (GitHub: gfx, Twitter: @__gfx__)

    • ෦ॺ • ٕज़෦ ϞόΠϧ։ൃج൫ • ۙگ • Ϛάωοτגࣜձࣾʹग़޲தʢ2015೥9݄~ʣ
  3. ͜ͷτʔΫͷഎܠ • 2016೥1݄ݱࡏɺΫοΫύου͸εϚϗ΍λϒϨοτͳ ͲɺϞόΠϧ୺຤ͰͷΞΫηε͕ա൒਺Λ௒͍͑ͯΔ • ͦΕΏ͑ʹϞόΠϧΞϓϦ։ൃͷن໛͕େ͖͘ͳͬͨ • ୯ҰͷAndroidΞϓϦɺiOSΞϓϦʹͷΈؔΘΔΤϯδ χΞ͸૬ରతʹগͳ͘ͳͬͨ •

    ҰํͰʮΫοΫύουʯ͸αʔϏεͷण໋͕௕҆͘ఆ ͯ͠։ൃɾӡ༻Ͱ͖Δ͜ͱ͕ٻΊΒΕΔ
  4. ϞόΠϧ୺຤͔ΒͷΞΫηεͷ಺༁ • PC vs εϚϗ • ΞΧ΢ϯτ࣋ͪϢʔβ͸ʮεϚϗͷΈʯ͕8ׂ • ήετϢʔβͷ͏ͪʮεϚϗʯ͸7ׂ •

    ΞϓϦ vs ΢Σϒ • ΞΧ΢ϯτ࣋ͪϢʔβ͸ʮΞϓϦͷΈʯ͕6ׂ • ήετϢʔβͷ͏ͪʮΞϓϦʯ͸1ׂ
  5. ։ൃʹ͓͚Δʮඪ४ʯͱ͸ʁ • ʮඪ४తͳ։ൃʯΛʮޮՌͱίετͷόϥϯε͕Α ͘ೲಘײͷ͋Δ։ൃʯͱߟ͑Δ • ͭ·Γʮඪ४తͰͳ͍։ൃʯͱ͸ʮௐ΂ͯ΋Θ͔Β ͳ͍ൿ఻ͷλϨ͕ଟ͘ɺཧෆਚʹײ͡Δ։ൃʯͱͳ Δ • ʮރΕٕͨज़ʯͷ͜ͱͱ͸ݶΒͳ͍ɻ؀ڥͷมԽʹ

    ͍͍ͭͯ͘͜ͱ΋େࣄɻ
  6. ΫοΫύουͷߟ͑Δ ඪ४తͳϞόΠϧΞϓϦ։ൃ w ৽ٕज़ͷಋೖ w $* 5FTU 2" w '54

  7. ৽ٕज़ͷಋೖ

  8. ͜͜Ͱ͍͏ʮ৽ٕज़ʯͱ͸ • ϓϩάϥϛϯάݴޠʢe.g. Swiftʣ • ϑϨʔϜϫʔΫ΍ϥΠϒϥϦʢe.g. RxJavaʣ • ϓϩτίϧʢe.g. HTTP/2ʣ

    • σʔλϑΥʔϚοτʢe.g. WebPʣ • ΞʔΩςΫνϟʢe.g. MVVM, Clean Architectureʣ • ͦͷଞιϑτ΢ΣΞɾαʔϏε
  9. ৽ٕज़Λಋೖ͢Δͱ͍͏͜ͱ • جຊతʹੵۃతʹ࠾༻͢Δํ਑ • ͦΕ͕Ͳ͏͍͏໰୊Λղܾ͢Δͷ͔Λ͖ͪΜͱ໌Β ͔ʹ͢Δ͜ͱ • ʮ࢖͏ਓ͸ಋೖऀ͚ͩʯ͸ආ͚Δ΂͖ࣄଶ • ৽ٕज़ಋೖͷࡍ͸ࣾ಺ษڧձ΍ϒϩάͳͲͰੵۃ

    తʹܒ໤׆ಈΛߦͳ͍ͬͯΔ • cf. Android։ൃͰRxJavaΛνʔϜʹಋೖͨ͠࿩
  10. ಋೖࡁΈɾݕ౼தͷٕज़ • ಋೖࡁΈ • WebP, Shared Web Credentials, Smart Lock

    for Passwords, Retrolambda, Dokumi, Pull-Request Builder • ݕ౼த • Swift, Kotlin, fastlane, Issue Tracking System, CI as a Service (Travis, CircleCI)
  11. ྫ4XJGU • 2015೥12݄ʹOSSԽ͞ΕͨiOS༻ͷϓϩάϥϛϯάݴޠ • ৽نͰ͸SwiftΛ࢖ͬͨΞϓϦ΋͋Γ • طଘͷObjective-CΛॻ͖׵͑Δͷ͸Ұྫ͚ͩ͋Γ • Global Cookpad

    iOS app • SwiftͷӨڹͰ࣮૷͞ΕͨObjective-Cͷ৽ػೳ͸ੵۃతʹ ࢖͍ͬͯ͘ํ਑ʢͨͱ͑͹δΣωϦΫεʣ • AppleʹΑΓະདྷ͕໿ଋ͞Ε͍ͯΔ
  12. ྫ,PUMJO • JetBrainsࣾͷ։ൃ͢ΔJVM༻ͷϓϩάϥϛϯάݴޠ • Android༻ͷϓϩάϥϛϯάݴޠͱͯ͠஫໨͞Ε͍ͯΔ • ߏจ͸ (Java + Swift)

    / 2 ͱ͍ͬͨͱ͜Ζ • ݴޠ࢓༷͸͔ͳΓΑ͘IDEͷαϙʔτ΋े෼ • ϥΠϯλΠϜͷϑοτϓϦϯτ΋1MBఔ౓ͱখ͞Ί • Javaͷࢿ࢈Λͦͷ··࢖͑ͯίʔυྔ͸JavaΑΓগͳ͍ • ͨͩ͜ΕʹΑͬͯʮԿΛղܾ͢Δͷ͔ʯ͸͸͖ͬΓͱ͠ͳ͍
  13. $* 5FTU 2"

  14. ϞόΠϧΞϓϦͷಛ௃ʢʣ • Ϣʔβʔ͕࢖͏όʔδϣϯΛ੍ޚͰ͖ͳ͍ • Ϣʔβʔ͕ΞϓϦͷΞοϓσʔτΛ͢Δͱ͸ݶΒͳ͍͠ɺ ࣮ࡍΞοϓσʔτΛ͠ͳ͍Ϣʔβ͸͍Δ • ʮΞοϓσʔτͷڧ੍ʯ͸͠ͳ͍ํ਑Ͱ͖͍ͯΔ • Android͸৽͍͠ύʔϛογϣϯΛ௥Ճ͢ΔͱݦஶʹΞοϓ

    σʔτ཰͕͕͞Δ • ύʔϛογϣϯΛ௥Ճ͢ΔͱࣗಈΞοϓσʔτ͕ޮ͔ͳ ͘ͳΔͨΊɻAndroid 6.0Ͱվળ͞Ε͕ͨະීٴ
  15. ϞόΠϧΞϓϦͷಛ௃ʢʣ • ࣮ߦ؀ڥΛ੍ޚ͢Δ͜ͱ΋Ͱ͖ͳ͍ • ୺຤ͷεϖοΫ / OSͷόʔδϣϯ / ௨৴؀ڥ͸· ͪ·ͪ

    • ΢ΣϒΞϓϦΑΓ΋ࣦഊ͕ॏ͘ςετ΋೉͍͠ • ςετίʔυ΋΢ΣϒΞϓϦΑΓॻ͘ͷ͕೉͍͠ • ίʔυϨϏϡʔɾCIɾQAͳͲͷ඼࣭؅ཧ͕ॏཁ
  16. $*+FOLJOT NVMUJTMBWFT • Android͸Linux/EC2 • iOS͸Mac࣮ػ • Travis CI, Circle

    CIͳͲ΋ݕ౼͕ͨ͠ະಋೖ • ίετʹରͯͦ͜͠·Ͱར఺͕ͳ͍ͱ͍͏൑அ • ؀ڥΛ੍ޚ͠΍͍͢ͱ͍͏ར఺Λͱ͍ͬͯΔ
  17. "OESPJE$*Ϛγϯ ςετσόΠεͷมભ 1. EC2 + emulator 2. Macbook ProʢiOS CIͱಉ͡Ϛγϯʣ

    + ࣮ػ୺຤ 3. ϋΠεϖοΫLinuxϚγϯ + ࣮ػ୺຤ • εέʔϧΞοϓͰͦͦ͜͜շద 4. EC2 + emulator • ؆୯ʹεέʔϧΞ΢τͰ͖ΔΑ͏ʹͨ͠ • ϨΠςϯγΑΓ΋εϧʔϓοτΛͱͬͨ݁Ռ
  18. 1VMM3FRVFTU#VJMEFS • JenkinsͷpluginͰɺPR͝ͱʹCIΛىಈ͢Δ • master branchʹ௚઀commit / push͢Δͷ͸ېࢭ • Ϗϧυʴςετ͕ύε͠ɺϨϏϡʔΛ௨ͬͨΒϚʔδՄ

  19. 1VMM3FRVFTU#VJMEFS͕ߦ͏͜ͱ • Pull-Request Builder (+Dokumi) • ςετΛ࣮ߦͯ͠PRʹࣦഊϝοηʔδΛϙετ • ੩తղੳΛ࣮ߦͯ͠PRͷ֘౰ՕॴʹϝοηʔδΛϙετ •

    ػցʹίʔυϨϏϡʔͤͯ͞ਓͷෛ୲ΛݮΒ͢ • ΞϓϦύοέʔδΛϏϧυʢapk, ipaʣ • ΞϓϦύοέʔδΛDeployGateʹΞοϓϩʔυ • ΤϯδχΞҎ֎Ͱ΋։ൃதͷ৽ػೳΛࢼ͠΍͘͢
  20. 6OJU5FTU2" • ςετΤϯδχΞ2ਓମ੍ • 2ਓڞίʔυΛॻ͚Δ • ςετίʔυ͸ϓϥοτϑΥʔϜ͝ͱͷඪ४ςετϑϨʔ ϜϫʔΫʢAndroid JUnit4, XCTestʣ

    • ։ൃऀ΋ॻ͘͠ɺςετΤϯδχΞ΋ॻ͘ • Appium΍಺੡πʔϧʹΑΔࣗಈԽ͞Εͨςετ΍ɺख࡞ ۀʹΑΔςετ΋࣮ࢪ
  21. 'BJMVSF5FBDIFT4VDDFTT

  22. 'BJMVSF5FBDIFT4VDDFTT • ো֐ϨϙʔτͷϑΥʔϚοτɿ • ໰୊ʹ͍ͭͯνʔϜͰ࿩͠߹͏͜ͱ • ͳͥͦͷ໰୊Λൃੜͤͯͨ͞ͷ͔Λهࡌ͢Δ͜ͱ • ࠶ൃ๷ࢭࡦͱͦͷ࣮ࢪ೔Λهࡌ͢Δ͜ͱ •

    ʮؾΛ෇͚Δʯʮ஫ҙ͢Δʯͱ͍ͬͨओ؍తͳ๷ ࢭࡦ͸ೝΊͳ͍
  23. '54͸ࢥߟͷϑϨʔϜϫʔΫ • ໰୊͕͋Ε͹ࠜຊతʹղܾ͢΂͖ͱ͍͏Ձ஋؍ • ʮͳͥ͜ͷ໰୊͕ى͖ͨͷ͔ʯΛ෼ੳٕͯ͠ज़తͳ ղܾࡦʹམͱ͜͠Ή • ։ൃʹ͓͚Δʮඪ४ʯΛ࡞͍ͬͯ͘աఔͰ΋͋Δ

  24. ࣮ࡍͷ'54͔Β ͍͔ͭ͘ϐοΫΞοϓ

  25. "OESPJEΞϓϦͰ 8JEHFU͕͋Δͱ͖ʹ Ξοϓσʔτ͢ΔͱϩάΞ΢τ

  26. $PPLQBE"QQ8JEHFU • AndroidͷϗʔϜʹஔ͚Δ খ͍͞ΞϓϦ • ىಈϑϩʔ͕ී௨ͷΞϓ Ϧͱҧ͏ʢ͜ͱ͕͋Δʣ

  27. 8JEHFU͕͋Δͱ͖ʹΞοϓσʔτ͢ΔͱϩάΞ΢τ • WidgetΛؚΊͯز͔ͭͷύλʔϯͰىಈϑϩʔ͕গ ͚ͩ͠ҧ͏ • ΞϓϦέʔγϣϯͷىಈ࣌ ʢApplication#onCreate()ʣʹ͢΂ͯͷॳظԽΛߦ͏ ͱ஗͗͢ΔͷͰɺผͷͱ͜Ζʹ੾Γ෼͚͍ͯͨ • ݁Ռɺ௨ৗͱҧ͏ىಈϑϩʔΛऔΔ৔߹ʹ͢΂ͯͷ

    ॳظԽ͕૸Βͳ͍ঢ়ଶͩͬͨ
  28. ղܾํ๏ • ॳظԽΛ Application#onCreate() Ͱߦ͏Α͏ʹͨ͠ • ͦͷࡍɺॳظԽϓϩηεΛݟͳ͓ͯ͠ߴ଎Խͨ͠ • ͜ͷॳظԽ͸εϓϥογϡεΫϦʔϯ͕ग़Δલͷ ͜ͱͳͷͰɺͦΕͳΓʹ࣌ؒΛ࢖ͬͯߴ଎Խ͢Δ

    Ձ஋͕͋Δ • ʮؾΛ͚࣮ͭͯ૷͢Δʯ͸ো֐ͷ΋ͱ
  29. / ໰୊Ͱ"1*ΞΫηε ͯ͠αʔόʔͷෛՙ্͕ঢ

  30. / ໰୊ • ͋ΔϦιʔεʢͨͱ͑͹RecipeʣΛNݸऔಘͨ͋͠ ͱɺͦͷϦιʔεʹඥͮ͘ผͷϦιʔεʢͨͱ͑͹ UserʣΛऔಘ͠Α͏ͱͯ͠͞ΒʹNճͷAPIΛൃߦ ͯ͠͠·͍ύϑΥʔϚϯε͕ྼԽ͢Δ໰୊ • RailsͰ͸Α͋͘Δ͜ͱͰɺbulletͱ͍͏N+1໰୊Λ ൃݟ͢Δઐ༻ͷgem·Ͱ͋Δ

  31. J04ΞϓϦͰ/ ໰୊ʹؾͮ͘ • ίʔυϨϏϡʔ΍QA Λ௨աͯ͠ɺϦϦʔεޙʹAPI αʔόͷෛՙ͕ߴ·ͬͯൃ֮ • αʔόʔαΠυͷ࣮૷΋Α͘ͳ͔ͬͨͷͰͦͷվ ળͰ͋Δఔ౓͸͠ͷ͛ͨ •

    ΞϓϦͷڍಈͦͷ΋ͷ͸ਖ਼ৗ͕ͩো֐͕͓͖Δͱ͍ ͏ঢ়گͩͬͨ
  32. ղܾࡦɿνΣοΫϦετʹ߲໨Λ௥Ճ • pull-requestʹಛఆͷϥϕϧΛ͚ͭΔͱɺͦΕʹԠ͡ ͨνΣοΫϦετ͕షΒΕΔ࢓૊Έ͕͋Δ • ͦΕΛ֦ுͯ͠νΣοΫͰ͖ΔΑ͏ʹͨ͠ • ߋʹΞϓϦ͔ΒͷϦΫΤετΛΩϟϓνϟͯ͠νΣο Ϋ͢Δ࢓૊ΈΛςετʹ૊ΈࠐΜͩ

  33. 1SP(VBSEͱͷઓ͍

  34. 1SP(VBSE • JavaͷόΠτίʔυͷͨΊͷminifyπʔϧ • γϯϘϧ໊ͷ୹ॖɺόΠτίʔυ࠷దԽɺϝλσʔλͷ࡟আɺσο υίʔυ࡟আɺ೉ಡԽͳͲΛߦ͏ • γϯϘϧ໊ͷ୹ॖͱσουίʔυ࡟আͰAPKαΠζΛখ͘͢͞Δޮ ՌΛظ଴ •

    ProGuard͸ͦͷ࢓্༷ɺΞϓϦͷػೳෆશΛඇৗʹى͜͠΍͍͢ • ͔͠͠APKαΠζͷॖখޮՌ͸਺ϝΨόΠτʹٴͿͷͰ࢖Θͳ͍ Θ͚ʹ͸͍͔ͳ͍
  35. BTTVNFOPTJEFF⒎FDUT • σουίʔυ࡟আʹ͓͍ͯɺಛఆͷϝιου͕෭࡞ ༻Λ࣋ͨͳ͍ͱ͍͏ώϯτΛ༩͑ΔΦϓγϣϯ • ϩΨʔͷϝιουΛ "no side-effects" ͱ͢Δ͜ͱͰɺ Log.d()ͷݺͼग़͠ΛόΠτίʔυ͔Β࡟আͰ͖Δ

    • ΫοΫύουΞϓϦͰ͸͜ΕͰϩάग़ྗΛ࡟͍ͬͯ ͕ͨ…
  36. ໰୊ϦϦʔεϏϧυͰϩάग़ྗ • ͋Δόʔδϣϯ͔Βϩάग़ྗ͕ແޮԽ͞Εͳ͍ঢ়ଶ ʹͳ͍ͬͯͨ • ͦ͜Ͱ -assumenosideeffects Ͱ Log.d() Λ࡟আ͢Δ

    ͜ͱʹͨ͠ɿ BTTVNFOPTJEFF⒎FDUTa DMBTTBOESPJEVUJM-PH\NFUIPET^
  37. ໰୊"1*αʔό΁ͷෛՙ૿େ • ΄Ͳͳͯ͘͠APIαʔό΁ͷෛՙ͕ߴ·͖ͬͯͨ • ೝূϦΫΤετ͕ա৒ʹൃߦ͞Ε͍ͯΔΒ͍͠ • ΫοΫύουΞϓϦ͸ىಈ࣌ʹೝূΛߦ͏Α͏ʹͳͬ ͍ͯΔ • ೝূ͕׬͍ྃͯ͠ͳ͍ͱ͖ʹൃߦ͞Εͨͦͷଞͷ

    APIίʔϧ͸ೝূ͕௨Δ·Ͱ଴ͭΑ͏ʹͳ͍ͬͯΔ w w
  38. "1*ίʔϧ͸ೝূ͕௨Δ·Ͱ଴ͭ w w • ͜ͷ଴ͪ߹Θͤʹ Object#wait() Λ࢖͍ͬͯͨ • -assumenosideeffects class

    Log { <methods>; } ͸Ϋϥε ֊૚ΛḪͬͯద༻͞ΕΔ • LogΫϥεͷεʔύʔΫϥεͰ͋ΔObjectΫϥεͷશϝ ιου͕෭࡞༻ͳ͠ͱղऍ͞ΕΔʂ • ͜ͷΑ͏ͳܦҢͰ Object#wait() ͷݺͼग़͕͠όΠτίʔ υ͔Β࡟আ͞Ε͍ͯͨ…
  39. ͳͥϦϦʔε·Ͱؾ෇͔ͳ͔͔ͬͨ • APIίʔϧͷೝূ଴͕ͪյΕͨ݁Ռɺೝূ͕ͱ͓Βͣʹ APIίʔϧ͕͞ΕͯΤϥʔʹͳ͍ͬͯͨ • ͔͠͠ɺAPIΫϥΠΞϯτʹ࣮૷͞ΕͨࣗಈϦτϥΠػ ߏ͕͏·͘ಈ͍ͯ͠·͍ɺϦτϥΠ͢Δؒʹೝূ͕ͱ͓ͬ ͯଓ͘APIίʔϧ͕੒ޭͯ͠͠·͏ • ·ͨ΋ΞϓϦͷڍಈͦͷ΋ͷ͸ਖ਼ৗ͕ͩো֐͕͓͖Δͱ

    ͍͏ঢ়گ
  40. "1*ݺͼग़͠ଟ͗͢໰୊ͷࠜຊղܾ • ΞϓϦ্ͰΦʔόʔϨΠදࣔ͢ΔϩΨʔΛͭ͘Γɺ status 4xx, 5xxͷAPIݺͼग़͠ΛͦͷϩΨʔͰه࿥͢Δ Α͏ʹͨ͠ʢAndroid, σόοάϏϧυͰͷΈ༗ޮʣ • ͦͷޙɺ௨৴पΓͷτϥϒϧ͸ΦʔόʔϨΠϩΨʔ

    ͷ͓͔͛Ͱ͍ͩͿॿ͔ͬͨ • ·ͨ௨৴ྔΛଌఆ͢ΔπʔϧΛͭ͘ΓɺQAʹऔΓೖ Εͨ
  41. ͓ΘΓ