iOSアプリのリジェクトリスクを早期に発見するための取り組み

9bcd328daf60fe29dc9970f6cfc26730?s=47 Kenta Kase
September 06, 2019

 iOSアプリのリジェクトリスクを早期に発見するための取り組み

iOSDC Japan 2019
https://fortee.jp/iosdc-japan-2019/proposal/d51e7062-2eb1-4a86-bf5f-4928fa3b04c8

iOSアプリ開発は年々複雑化しています。次々と追加される新デバイスや新しいAPIへの対応など技術的な要因はいくつかありますが、それ以外にも更新され続けているApp Store Reviewガイドラインやその他のApp Storeに提出できるアプリの要件を遵守する必要があるのもその要因の1つです。

ガイドラインや提出できるアプリの要件は日々修正、追加されているため常に最新情報を把握することは難しいです。ですがこれを怠ってしまうと、いざリリースという段階になってリジェクトされてしまい、思わぬ対応コストとスケジュールの変更を余儀なくされる可能性があります。

この問題を解決するため、ビルドされたアプリに対してガイドラインやApp Storeに提出できるアプリの要件を遵守できているか機械的にチェックするツールを作成しました。このツールはFastlaneプラグインとして提供され、Fastlaneによるビルドパイプラインに簡単に組み込むことが可能です。ツールによるチェック結果はコンソールログ以外にHTMLレポートとして出力が可能で、検証を担当されているQAチームと連携してリリース前の段階でアプリに問題が無いことを確認しています。

本発表では以下の内容をお話しします

- このツールを開発した経緯
- 実際にどのような項目をチェックしているのか
- チェック機能の実装方法
- QAチームとの連携
- ガイドラインを追い続けるための情報源

iOS開発においてApp Store ReviewガイドラインとApp Storeに提出できるアプリの要件を満たすために気をつけるべき注意点と、今回紹介するチェックツールと同様のものを自作するために必要な知識を持ち帰ってもらいたいと思います。

9bcd328daf60fe29dc9970f6cfc26730?s=128

Kenta Kase

September 06, 2019
Tweet

