RORK LABEN
PLAY — Google Play の target API level 36 要件が昨日8月31日に発効しました。今日以降、新規アプリと既存アプリの更新は Android 16 対応が必須ですVISIBILITY — API 35 のままのアプリは掲載こそ続きますが、新しい Android 版のユーザーには表示されなくなります。エラーが出ないまま新規インストールだけが減る点に注意が要りますEXTENSION — 間に合わなかった場合は、Play Console から2026年11月1日までの延長申請が出せます。恒久対応の計画とセットで進めるのが実務的ですAPPLE — Apple 側は9月9日にイベント、iOS 27 の正式リリースは9月14日と報じられています。生成したアプリの iOS 27 実機確認はリリース週の前に済ませておきたいところですEXPO — Expo が expo-paste-input を公開しました(8月28日)。React Native の TextInput に画像・GIF・ステッカーの貼り付けを追加するネイティブモジュールですEAS — EAS Observe が8月20日に GA になりました。クラッシュや性能の観測を、ビルドや配信と同じ EAS 上で持てるようになっていますPLAY — Google Play の target API level 36 要件が昨日8月31日に発効しました。今日以降、新規アプリと既存アプリの更新は Android 16 対応が必須ですVISIBILITY — API 35 のままのアプリは掲載こそ続きますが、新しい Android 版のユーザーには表示されなくなります。エラーが出ないまま新規インストールだけが減る点に注意が要りますEXTENSION — 間に合わなかった場合は、Play Console から2026年11月1日までの延長申請が出せます。恒久対応の計画とセットで進めるのが実務的ですAPPLE — Apple 側は9月9日にイベント、iOS 27 の正式リリースは9月14日と報じられています。生成したアプリの iOS 27 実機確認はリリース週の前に済ませておきたいところですEXPO — Expo が expo-paste-input を公開しました(8月28日)。React Native の TextInput に画像・GIF・ステッカーの貼り付けを追加するネイティブモジュールですEAS — EAS Observe が8月20日に GA になりました。クラッシュや性能の観測を、ビルドや配信と同じ EAS 上で持てるようになっています
記事一覧/アプリ開発
アプリ開発/2026-05-27中級

iPhone Air と 17 Pro Max の新解像度を 6 アプリ並行で対応した実装ノート

iPhone Air 420×912 / 17 Pro 402×874 / 17 Pro Max 440×956 を 6 アプリの DefineManager.h に並行投入した実装ノート。三項演算子 29 箇所の追加と段階公開で 0 件の解像度起因クラッシュに着地した過程です。

ios12iphone-airiphone-17screen-resolutionapp-dev2

プレミアム記事

iPhone Air が 420×912、17 Pro が 402×874、17 Pro Max が 440×956 — Apple が秋に新解像度を 3 つ同時に出したのは、長く個人で iOS をやってきた私にとっても、なかなか珍しい年でした。Beautiful HD Wallpapers / Ukiyo-e Wallpapers / Relaxing Healing / Law of Attraction を含む 6 アプリを、限られた個人開発の時間でどう並行対応するかは、今期最大の運用課題でした。

旧来の DefineManager.h に積み上げた三項演算子マクロは、解像度が増えるたびに「正しい順序で読むしかない」プレーンな分岐の連続でした。今回の 3 解像度追加で、29 箇所の三項演算子を 6 アプリすべてに同期する必要があり、ここを Claude on Xcode と手作業で 2 日かけて整え直しました。崩した瞬間にレイアウトが歪むファイルなので、その経緯を残しておきます。

始まりは「セーフエリア境界の 1 ピクセル」

新解像度対応の最初の兆候は、Xcode 17 の新シミュレータでビルドした瞬間でした。Beautiful HD Wallpapers のメイン画面下部、AdMob のバナー上のセーフエリアが 1 ピクセル分だけ広く、その隙間に微妙な背景色が漏れていました。

iPhone Air は 6.6 インチで Dynamic Island 搭載、ノッチではなくダイナミックなセーフエリア管理が要求される機種です。UIScreen.main.bounds.size を直接見るのではなく、safeAreaInsets を介してレイアウトを組み直す必要がありました。

// 旧来の判定(iPhone 16 Pro Max までしか想定していなかった)
#define IS_IPHONE_PRO_MAX \
  ([UIScreen mainScreen].bounds.size.height == 932.0f)
 
// 17 Pro Max は 956pt 縦になったため、true / false の判定が反転していた

最初に出した v3.0.0 ビルドでは、17 Pro Max のユーザーが下部広告領域の上に 8pt の謎の余白を見続ける状態になっていました。実機を持っていない解像度のレイアウトを、シミュレータと TestFlight だけで詰め切るのは、毎年のように難しい仕事です。

DefineManager.h に三項演算子を 29 箇所足す現実

旧来のマクロは次のような形でした。

#define IS_IPHONE_AIR \
  ([UIScreen mainScreen].bounds.size.width == 420.0f && \
   [UIScreen mainScreen].bounds.size.height == 912.0f)
 
