RORK LABEN
TOOLING — Rorkの開発者向けリポジトリが動き続けています。rork-xcodeが7月16日、rork-deviceが7月15日、rork-plistが7月13日に更新されましたOPUS46 — RorkでClaude Opus 4.6が稼働しています。Rork MaxはClaude Codeを土台にアプリを組み立てる設計ですSIM — ブラウザ上で動くクラウドのiOSシミュレータを備え、実機へのインストールは1クリック、App Storeへの提出は2クリックと案内されていますMAX — Rork MaxはReact Nativeではなく純粋なSwiftを出力します。iPhone・iPad・Apple Watch・Apple TV・Vision Pro、そしてiMessageまでが射程ですNATIVE — HealthKit、ARKitとLiDAR、NFC、Dynamic Island、Live Activities、Metalによる3D、Core MLのオンデバイス推論まで扱えますSEED — RorkはLeft Lane Capitalが主導する1,500万ドルのシードラウンドを実施し、Peak XVとa16z Speedrunが参加しましたTOOLING — Rorkの開発者向けリポジトリが動き続けています。rork-xcodeが7月16日、rork-deviceが7月15日、rork-plistが7月13日に更新されましたOPUS46 — RorkでClaude Opus 4.6が稼働しています。Rork MaxはClaude Codeを土台にアプリを組み立てる設計ですSIM — ブラウザ上で動くクラウドのiOSシミュレータを備え、実機へのインストールは1クリック、App Storeへの提出は2クリックと案内されていますMAX — Rork MaxはReact Nativeではなく純粋なSwiftを出力します。iPhone・iPad・Apple Watch・Apple TV・Vision Pro、そしてiMessageまでが射程ですNATIVE — HealthKit、ARKitとLiDAR、NFC、Dynamic Island、Live Activities、Metalによる3D、Core MLのオンデバイス推論まで扱えますSEED — RorkはLeft Lane Capitalが主導する1,500万ドルのシードラウンドを実施し、Peak XVとa16z Speedrunが参加しました
記事一覧/開発ツール
開発ツール/2026-05-09中級

プレミアム会員専用アイコンを動的に切り替える — Rork で Alternate App Icons を実装するときの設定と落とし穴

Rork で作ったアプリにプレミアム会員専用のアイコンを実装したとき、Expo の標準APIだけでは詰まりました。Alternate App Icons の Info.plist 設定・アセット配置・iOS 18 でのキャッシュ挙動まで、実装手順と注意点をまとめます。

Rork515Alternate App IconsExpo149iOS108アプリアイコン

プレミアム会員になった瞬間にアプリアイコンが特別なデザインに切り替わる、季節限定のアイコンを期間中だけ出し分ける、ダークモード好きな人だけ別の配色を選べるようにします。こうした「アプリ内からアイコンを動的に切り替える」機能を Rork で組み込もうとしたとき、Expo SDK 標準の expo-imageexpo-router を眺めていても答えが見つからず、半日詰まりました。

iOS が公式に提供している Alternate App Icons API を使えば実現できるのですが、Rork(Expo ベース)の場合は Info.plist の手書き編集と asset 配置が必須で、ここを誤るとビルドは通っても切り替えが反応しないか、TestFlight 配布時に弾かれるかのどちらかになります。今回は実際に小さな個人開発アプリでこの機能を入れたときの手順と、つまずいた箇所を残しておきます。

Alternate App Icons とテーマカラー対応アイコンは別物

最初に整理しておきたいのが、よく混同される2つの機能の違いです。

  • Themed Icons(iOS 18.0〜): ライト・ダーク・着色(tinted)の3バリアントを OS が自動で切り替える機能。Assets.xcassets/AppIcon.appiconset/Contents.jsonappearances を追加するだけで対応します。ユーザーが手動で選ぶことはできません
  • Alternate App Icons(iOS 10.3〜): ユーザーまたはアプリのコードから明示的に「次はこのアイコン」と指定して切り替える機能。UIApplication.setAlternateIconName(_:) を呼びます。Themed Icons とは独立した別の API です(Themed App Icons の対応手順 は別途まとめています)