Transcript

  1. iOSΞϓϦͷ
 ϦδΣΫτϦεΫΛૣظʹ ൃݟ͢ΔͨΊͷऔΓ૊Έ iOSDC Japan 2019 Ճ੉݈ଠ @Kesin11 ൃද։࢝લʹ͓खݩʹipaΛ͝༻ҙ͠
 zipղౚͯ͠௖͚ΔͱΑΓָ͠Ή͜ͱ͕Ͱ͖·͢

  2. ࣗݾ঺հ • ॴଐɿDeNAͷSWETάϧʔϓ
 (SoftWare Engineer in Test) • Twitterɿ@Kesin11 •

    GitHubɿKesin11 • ͓࢓ࣄɿCI/CD׆༻αϙʔτɺؔ࿈ٕज़ͳͲͷݕূ • ൒೥લ·Ͱ͸QAνʔϜͷࣗಈԽαϙʔτ
  3. DeNA Testing Blog swet.dena.com

  4. ओ࠵ษڧձ TestNight ࣍ճ͸10/02 CICD Test Night #5

  5. ಥવͰ͕͢ΫΠζͰ͢

  6. લճApp Store ReviewΨΠυ ϥΠϯ͕ߋ৽͞Εͨͷ͸͍ͭʁ • ᶃɹ1-3݄ • ᶄɹ4-6݄ • ᶅɹ7-8݄

    • ᶆɹࠓ೥͸·ͩߋ৽͞Ε͍ͯͳ͍
  7. લճApp Store ReviewΨΠυ ϥΠϯ͕ߋ৽͞Εͨͷ͸͍ͭʁ • ᶃɹ1-3݄ • ᶄɹ4-6݄ • ᶅɹ7-8݄

    • ᶆɹࠓ೥͸·ͩߋ৽͞Ε͍ͯͳ͍
  8. લճApp Store ReviewΨΠυ ϥΠϯ͕ߋ৽͞Εͨͷ͸͍ͭʁ • ਖ਼ղ: ᶄ 4-6݄ʢ۩ମతʹ͸6/3ʣ • ࢠڙ޲͚ΞϓϦͰͷ3rd޿ࠂ΍σʔλऩूͷ੍ݶ

    • MDM͕ڐ͞ΕΔέʔεʹϖΞϨϯλϧίϯτ ϩʔϧΛ௥Ճ • ҰํͰऩूͨ͠σʔλͷऔΓѻ੍͍ݶΛ໌ه
  9. ։ൃऀ΍૊৫ͱͯ͠
 ϓϥοτϑΥʔϜ͔Βͷ
 Ξφ΢ϯεΛ
 ೺Ѳ͓ͯ͘͜͠ͱ͸େࣄ

  10. ࣾ಺ͷ։ൃɾϦϦʔεϑϩʔ ϑϩʔͷޙ΄Ͳ໰୊͕ى͖ͨͱ͖ͷख໭Γ͕େ͖͍

  11. ৽ػೳ͕૿͑Ε͹
 ReviewΨΠυϥΠϯ΋૿͑Δ ਓ͕ؒશͯνΣοΫ͍ͯ͘͠ମ੍͸
 ͍͔ͭݶք͕དྷͯ͠·͏

  12. ϦδΣΫτϦεΫΛݕࠪ͢Δ FastlaneϓϥάΠϯΛ࡞Γ·ͨ͠

  13. AppChecker • FastfileʹϏϧυޙͷipaͷύεΛॻ͚ͩ͘Ͱ؆ ୯ʹಋೖՄೳ

  14. None
  15. None
  16. ܯࠂϨϕϧ • error • App StoreʹΞοϓϩʔυ࣌ʹΤϥʔʹͳΔɺ
 ͋Δ͍͸৹ࠪ࣌ʹϦδΣΫτͷϦεΫ͕ߴ͍ • warn •

    error΄Ͳ໰୊ʹͳΒͳ͍͜ͱ΋͋Δ͕मਖ਼͕๬·͍͠ • info • ৚݅࣍ୈͰwarnఔ౓ͷϦεΫ͕͋Δ΋ͷ • QAଆͰ༻్Λ೺Ѳ͓͖͍߲ͯͨ͠໨
  17. νΣοΫ͍ͯ͠Δ߲໨ - error • App StoreʹΞοϓϩʔυ࣌ʹΤϥʔʹͳΔɺ ͋Δ͍͸৹ࠪ࣌ʹϦδΣΫτͷϦεΫ͕ߴ͍ • ݕ஌͞Εͨ৔߹͸ݪଇͱͯ͠मਖ਼ඞਢ

  18. νΣοΫ͍ͯ͠Δ߲໨ - error • iOS SDKόʔδϣϯ͕ݹ͗͢ͳ͍͔ • Xcodeόʔδϣϯ͕ݹ͗͢ͳ͍͔ • ΞΠίϯαΠζ͕ἧ͍ͬͯΔ͔

    • PrivateFrameworkΛϦϯΫ͍ͯ͠ͳ͍͔ • ඇެ։url schemeΛ࢖͍ͬͯͳ͍͔ • ϓϥΠόγʔʹؔ͢Δػೳͷઆ໌จ͕ۭͰͳ͍͔ • 64bitରԠ
  19. νΣοΫ͍ͯ͠Δ߲໨ - error • iOS SDKόʔδϣϯ͕ݹ͗͢ͳ͍͔ • Xcodeόʔδϣϯ͕ݹ͗͢ͳ͍͔ • ΞΠίϯαΠζ͕ἧ͍ͬͯΔ͔

    • PrivateFrameworkΛϦϯΫ͍ͯ͠ͳ͍͔ • ඇެ։url schemeΛ࢖͍ͬͯͳ͍͔ • ϓϥΠόγʔʹؔ͢Δػೳͷઆ໌จ͕ۭͰͳ͍͔ • 64bitରԠ
  20. iOS SDKόʔδϣϯ
 Xcodeόʔδϣϯ
 ݹ͗͢ͳ͍͔

  21. iOS SDKɺXcodeͷόʔδϣϯ • ݹ͍όʔδϣϯͰϏϧυͨ͠ipa͸ϦϦʔεͰ͖ͳ͍ • ݱࡏ͸iOS 12.1 SDKҎ্ͰϏϧυ͕ඞཁ • ipa಺ͷinfo.plist͔Β֬ೝ͕Մೳ

    • DTXcode: Xcodeͷόʔδϣϯ • DTPlatformVersion: iOS SDKͷόʔδϣϯ
  22. iOS SDKɺXcodeͷόʔδϣϯ • ࣮ࡍʹipaΛղౚͯ͠த਎ΛݟͯΈ·͠ΐ͏ • plutil -p {ΞϓϦ໊}.app/Info.plist iOS 12.1

    SDKͰϏϧυ͞Εͨ Xcode 10.1ͰϏϧυ͞Εͨ
  23. iOS SDKɺXcodeͷόʔδϣϯ • πʔϧʢrubyʣͰͷ࣮૷ • ॳظ͸FastlaneCore::IpaFileAnalyzerͰInfo.plistͷத਎Λࢀর • ipa಺ͷϑΝΠϧ਺͕64KΛ௒͑Δ৔߹ɺrubyzip͕ݪҼͰղ ౚͰ͖ͳ͔ͬͨ •

    ֎෦ϓϩηεͰunzipΛ࢖ͬͯzipղౚΛࣗલͰߦ͏Α͏ʹมߋ • ஋ΛGem::VersionͷΦϒδΣΫτʹͯ͠όʔδϣϯൺֱ
  24. ΞΠίϯͷαΠζͷछྨ͕
 ෆ଍͍ͯ͠ͳ͍͔

  25. ΞΠίϯͷαΠζ • iPhone, iPadຖʹඞཁͳαΠζ͕଍Γ͍ͯͳ͍ ͱΞοϓϩʔυͰ͖ͳ͍ • Human Interface Guidelinesͷicons and

    ImagesΛࢀর • https://developer.apple.com/design/human-interface- guidelines/ios/icons-and-images/app-icon/
  26. ΞΠίϯͷαΠζ • xcrun --sdk iphoneos assetutil --info {ASSETS_CAR_PATH} • ipa಺ͷAssets.carΛࢦఆ͢Δͱ

    ΞΠίϯΛؚΉΞηοτͷϝλ σʔλ͕jsonͰऔಘͰ͖Δ • jsonΛύʔεͯ͠ඞཁͳαΠζ ͷఆٛͱൺֱͯ͠ෆ଍͍ͯ͠ ͳ͍͔νΣοΫ
  27. PrivateFrameworkΛ
 ࢖͍ͬͯͳ͍͔

  28. PrivateFrameworkΛ࢖͍ͬͯͳ͍͔ • ͦ΋ͦ΋PrivateFrameworkͱ͸ʁ • ϔομʔ͕ެ։͞Ε͍ͯͳ͍Framework • ී௨͸ϦϯΫ΋ݺͼग़͢͜ͱ΋Ͱ͖ͳ͍ • ΋͠࢖͍ͬͯΔͱϦδΣΫτର৅

  29. ϦϯΫ͞Ε͍ͯΔ
 FrameworkΛௐ΂Δ

  30. ΞϓϦͷόΠφϦຊମ • otool -L {ΞϓϦ໊}.app/{ΞϓϦ໊} • όΠφϦʹϦϯΫ͞Ε͍ͯΔ΋ͷΛௐ΂Δ͜ͱ͕ Ͱ͖Δ • ipaΛղౚͯ͠ɺΞϓϦຊମͷόΠφϦʹotool

    Λ͔͚Δ
  31. None
  32. 3rdύʔςΟͷFramework

  33. γεςϜͷFramework

  34. Swiftؔ܎ͬΆ͍ʁ

  35. ґଘ͍ͯ͠Δ֎෦SDK • ࣮͸ຊ౰ʹௐ΂͍ͨͷ͸ͪ͜Β • ֎෦SDK͕ѱ͞Λ͍ͯ͠ͳ͍͔֬ೝ͍ͨ͠ • ղౚͨ͠ipaͷFrameworks/ͷதʹ֎෦SDKͳ ͲͷFrameworkؚ͕·Ε͍ͯΔ

  36. ֤FrameworkͷόΠφϦʹ
 ·ͱΊͯotoolΛ࣮ߦ

  37. QRCodeReader͕ϦϯΫ͍ͯ͠Δ
 Framework

  38. ࣗ෼ͷΞϓϦʹؚ·ΕΔ શͯͷFramework͕
 ϦετΞοϓͰ͖ͨ

  39. PrivateFramework͸
 ؚ·Ε͍ͯΔʁ

  40. ͦ΋ͦ΋Frameworkͷ
 ৔ॴ͸ʁ

  41. Frameworkͷ৔ॴ • /Applications/Xcode.app/Contents/Developer/ Platforms/iPhoneOS.platform/Developer/ SDKs/iPhoneOS.sdk/System/Library/ Frameworks/ • ͜͜ʹ͸iPhoneʹؚ·ΕΔFrameworkͷϔο μʔ͔͠ͳ͍ •

    ౰વPrivateFrameworkͷϔομʔ͸ଘࡏ͠ͳ͍
  42. Frameworkͷ࣮ମ͸
 օ͞ΜͷiPhoneͷதʹ

  43. Ͱ΋࣮͸΋͏Ұͭmacͷதʹ΋ ࣮ମ͕ଘࡏ͠·͢ iOSγϛϡϨʔλʔ

  44. γϛϡϨʔλʔ༻ͷFramework ͷ৔ॴ • /Applications/Xcode.app/Contents/Developer/Platforms/ iPhoneOS.platform/Developer/Library/CoreSimulator/ Profiles/Runtimes/iOS.simruntime/Contents/Resources/ RuntimeRoot/System/Library/Frameworks/ • Frameworks/͕ଘࡏ͢Δಉ֊૚ʹPrivateFrameworks/͕ ଘࡏ͢Δ

    • ͜ͷσΟϨΫτϦ಺Λௐ΂Δ͜ͱͰɺͲͷΑ͏ͳ໊લͷ PrivateFramework͕ଘࡏ͢Δ͔஌Δ͜ͱ͕Ͱ͖Δ
  45. ݕ஌͢΂͖ PrivateFramework͕
 ϦετΞοϓͰ͖ͨ

  46. ࠷ऴతͳνΣοΫͷ࢓૊Έ • otool -LͰΞϓϦʹؚ·ΕΔશͯͷFrameworkΛϦετΞοϓ • ਖ਼نදݱͰҎԼͷFrameworkؚ͕·Ε͍ͯͨΒNGͱ͢Δ • PrivateFrameworks/*.framework • Frameworks/IOKit.framework

    • IOKit͸Frameworks/ʹଘࡏ͢Δ͕ී௨͸࢖͑ͳ͍ • ࢖͏ͱϦδΣΫτ͞ΕΔͷ͸ଟ෼݁ߏ༗໊ͳ࿩
  47. νΣοΫ͍ͯ͠Δ߲໨ - warn • App StoreΞοϓϩʔυ΍৹ࠪͰ100%
 ϦδΣΫτ͞ΕΔͱ͸ݴ͑ͳ͍͕
 मਖ਼͕๬·͍͠

  48. νΣοΫ͍ͯ͠Δ߲໨ - warn • ετΞʹରԠݴޠ͕೔ຊޠͱͯ͠දࣔ͞ΕΔ ͔ • UIRequiredDeviceCapabilitiesʹ࢖͏ػೳ͕ minimumOSVersionΛຬ͍ͨͯ͠Δ͔

  49. νΣοΫ͍ͯ͠Δ߲໨ - warn • ετΞʹରԠݴޠ͕೔ຊޠͱͯ͠දࣔ͞ΕΔ ͔ • UIRequiredDeviceCapabilitiesʹ࢖͏ػೳ͕ minimumOSVersionΛຬ͍ͨͯ͠Δ͔ ࣌ؒͷ౎߹্·ͱΊͯεΩοϓ͠·͢

  50. νΣοΫ͍ͯ͠Δ߲໨ - info • ৚݅࣍ୈͰwarnఔ౓ͷϦεΫ͕͋Δ΋ͷ • QAଆͰ༻్Λ೺Ѳ͓͖͍߲ͯͨ͠໨

  51. νΣοΫ͍ͯ͠Δ߲໨ - info • ϓϥΠόγʔσʔλʹΞΫηε͢Δ Frameworkͷ༻్ • ࢖༻͍ͯ͠ΔόοΫάϥ΢ϯυαʔϏε • λʔήοτσόΠε

    iPhone, iPad༻͔
  52. νΣοΫ͍ͯ͠Δ߲໨ - info • ϓϥΠόγʔσʔλʹΞΫηε͢Δ Frameworkͷ༻్ • ࢖༻͍ͯ͠ΔόοΫάϥ΢ϯυαʔϏε • λʔήοτσόΠε

    iPhone, iPad༻͔
  53. ϓϥΠόγʔσʔλʹ
 ΞΫηε͢ΔFramework

  54. ϓϥΠόγʔσʔλʹΞΫηε͢Δ Framework • ReviewΨΠυϥΠϯΑΓɺऔΓѻ͍ʹ஫ҙ͢ ΂͖σʔλΛऔಘͰ͖ΔFrameworkΛ
 ࢖༻͍ͯ͠Δ͔Ͳ͏͔ • otoolͰ࢖༻͍ͯ͠ΔFrameworkΛௐ΂Δ • QAଆͰ༻్Λ֬ೝ͢ΔͨΊ

  55. ϓϥΠόγʔσʔλʹΞΫηε͢Δ Framework • App Store ReviewΨΠυϥΠϯΛࢀর • 5.1.2 σʔλͷ࢖༻ͱڞ༗ʢviʣ •

    5.1.3 ݈߁͓Αͼ݈߁ʹؔ͢Δௐࠪʢiʣ • ϚʔέςΟϯά΍޿ࠂ໨తͳͲʹ࢖༻ͯ͠͸͍͚ͳ͍ɺͳͲ͕ ఆΊΒΕ͍ͯΔ • ର৅ͱͳΔAPIͳͲ΋໌ه͞Ε͍ͯΔ • ϔϧεέΞ΍ࣸਅͳͲ
  56. AppCheckerΛ
 Ͳ͏׆༻͍͔ͯ͘͠

  57. AppCheckerಋೖޙͷશମͷϑϩʔ Logo by
 https://www.bitrise.io/presskit
 https://github.com/logos

  58. HTMLͷϨϙʔτ શମ݁ՌͷαϚϦʔ

  59. ։ൃऀ͔Βͷϝοηʔδ

  60. ผͷYAMLʹهࡌͨ͠ϝοηʔδ͕
 సࣸ͞ΕΔ࢓૊Έ

  61. ݩͷInfo.plist΋ࢀরͰ͖ΔΑ͏ʹදࣔ

  62. ։ൃɾQAͰͷνΣοΫ͕
 ࣗಈԽɺলྗԽ͞Ε·ͨ͠

  63. ΨΠυϥΠϯΛ
 ௥͍ଓ͚Δํ๏

  64. ΨΠυϥΠϯΛ௥͍ଓ͚Δํ๏ • Appleͷσϕϩούʔ޲͚News • https://developer.apple.com/news/ • ཁٻSDKόʔδϣϯߋ৽ͳͲॏཁͳ৘ใ΋ྲྀΕΔ • ࣾ಺ͷաڈͷϦδΣΫτࣄྫΛڞ༗ͯ͠ԣల։ •

    ReviewΨΠυϥΠϯ͕ߋ৽͞ΕͨࡍʹdiffΛऔΔ
  65. ·ͱΊ • ϦδΣΫτϦεΫΛݕ஌͢Δࣾ಺Fastlane
 ϓϥάΠϯΛ࡞੒͠·ͨ͠ • νΣοΫࣗಈԽʹΑΓૣظϑΟʔυόοΫɺ
 HTMLϨϙʔτʹΑΓQAνΣοΫͷলྗԽ • ϦδΣΫτʹΑΔख໭ΓΛͳ͍͖͍ͯͨ͘͠ •

    App Store ReviewΨΠυϥΠϯ͸ৗʹཁνΣοΫ