iOSのAdHoc配布アプリを放置するな!1年後に突然全員起動しなくなる「時限爆弾」の正体と対策
社内検証用や実機テストでAdHocビルドしたiOSアプリをそのまま放置していると、プロビジョニングプロファイルの有効期限(最長1年)を迎えた瞬間にインストール済み全端末で突然起動しなくなります。本記事では、なぜアプリが即落ちするのかという署名の仕組みから、MacのCLIで有効期限をサクッと確認するコマンド、そして現場でパニックを起こさないためのカレンダー運用と再配布フローまでを自分の実体験をもとに解説します。
月曜の朝9時に鳴り響くSlackの悲鳴
ある月曜日の朝、出社してコーヒーを淹れた直後にSlackの通知がけたたましく鳴り始めました。「営業用のデモアプリが全員起動しない」「タップした瞬間に画面が閉じる」「今すぐ客先で使うのにどうなってるんだ」という現場からの怒涛のメンションです。1台だけなら端末の不具合やOSアップデートの影響を疑いますが、社内の営業メンバー数十人全員のiPhoneで同時に起きている。これはもう嫌な予感しかしません。
急いで原因を調べた結果、原因はアプリのバグでもサーバーダウンでもなく、ちょうど1年前にビルドして配布したAdHoc版のプロビジョニングプロファイルが期限切れを迎えたことでした。ビルドした当時は「とりあえず社内テスト用だし、そのうちストア公開するか正式版に切り替えるだろう」と軽い気持ちで放置していたんですよね。まさに自分で仕掛けた時限爆弾が、1年という完璧なタイマーを経て炸裂した瞬間でした。
なぜAdHocアプリは1年で動かなくなるのか
iOSアプリを実機で動かすためには、Appleが発行した証明書とプロビジョニングプロファイルによる署名が不可欠です。App Store経由で一般配布されるアプリはストア側で管理されるため端末側で期限切れクラッシュを起こすことはありませんが、AdHoc配布や開発用ビルドは話が別です。
AdHoc配布用のプロビジョニングプロファイル(Provisioning Profile)には、登録された端末のUDID一覧やApp ID、そして配布用証明書(Distribution Certificate)の情報が含まれており、その有効期限はAppleの仕様上最長で1年(365日)に固定されています。また、署名に使用したDistribution Certificate自体の有効期限(通常1年)が先に切れる場合は、プロファイルの期限もそれに引きずられます。
この期限が切れると、iOSのセキュリティ機構(AMFI: Apple Mobile File Integrity)がアプリの署名を「無効」と判定します。ユーザーがアプリアイコンをタップした瞬間に署名検証が行われ、即座にプロセスが強制終了されるため、ユーザー視点では「一瞬スプラッシュ画面が出たと思ったらホーム画面に戻される(即落ちクラッシュ)」という極めて分かりづらい挙動になります。
IPAファイルとプロファイルの期限をコマンドで調べる
「今社内に配っているアプリがいつ爆発するのか」を把握するには、Macのターミナルから security コマンドを使ってプロビジョニングプロファイルの中身をデコードするのが一番手っ取り早いです。
単体の .mobileprovision ファイルを確認する場合
XcodeやApple Developerポータルからダウンロードしたプロファイルファイルを直接調べる場合は、以下のコマンドを実行します。プロファイルの実体はCMS形式でラップされたXML plistなので、security cms -D -i でデコードし、PlistBuddy で ExpirationDate を抽出します。
# プロビジョニングプロファイルの有効期限を抽出して表示
security cms -D -i /path/to/your_adhoc.mobileprovision | \
/usr/libexec/PlistBuddy -c 'Print :ExpirationDate' /dev/stdin
# 実行結果の例:
# Mon Aug 24 22:30:00 JST 2027
手元にある .ipa ファイルから直接確認する場合
ビルド済みの .ipa ファイルしか手元にない場合でも、わざわざ拡張子を .zip に変えて解凍する必要はありません。unzip -p で標準出力に取り出し、パイプで繋ぐことで1行で確認できます。
# IPA内部の embedded.mobileprovision から有効期限を一発取得
unzip -p /path/to/App.ipa "Payload/*.app/embedded.mobileprovision" | \
security cms -D -i /dev/stdin | \
/usr/libexec/PlistBuddy -c 'Print :ExpirationDate' /dev/stdin
このワンライナーをチームのWikiやスニペットツールに登録しておくだけで、怪しいビルドを見つけたときに数秒で爆発日時を特定できるようになります。
現場で事故を防ぐための3つの運用ルール
AdHoc配布の期限切れ事故を防ぐには、技術的な工夫よりも「忘れないための運用設計」が何倍も大事だと実感しています。自分たちのチームでは、痛い目を見て以来以下の3つのルールを徹底しています。
1. ビルド作成日ではなく「期限の1ヶ月前」をカレンダーに登録する
AdHocビルドを作成して関係者に配ったその瞬間に、Googleカレンダーやリマインダーに「〇〇アプリ AdHoc署名期限切れ警告(1ヶ月前)」というイベントを登録します。ビルドを担当したエンジニア個人のカレンダーだけでなく、チームの共有カレンダーやSlackの定時リマインダー通知に仕込んでおくのがポイントです。1ヶ月の猶予があれば、再ビルド、実機動作確認、社内アナウンス、そして各端末への再インストールまで余裕を持って完了できます。
2. そもそも社内配布にAdHocを使い続けない設計を考える
AdHoc配布はUDIDの登録上限(年間100台まで)やプロファイルの年次更新など、長期運用には向いていません。テストや社内利用の規模に応じて、適切な配布方式に切り替えるのが根本解決になります。
| 配布方式 | メリット | デメリット・制約 |
|---|---|---|
| AdHoc配布 | 審査なしで即座に特定端末へ配れる | 最長1年で全滅、UDID事前登録(上限100台)が必要 |
| TestFlight(内部/外部) | メール招待で簡単配布、更新がスムーズ | ビルド有効期限が90日(定期的なビルドアップロードが必要) |
| Apple Business Manager (Custom Apps) | 審査あり、社内限定でApp Store経由の安全な配布 | 組織のD-U-N-S番号やABM環境、審査対応が必要 |
一時的な動作確認ならAdHocやTestFlightで十分ですが、半年以上使われる社内ツールであれば、多少手間がかかってもCustom Apps(カスタムApp)やMDM経由での配布を検討する方が、将来的なメンテナンスコストを大幅に下げられます。
3. fastlaneで証明書・プロファイル管理をコード化する
手動でXcodeやポータルサイトからプロファイルを再生成していると、誰がどの証明書で作ったのかが分からなくなりがちです。fastlane match を導入してリポジトリで証明書とプロファイルを一元管理し、CI/CDパイプラインからワンクリックでAdHocビルドを再生成できるようにしておくと、期限更新時の作業が数分で終わります。
もし期限が切れてパニックになったときの緊急リカバリー
万が一、事前更新を忘れて期限が切れてしまった場合の復旧手順についても触れておきます。有効期限が切れたアプリは端末側でいくら再起動しても二度と立ち上がりません。
解決策はただ一つ、「新しい有効期限を持つプロビジョニングプロファイルでアプリを再ビルド(または再署名)し、端末に上書きインストールする」ことだけです。このとき、Bundle Identifierと署名チームが同一であれば、アプリ内のローカルデータ(UserDefaultsやCoreData、SQLiteなど)を保持したまま上書きアップデートが可能です。慌ててユーザーに「一度アプリを削除してから再インストールしてください」とアナウンスすると、端末内の未同期データが全消去されて二次災害になるので絶対に避けてください。
時限爆弾を抱えたまま走らないために
開発中のアプリや社内向けプロトタイプは、「動いている間は問題ない」とつい放置されがちです。しかし、iOSのAdHoc署名期限は誰に対しても平等に1年後に訪れます。特に新人の頃や急ぎのプロジェクトでは、ビルドが通って実機で動いた瞬間に安心しきってしまいがちです。
「AdHocを吐き出したらその場でカレンダーに11ヶ月後の再配布タスクを入れる」。このたった1分の習慣を身につけるだけで、月曜日の朝に社内中から詰められる恐怖を回避できます。今手元に運用中のAdHocアプリがある人は、ぜひ先ほどのコマンドで残りの寿命を確認してみてください。