私が当初混乱していたのは、「ダークモード時に専用アイコンを出したい」という要件で、これは Themed Icons だけで足りるケースでした。一方で「サブスク開始時に金色のアイコンに切り替える」のような明示的な切り替えは Alternate App Icons が必要です。要件を一文で言語化すると、自分が必要なのがどちらの API かはっきりします。

Expo(Rork)で Alternate App Icons を有効化する3ステップ

公式 Apple ドキュメントが解説するのは Xcode プロジェクトを直接いじる前提の手順なので、Expo Managed Workflow ベースの Rork ではそのまま使えません。私が辿り着いた最小構成は次の3ステップです。

ステップ1: アイコン画像を用意する

代替アイコンは AppIcon.appiconset とは別に、ファイル名で参照される独立した PNG として配置します。最低限以下のサイズを揃えます。

  • [name]@2x.png(120×120)
  • [name]@3x.png(180×180)
  • iPad もサポートする場合は [name]~ipad.png(76×76)と [name]~ipad@2x.png(152×152)も追加

私は最初、これを AppIcon-Premium.appiconset のようなアセットカタログに入れてしまい、ビルドは通るのに setAlternateIconNameImage not found を返し続けて1時間つぶしました。Alternate Icons は アセットカタログ外のリソースとして配置するのが正解です。

ステップ2: Info.plist に CFBundleAlternateIcons を追記

Rork で生成されたプロジェクトの app.json(または app.config.ts)に、Expo の infoPlist 設定経由で追記します。

{
  "expo": {
    "ios": {
      "infoPlist": {
        "CFBundleIcons": {
          "CFBundlePrimaryIcon": {
            "CFBundleIconFiles": ["AppIcon"],
            "UIPrerenderedIcon": false
          },
          "CFBundleAlternateIcons": {
            "Premium": {
              "CFBundleIconFiles": ["icon-premium"],
              "UIPrerenderedIcon": false
            },
            "DarkGold": {
              "CFBundleIconFiles": ["icon-dark-gold"],
              "UIPrerenderedIcon": false
            }
          }
        }
      }
    }
  }
}

ここで指定する CFBundleIconFiles の値は、ステップ1で配置した PNG のベース名です。@2x @3x のサフィックスは含めません。

ステップ3: JavaScript からネイティブ関数を呼ぶ

Expo には Alternate App Icons 公式モジュールがまだ入っていないので、コミュニティ製の expo-dynamic-app-icon を使うのが最速です。

// app/components/IconSwitcher.tsx
import { setAppIcon, getAppIcon } from "expo-dynamic-app-icon";
import { Alert } from "react-native";
 
export async function switchToPremiumIcon() {
  const current = getAppIcon();
  if (current === "Premium") return; // すでに切替済みなら何もしない
 
  const result = await setAppIcon("Premium");
  // result は "Premium" または false(失敗時)
  if (result === false) {
    Alert.alert("アイコン切替に失敗しました", "iOS 設定を確認してください");
    return;
  }
 
  // 切替直後にダイアログが OS から自動表示される(抑制不可)
}
 
// 期待する出力:
// 成功時 → "Premium" を返し、ホーム画面のアイコンが変わる
// 失敗時 → false を返し、Info.plist 設定の不備を疑う

詰まりやすい3つの落とし穴

落とし穴1: Expo Go では絶対に動かない

expo-dynamic-app-icon はネイティブモジュールを必要とするので、Expo Go では setAppIcon is not a function エラーになります。EAS Build でカスタム Dev Client を作ってからでないとローカル検証もできません(Dev Client セットアップ手順 を別記事にまとめています)。私は eas build --profile development --platform ios でビルドしてから初めて挙動確認できました。

落とし穴2: 切替後の OS 標準ダイアログは抑制できない

setAlternateIconName を呼ぶと、iOS が「このアプリのアイコンが変更されました」というアラートを自動的に表示します。これは API レベルで抑制できません。プライベート API を使う回避策がネット上にありますが、App Store 審査でリジェクト対象になるので使わない判断が安全です。代わりに、UI 側で「アイコンが切り替わります。ホーム画面でご確認ください」と事前にメッセージを出してユーザーの心構えを作っておくと、突然のダイアログで驚かれずに済みます。

