AppStoreにKids Category向けのアプリを申請して、リジェクト対応した話
Kids Category とは
AppStoreに5才以下〜11才以下を対象とした"子供向け"というカテゴリーがあり、そこに掲載しているアプリのこと。 子供を対象にしたアプリを作成した場合、AppStoreConnectの年齢制限編集で"子供向けに制作に"チェックが必要になる。 そうしないとAppStoreの子供向けカテゴリーに表示されないため、子供が触る機会が少ないアプリになるので対応は必要になる。
ただ子供向けアプリは、17才以上を対象としたアプリと比べて審査が少し厳しくなる。 子供向けアプリは子供向けAppのApp Reviewガイドラインに準拠する必要がある。
子供向けAppのガイドライン
ガイドラインに記載してあるように次の通りにアプリを準拠しなければならない。
- App外へのリンク、課金要素などに関しては子供が触れないようにペアレンタルゲートをつける必要がある。
- 「子ども向け」カテゴリのAppには、他社製の分析機能や広告を組み込むことはできない。
- IDFA(広告ID)を取得してはいけない
- 子供を特定できる情報は取得してはいけない
- 名前
- 生年月日
- メールアドレス など
リジェクト内容
You have selected the Kids category for your app, but it includes links out of the app or purchasing opportunities without first obtaining parental permission. Kids Categoryなのにアプリ内にペアレンタルゲートが組み込まれてない、という内容。
- 対応: ペアレンタルゲートを追加で実装して対応。問題はランダムにする必要がある。他にリリースしてるアプリを参考に実装。
your app appears to use IDFA. アプリ内でIDFAを使っていますよ、という内容。 アプリ内ではIDFAは取得してはいないはずなのに...、ただFirebaseは使っているので、よく調べてみるとFirebase AnalytycsとClashlytycsでIDFAを送信している処理を行なっているみたい。 Firebase Help 「デバイスの識別」より
"デフォルトでは、Firebase SDK はモバイル端末の識別子(例: Android の広告 ID や iOS の広告識別子)を収集し、Cookie に似たテクノロジーを利用します。"
とのこと- 対応: Firebase自体を使うことを削除し、申請したら通った。
- データの収集 - Firebase ヘルプ https://support.google.com/firebase/answer/6318039?hl=ja
アナリティクスとクラッシュログを使いたかったため、FirebaseからReproやAppsFlyerなどのサービスに乗り換えようと検討したが、 いずれもIDFAを取得するコードがSDK内に組み込まれているため、断念。
Repro SDKで取得しているデータ・情報について知りたい | Repro Knowledge Base https://support.repro.io/ja/articles/2001441-repro-sdk%E3%81%A7%E5%8F%96%E5%BE%97%E3%81%97%E3%81%A6%E3%81%84%E3%82%8B%E3%83%87%E3%83%BC%E3%82%BF-%E6%83%85%E5%A0%B1%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6%E7%9F%A5%E3%82%8A%E3%81%9F%E3%81%84
そもそもガイドラインには「子ども向け」カテゴリのAppには、他社製の分析機能や広告を組み込むことはできません。
と記載されているのでFirebase以外も組み込むのは難しそう。
子供を特定しない範囲でデータを収集したい場合は、自分たちでサーバーサイドの部分も実装が必要になるかと思います。
審査をする前に毎回以下の質問が聞かれていたので、ガイドラインに準拠するのは厳格に決められている感じがします。
- Does your app include third-party analytics? If so, please provide details about what data is collected for this purpose.
アプリにサードパーティの分析が含まれていますか?その場合、この目的のために収集されるデータの詳細を入力してください。
- Does your app include third-party advertising? If so, please provide a link to the ad network's publicly-documented practices and policies for kids apps.
アプリにサードパーティの広告が含まれていますか?その場合は、広告ネットワークで公開されている子供向けアプリの慣行とポリシーへのリンクを提供してください。
- Will the data be shared with any third parties? If so, for what purposes and where will this information be stored?
データは第三者と共有されますか?その場合、この情報はどのような目的でどこに保存されますか?
- Is your app collecting any user or device data for purposes beyond third-party analytics or third-party advertising? If so, please provide a complete and clear explanation of all planned uses of this data.
アプリは、サードパーティの分析やサードパーティの広告以外の目的でユーザーまたはデバイスのデータを収集していますか?その場合、このデータのすべての計画された使用法の完全かつ明確な説明を提供してください。
参考
カテゴリと見つけやすさ - App Store - Apple Developer https://developer.apple.com/jp/app-store/categories/
App Store Reviewガイドライン - Apple Developer https://developer.apple.com/jp/app-store/review/guidelines/#kids-category
ペアレンタルゲート - App Store - Apple Developer https://developer.apple.com/jp/app-store/parental-gates/
Main.storyboardをリネームして使うときにハマったこと
Xcodeでプロジェクトを作成したときに元々用意されているMain.storyboardをリネームして使おうとしたときにハマった。
環境
- Xcode11.1
試したこと
- Main.storyboardをProject Navigatorからリネーム
- Info.plistから
Main storyboard file base name
をリネーム - Main Interfaceを確認 リネーム後の名称に置き換わっていることを確認
ビルドすると"NSBundleでMain.storyboardが見つかりません"というエラーが表示される。
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Could not find a storyboard named 'Main' in bundle NSBundle </Users/
今まではこのやり方で問題なかったはずなのに🤔
解決方法
- Info.plistにある"Storyboard Name"にあるValueがMainのままになっていたのでリネームしたら直った。
Info.plist>Application Scene Manifest>Scene Configuration>Application Session Role>Item 0 (Default Configuration)>Storyboard Name⬅︎ココ
- 原因はXcode11, iOS13からInfo.plistに"Application Scene Manifest"の設定が追加されたことにあった。
参考
- 【xcode 11】新たに導入されたsceneDelegateの各メソッドが呼ばれるタイミング - Qiita https://qiita.com/ninoko1995/items/b28a712d5f620dbebb6f
Github pagesで複数ページを作成する
AppStoreのサポートURL、プライバシーポリシーURL用にGithub pagesを使ってWebページを作成した。
以下のサイトの gh-pagesブランチを親なしで作成する
を試した。
gh-pagesをサブディレクトリ内で管理 - Kludge Factory https://tyfkda.github.io/blog/2016/06/07/git-worktree.html
Tips
$ git checkout --orphan gh-pages
でメインで作業しているブランチとは独立したブランチになる。
作業用ブランチとHTMLファイルのブランチを分けるのが目的。
ブランチを作成後はcheckoutしてxxx.htmlを作成してpushすればWebから見れるようになる。
root直下にhtmlファイルを置くと以下のようなURLになる。
https://<User>.github.io/<Repository_name>/xxx.html
- ディレクトリ名がそのままURLに反映される。
以下の場合、support
と privacypolicy
がディレクトリ名。
https://
root直下に support.html
や privacypolicy.html
として置いてもWebページが見れたので、
わざわざディレクトリを作ってhtmlファイルを分ける必要はなさそう。
こんなときに使える
- AppStoreの申請に必須なサポートURL、プライバシーポリシーURLがコストがかからずに用意できる。
- ポートフォリオページなど。
まとめ
gh-pages
ブランチを作成して公開の他にも masterに /docs
ディレクトリを作成などの公開方法もある。
/docs
ディレクトリを使用して公開の方が簡単そう。
リポジトリをhtmlだけとはいえpublicにするのが不安だったため、gh-pagesの方法を採用したが、
特に問題ないようであれば次回は /docs
の方でやってみる。
- GitHub Pagesの使い方 – 複数ページのホームページの作り方【無料】 | Howpon[ハウポン] https://howpon.com/7226#i
参考
GitHub Pagesの使い方 – 複数ページのホームページの作り方【無料】 | Howpon[ハウポン] https://howpon.com/7226#i
gh-pagesをサブディレクトリ内で管理 - Kludge Factory https://tyfkda.github.io/blog/2016/06/07/git-worktree.html
GitHub Pages について - GitHub ヘルプ https://help.github.com/ja/github/working-with-github-pages/about-github-pages
Lets Build That App - AppStoreJSONAPIsコース #3
学び
- イニシャライザのテクニック
- 戻り値がCGSizeの場合、
CGSize(width: , height: )
と書くのではなく、.init(width: , height: )
で書いた方が簡潔に書ける。 - UIEdgeInsetsなどの型の初期化に便利そう。
- 戻り値がCGSizeの場合、
- collectionviewのCellのサイズを変更するときは
UICollectionViewDelegateFlowLayout
に準拠してからsizeForItemAtでCGSizeをreturnする。
Lets Build That App - AppStoreJSONAPIsコース #1
Lets Build That Appで「AppStoreJSONAPIs」コースが25ドル安い$75ドルになっていたので人生初Paypalで購入した。(元値は$100)
時々こういうセールはあるみたい。
もともと気になっていたので、買うしかないと思った。
Lessonは 58個
最初の2レッスンで以下の画像なような感じになります。
まだtabBarControllerをセットした段階。 これからAppStoreに仕上がっていくとワクワクする。
AppStore JSON APIs | Lets Build That App https://www.letsbuildthatapp.com/course/AppStore-JSON-APIs
学び
- viewControllersで表示するVCを管理する。 viewControllers - UITabBarController | Apple Developer Documentation https://developer.apple.com/documentation/uikit/uitabbarcontroller/1621185-viewcontrollers
Deployment InfoのMain Interfaceを削除しなくても、 AppdelegateのdidFinishLaunchingWithOptionsで以下のように書けば、コードが優先されること。
vimeoなのでYoutubeのように日本語字幕ができない。 自動翻訳ソフトを使えばなんとかなると思うが、英語でも半分くらいは意味が理解できる。
Could not launch "App名"のエラーが出たときの対処方法
実機でビルドした際に上記のタイトルのようにCould not launch "App名" でエラーが出た。
シミュレーターでビルドすると出ない。。
SchemeからRunとArchiveをDebug用にしたらエラーが出ない🤔
解決方法
Provisioning ProfileをDebug用に変更したらエラーが出なくなった。
RUNするときにRelease用のProvisionnig Profileだったからエラーが起きた。(AdHocやAppStoreなど)
まとめ
Releaseのプロビではブレークポイントで止めるなどデバッグできないことがわかった。
Release版を実機でビルドしたい、ブレークポイントで止めたい時はProvisioning ProfileがDebug用になっているか確認をする。