#define IS_IPHONE_17_PRO \
  ([UIScreen mainScreen].bounds.size.width == 402.0f && \
   [UIScreen mainScreen].bounds.size.height == 874.0f)
 
#define IS_IPHONE_17_PRO_MAX \
  ([UIScreen mainScreen].bounds.size.width == 440.0f && \
   [UIScreen mainScreen].bounds.size.height == 956.0f)

問題は、レイアウト値を返す側のマクロです。たとえばナビゲーションバーの高さオフセットは以下のように三項演算子で連鎖していました。

#define NAV_BAR_OFFSET \
  (IS_IPHONE_AIR ? 18.0f : \
   IS_IPHONE_17_PRO_MAX ? 22.0f : \
   IS_IPHONE_17_PRO ? 18.0f : \
   IS_IPHONE_16_PRO_MAX ? 20.0f : \
   IS_IPHONE_16_PRO ? 18.0f : 16.0f)

ここに 29 箇所の三項演算子を 1 つずつ追加するわけですが、評価順を間違えると別端末のレイアウトが壊れます。Air と 17 Pro が両方 18pt なら共有してよさそうに見えますが、私はあえて分けて書きました。理由は、来年のリビジョンで Air と 17 Pro の挙動が分岐したときに、どこを直せばよいかを今のうちに固定しておきたかったからです。

12 年間個人でアプリを書いてきて学んだのは、「目先の DRY」と「将来の差分修正のしやすさ」は同義ではないという感覚です。アート活動と並行して個人開発を続けていると、半年後の自分は今の自分とほぼ別人で、コードに書かれていないことは確実に忘れます。三項演算子の冗長性は、未来の自分への手紙のようなものだと考えています。

ここまでお読みいただきありがとうございます。

この記事の続きを読む

この先には、実装コードやベンチマーク結果など、実務でお役に立てる内容をご用意しています。このサイトは広告を掲載しておらず、サーバーや開発にかかる費用はメンバーの皆様のご支援で成り立っています。もしお役に立てていましたら、ご支援いただけますと大変ありがたいです。

この記事で得られること
iPhone Air・17 Pro・17 Pro Max の 3 解像度(420×912 / 402×874 / 440×956)を、6 アプリ並行で同時にリリースする際のチェックリストと、29 箇所の三項演算子分岐の正しい配置順を再現できます
DefineManager.h を介した端末判定マクロが、新解像度の追加で破綻しないように維持するためのテーブル駆動リファクタリングの初期パッチを移植できます
5,000 万 DL を超えるアプリポートフォリオで、新解像度起因のクラッシュを 14 日間 0 件に抑えるための App Store Connect 段階公開 + Crashlytics 監視フィルタを構築できます
Stripe による安全な決済 · いつでもキャンセル可能

この記事を購入する

この先の内容をすべてお読みいただけます。一度のご購入で、いつでも何度でもアクセスできます。このサイトは広告を掲載しておらず、皆さまのご支援がサーバー費用などの運営を支えています。

または
メンバーシップなら全記事が読み放題 →
シェア

お読みいただきありがとうございます

Rork Lab は広告なしで運営しており、サーバー費用などの運営コストはメンバーシップのご支援で賄っています。実装コード・ベンチマーク・本番設計パターンなど、実務でお役立ていただける記事を毎日更新しています。もし読んでよかったと感じていただけましたら、ぜひご覧ください。

  • コピー&ペーストで使える実装コード付き
  • 毎日新しい上級ガイドを追加
  • ¥580/月 または ¥2,480 の永久アクセス
メンバーシップを見る →

関連記事

アプリ開発2026-08-30
targetSdk を 36 にした後、依存ライブラリのどこを見るか
依存ライブラリの AndroidManifest を実際に6本開いて数えました。targetSdkVersion は1本も書かれておらず、代わりに12個の権限が入ってきます。提出前に何を見るべきかの整理です。
アプリ開発2026-08-28
定期ジョブの取りこぼしに二週間気づけなかったのは、成功ログだけを見ていたからです
1日2回動くはずのアセット処理ジョブが半分しか発火せず、それでもログは全て成功でした。実行されなかった回を検出する台帳と、滞留の傾きを見る二つ目の番兵を、実行結果つきで組み立てます。
アプリ開発2026-08-26
タブレットで縦固定が外れる Android 16 の変更と、Expo 側に用意されていない逃げ道
targetSdkVersion 36 では、sw600dp 以上の画面で screenOrientation が無視されます。app.json の orientation では戻せないこと、オプトアウトのプロパティが何を戻して何を戻さないかを、手元で確かめた出力とあわせて整理しました。
📚RECOMMENDED BOOKS
大規模言語モデル入門
山田育矢
LLM開発
生成AIプロンプトエンジニアリング入門
我妻幸長
プロンプト
Claude CodeによるAI駆動開発入門
平川知秀
AI駆動開発
※ アフィリエイトリンクを含みます
もっと見る →