落とし穴3: アイコンキャッシュが残ってビルド後すぐ確認できない

新しい代替アイコンを Info.plist に追加した直後、シミュレータでビルドしても切替が反映されないことがあります。これは iOS の SpringBoard 側のアイコンキャッシュが原因です(アイコン更新が反映されないトラブル対処 も合わせて参照してみてください)。私が試して効いた手順は、シミュレータのアプリを完全削除 → クリーンビルド → 再インストール、の組み合わせでした。実機でも同じく、一度アンインストールしてから検証するのが確実です。

アクセシビリティとレビュー時の注意点

代替アイコンを実装するとき、私が後から気づいて慌てた点が2つあります。

ひとつは、App Store Connect のレビュー時にプライマリアイコンと alternate icons の両方が「このアプリのブランドを正しく表現しているか」「他社製品と紛らわしくないか」を見られることです。例えば「ダークモード版」を装って実は他社のロゴに似た意匠を入れていると、ガイドライン 4.5.1 で弾かれます。

もうひとつは、UIAccessibility のラベルが代替アイコンに引き継がれない仕様です。VoiceOver ユーザーがホーム画面でアプリを探すとき、アイコン名(ファイル名ベース)がそのまま読み上げられるので、icon-premium-v2-final のような開発者しか分からない名前は避け、Premium Classic のようなユーザー視点の命名にしておきます。

全体を振り返って

Rork で Alternate App Icons を実装するとき、最初に確認すべきは「自分の要件は Themed Icons で足りるのか、本当に明示的な切り替えが必要なのか」です。本当に Alternate Icons が要るのであれば、Info.plist 設定・アセット配置・コミュニティモジュール導入の3点を押さえれば動きます。Expo Go では検証できない、iOS の確認ダイアログは消せない、アイコンキャッシュが残るという3つの罠に最初に気づけると、半日詰まる時間を回避できると思います。

まずは EAS で Dev Client をビルドし、ダミーの2色アイコンで切り替え動作を確認するところから着手するのが安全です。本番デザインは挙動が確定してから差し替えるほうが、不要なリビルドを避けられます。

実装の参考になれば嬉しいです。お読みいただきありがとうございました。

5,000 万 DL の運用で見えた、Rork アプリの収益化判断

シェア

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

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

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

もしこの記事がお役に立ちましたら、チップ(¥150)で応援いただけると大変励みになります。広告なしでの運営を続けるため、皆さまのご支援が大きな力になっています。

関連記事

開発ツール2026-06-29
写真の「選択した項目だけ許可」に正しく向き合う設計
iOS の写真ライブラリ限定アクセス(選択した項目だけ許可)に Rork(Expo)アプリで正しく対応します。フルアクセス・限定・拒否の3状態の判定、選んだ写真だけを扱う前提の画面設計、追加選択を促す導線までを実装コードとともに整理します。
開発ツール2026-06-26
ユーザー自身の画像を「ファイル」アプリから取り込む — Rorkアプリのドキュメントピッカーとセキュリティスコープ付きURL
写真アプリにない画像を「ファイル」アプリやiCloud Driveから取り込むと、選んだはずのURLが直後に無効になります。expo-document-pickerとセキュリティスコープ付きURL、サンドボックスへの確実なコピーまでを、動くコードで整理します。
開発ツール2026-06-15
Rork 製アプリのウィジェットにタップで動くボタンを置く — App Intents で「アプリを開かない操作」を実装する
Rork が生成する Expo アプリのウィジェットに、タップしてもアプリを開かずに状態を変えるボタンを置く方法です。App Intents と WidgetKit を App Group で結び、reloadTimelines まで往復させる実装を、詰まった2か所も含めて手順で整理します。
📚RECOMMENDED BOOKS
大規模言語モデル入門
山田育矢
LLM開発
生成AIプロンプトエンジニアリング入門
我妻幸長
プロンプト
Claude CodeによるAI駆動開発入門
平川知秀
AI駆動開発
※ アフィリエイトリンクを含みます
もっと見る →