『Interval Reminder』開発録 #3(finish)
インターバルリマインダーが配信開始しました。
最終的に使用したライブラリ
検討していたライブラリはこうでした。
- Realm
- Chameleon
- Permission Scope
- Onboard
- Appirater
- fastlane
が、このうち、結局最終的に使用したのは以下のもののみとなりました。
- Realm データベース
- Chameleon UIのテーマカラー
- Appirater 評価ページへの誘導
- fastlane デプロイと申請の自動化、Git管理
fastlaneを使用しての申請
fastlaneを使用しての申請作業は初めてだったので、うまくできるか不安だったのですが、最終的にはちゃんとfastlaneのみで完遂できました。
スピード重視なので、かなりハマるようだったらいつも通り(と言っても2回目だが)の手作業でやろうとしたのでホッと安心。
参考にしたのは以下のページ。
また、Fastfile
をどのようにすればいいのかは、以下のページを参考にした。
アップロードできなかった時に直した箇所
initした時に生成される初期設定のFastfileだと、アップロードに失敗した。
その原因はどうやらプロビジョニングプロファイルがなかったせいらしく、以下をつけたしたら自動的にダウンロードされうまくアップロードできるようになった。
sigh( app_identifier: "com.{yourname}.{appname}" )
この記述は、手作業で行うところの、
このページで行っている部分に当たる。なのでこれは行わなくて済んだ。
最終的なFastfile
fastlane_version "2.45.0" default_platform :ios platform :ios do before_all do ENV["SLACK_URL"] = "{your slack hook URL}" cocoapods end desc "Runs all the tests" lane :test do scan end desc "Submit a new Beta Build to Apple TestFlight" desc "This will also make sure the profile is up to date" lane :beta do gym(scheme: "IntervalReminder") pilot end desc "Deploy a new version to the App Store" lane :release do sigh( app_identifier: "com.{yourname}.{appname}" ) gym( workspace: "IntervalReminder.xcworkspace", scheme: "IntervalReminder", configuration: "Release" ) deliver( force: true, skip_screenshots: true, // ---[1]2回目以降で変更する必要のない時はtrue skip_metadata: true // ---[1]同上。デフォルトはfalse ) clean_build_artifacts // ---[2] end after_all do |lane| slack( message: "Successfully deployed new App Update." ) end error do |lane, exception| slack( message: exception.message, success: false ) end end
おそらく必要ない記述もあるだろうが、1回目でsighがなく失敗したのだが、原因がわからなかったので、サンプルを参考に色々足してみた結果がこうなった。
本当はsighの記述だけで行けると思う。
また、(2)のclean_build_artifacts
は、ビルドしてアップロードした後にビルドで使用したファイル(プロビジョニングプロファイル)も含めてクリーンに削除してくれる。
プロビジョニングプロファイルはその都度ダウンロードでも問題なく何度もアップロードできた。
fastlaneで行うAppleの二段階認証
fastlaneで行う初回のアップロード時に、ターミナルに英語で2段階認証でどうたらこうたら出て、AppleIDのページにアクセスしてどうにかしろというメッセージが出た。
▲これかと思ったがこれではない。
- 普通にAppleIDのパスを入れるも通らない
- AppleIDのページでログインする時に出る、番号をそこに打つのかと初めは思ったので、それを打っても認証が通らない。
と両者試して通らなかったので、どうすればいいかわからず困惑。
調べたらAPP-SPECIFIC PASSWORDS
なるものがAppleIDのSecurityの中に存在するらしく、ここで生成したパスワードを入力するらしかった。
GeneratedをクリックするとUse an app-specific password to sign in to an app or service not provided by Apple.
と表示されるのでそこには、このパスワードを使う用途などをメモを記述しCreateを押す。
そうすると、自動的にランダムなパスワードが生成されるので、それをターミナルに打つことでfastlaneからItunes Connectへのアップロードができるようになった。
怪奇現象、バイナリのアップロードに成功してもItunes connectからバイナリがすぐ消える
バイナリのアップロードが完了しても、バイナリのページから該当のバイナリが消えてしまう現象が置きた。
なにかの見間違いかと思い、何度もアップロードするも再現率は100%。
しばらくどうしたらいいかわからなかったが、メールボックスを見るとAppleからのメールが届いていた。
気づかないので、ページのほうでなんらかのメッセージくらい出して欲しい。
具体的なメール内容はこれ。
Dear developer, We have discovered one or more issues with your recent delivery for "Interval Reminder". To process your delivery, the following issues must be corrected: Missing Info.plist key - This app attempts to access privacy-sensitive data without a usage description. The app's Info.plist must contain an NSContactsUsageDescription key with a string value explaining to the user how the app uses this data. Missing Info.plist key - This app attempts to access privacy-sensitive data without a usage description. The app's Info.plist must contain an NSCalendarsUsageDescription key with a string value explaining to the user how the app uses this data. Missing Info.plist key - This app attempts to access privacy-sensitive data without a usage description. The app's Info.plist must contain an NSPhotoLibraryUsageDescription key with a string value explaining to the user how the app uses this data. Missing Info.plist key - This app attempts to access privacy-sensitive data without a usage description. The app's Info.plist must contain an NSBluetoothPeripheralUsageDescription key with a string value explaining to the user how the app uses this data. Missing Info.plist key - This app attempts to access privacy-sensitive data without a usage description. The app's Info.plist must contain an NSMicrophoneUsageDescription key with a string value explaining to the user how the app uses this data. Missing Info.plist key - This app attempts to access privacy-sensitive data without a usage description. The app's Info.plist must contain an NSMotionUsageDescription key with a string value explaining to the user how the app uses this data. Once these issues have been corrected, you can then redeliver the corrected binary. Regards, The App Store teamz
使用している機能のうち、プライバシーのためにInfo.plist
への記述が足りないという警告。
しかしメールで注意されている、NSContactsUsageDescription
やNSCalendarsUsageDescription
等、どれひとつこのアプリでは使用していないし全く心当たりがなかったので当惑。
まさか、サードパーティライブラリのせいかと思いつき、使用していないPermission ScopeをCocoa Podsの記述から削除すると上記の警告がなくなった。
Permission Scopeの罠
Permission Scopeは結局使用しなかったのだが、次回以降のアップデートで使うつもりだったので、そのままビルドして申請したところ、上記のようなメールが届いた。
だがこれを消すとなくなったので、結局犯人はPermission Scopeだった。
ということで、自分のアプリで使用していなくてもライブラリの方で使っている場合もあるのだなと学習になった。
それでもまだ問題があった
Permission Scopeを削除してアップロードしても、まだ以下のようなメールが届いた。
Missing Info.plist key - This app attempts to access privacy-sensitive data without a usage description. The app's Info.plist must contain an NSPhotoLibraryUsageDescription key with a string value explaining to the user how the app uses this data. Once these issues have been corrected, you can then redeliver the corrected binary.
今度はNSPhotoLibraryUsageDescription
だ。だが当然ながらフォトライブラリーにアクセスするような機能は今回のアプリでは搭載していない。
またライブラリによる使用だが、使用しているライブラリを特定するのも面倒そうだし、そもそも特定したところで、使用しているから削れない。
ということで、審査に通るかわからないが以下のような記述で押し通せるか試してみた。
<key>NSPhotoLibraryUsageDescription</key> <string>Do not use by this app. but third party Library includes that code.</string>
要約すると、「使っているライブラリが使っているだけで、このアプリでは使用していない」と書いた。
参考にしたページでは
とれる対応としては以下のいずれかでしょう。 - plistにまっとうな理由を書く - ライブラリを使うのをやめる
Appleからの公式見解も出ています。 https://forums.developer.apple.com/message/176579#176579
前者に対応する場合、ライブラリ提供元に問い合わせて、どのような用途で上記コードを使っているかを問い合わせる必要がありそうです(そのうちアナウンスがあるかもしれません)。
と、あったので、果たしてこんな記述で審査に通るか不安だったが、「ライブラリ提供元に問い合わせて、どのような用途で上記コードを使っているかを問い合わせる」はあまりにも時間がかかるので他に仕様がなかったので、これでダメ元で提出。
結果的には配信開始されたので、こういった記述でも問題なかったようだ。
Itunes connect「契約保留中」の罠
上記諸々で開発の罠はくぐり抜けたのだが、最後の最後で罠が待っていた。
アプリ申請後、2日くらいで順調に「レビュー待ち」→「レビュー中」と進んでいったのだが、「契約保留中」という前のアプリの時には見られなかったステータスに変更された。
何か問題があったのかとドキッとしたがメールも何も届いていない。
Googleで調べてみても、なんか勝手に進むみたいな記述があったのでそのまま数日放置。しかし一向に配信されない。
おかしいと思って再度調べてみると、どうやらこれは有料アプリにした時の、銀行の情報や、契約関係の同意が足りない時に出るステータスらしい。
処女作アプリでは無料だったので、このプロセスが必要なかったのだ。
ということで、以下のページを参考に契約情報を更新した。
iTunes connectで入金口座の登録をしよう | onTheHammock LLC
Swift:iTunes Connectの登録作業を実施 | raizan2ame
無事、配信開始
ということで、様々なハマりポイントや罠をくぐり抜け、なんとか初の有料アプリを配信することができました。
なにかの参考になれば幸いです。
ストアのサンプル画像をどうやって作ったか
▲これ
はじめは、こういった画像を簡単に作成できるサービスである「Useful Tools for Mobile App Creators | LaunchKit」を使おうと思っていたのだが、どうやらGoogleへ買収されてオープンソース化してしまい、サービスが稼働していない模様。
これを使うにはVagrantやVirtualBox等を用いて自分で環境を構築する必要があるようだ。
なのでVirtualBoxを落としてVagrantも導入して行おうと思ったのだが、現状のLaunchKitは、最新のVirtualBoxに対応していないらしく、古いバージョンもDLできなくなっていたので断念。
同類のサービスである「DaVinci Apps – Create customized App Store screenshots for you iPhone and Android app」を使うことに。
しかしこちらは無料枠だと画像全面に透かしが入ってしまい使い物にならなかった。有料枠は年払いしかなく、そこまで高頻度に使用するわけでもないのでこちらも断念。
結局、DaVinci Appsで出力した透かしの画像をテンプレートに、無料素材等を用いて自分でPhotoshopで組み上げることにし完成。
追記:こんなサービス出たそうです
今回使ったライブラリの感想
Realm 素晴らしい。UserObjectsは二度と使わないと思う。
Chameleon なくてもなんとかなるけどスピード重視して頭使いたくない場合は有効。
fastlane いいね
次回以降チャレンジしたいこと
- App内課金(フリーミアムモデル、購入して広告なくなる等)