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-18中級

Rork で Linking.canOpenURL が iOS だけ false を返す ─ LSApplicationQueriesSchemes 設定漏れの直し方

TikTok や X、LINE 公式アカウントへ飛ばす実装が iOS の本番ビルドだけで動かない症状を、LSApplicationQueriesSchemes の追加と EAS Build の再生成手順で確実に解消します。

Rork515React Native209iOS108LinkingInfo.plist5トラブルシューティング77

壁紙アプリの宣伝枠に「TikTok を開く」「X でシェアする」を追加した翌日、レビュアーから「iPhone で押しても何も起きない」という連絡が立て続けに 3 件届いたことがあります。シミュレーターでも開発用クライアントでも動いていたので、ストア配布ビルドだけで起きる症状の切り分けに半日かかりました。原因は驚くほど単純で、Info.plistLSApplicationQueriesSchemes を一行も書いていなかっただけだったのです。

私自身は 2014 年から個人でアプリ開発をしてきましたが、Linking.canOpenURL まわりは iOS 9 以降に挙動が大きく変わり、AdMob やプッシュ通知のような派手な変更と違って静かに罠だけが増えていきました。Rork(あるいは Expo / React Native)でこれをきれいに直すには、コード側ではなく設定ファイル側に手を入れる必要があります。

まず症状の特徴を確かめる

似たような不具合に見えても、LSApplicationQueriesSchemes 起因かどうかは挙動でほぼ判別できます。

  • シミュレーターと開発ビルドでは動くが、TestFlight / 本番ストア配布ビルドだけ動かない
  • canOpenURL("tiktok://...") がコールバックで false を返す
  • Xcode のコンソールに -canOpenURL: failed for URL: "..." - error: "This app is not allowed to query for scheme tiktok" という警告が出る
  • Android の同じコードは問題なく動いている

最後の警告メッセージが出ていれば、もう原因は確定です。iOS 9 以降、canOpenURL は宣言していないスキームに対して常に false を返すようになりました。Apple がプライバシー保護として導入した制限で、未宣言のスキームを使って他アプリのインストール状況を探る挙動を防ぐためのものです。

openURL 自体は宣言なしでも実行できる場合がありますが、Rork のように「インストールされていなければウェブ版を開く」という分岐をしているコードは、canOpenURL が常に false になることで「インストールされていない」と誤判定されます。結果として、ユーザーは TikTok アプリを入れているのに、毎回 Safari のウェブ版に飛ばされる、という体験になります。

修正 1: app.json に ios.infoPlist.LSApplicationQueriesSchemes を追加する

Rork は Expo の app config を踏襲しているので、Info.plist を直接いじる必要はありません。プロジェクトルートの app.json(または app.config.ts)に以下のキーを足します。

{
  "expo": {
    "name": "MyApp",
    "ios": {
      "bundleIdentifier": "net.dolice.myapp",
      "infoPlist": {
        "LSApplicationQueriesSchemes": [
          "tiktok",
          "twitter",
          "instagram",
          "line",
          "fb",
          "fb-messenger",
          "youtube",
          "mailto",
          "tel",
          "sms"
        ]
      }
    }
  }
}

app.config.ts を使っている場合は次のようになります。

import type { ExpoConfig } from "expo/config";
 
const config: ExpoConfig = {
  name: "MyApp",
  slug: "myapp",
  ios: {
    bundleIdentifier: "net.dolice.myapp",
    infoPlist: {
      LSApplicationQueriesSchemes: [
        "tiktok",
        "twitter",
        "instagram",
        "line",
        "fb",
        "fb-messenger",
        "youtube",
        "mailto",
        "tel",
        "sms",
      ],
    },
  },
};
 
export default config;

mailtotelsms は iOS が標準で許可しているので必須ではないものの、ここに並べておくとレビュー時に整理しやすいので、私は一緒に書いてしまいます。

修正 2: 実際の URL Scheme を間違えない

ハマりやすいのが「アプリ名 ≠ Scheme 名」のケースです。X を開きたいときに "x" と書いても無効で、現状は依然として "twitter" を使います。LINE も "line" ではなく LINE 公式アカウントの友だち追加なら "https://line.me/R/ti/p/..."(Universal Link)を使うのが安全です。

代表的なスキーム名を一覧にしておきます。

  • TikTok アプリ起動: tiktok
  • X(旧 Twitter)アプリ起動: twitter
  • Instagram プロフィール: instagram
  • LINE 友だち追加(Universal Link 経由が推奨): https://line.me/...
  • Facebook ページ: fb
  • Facebook Messenger: fb-messenger
  • YouTube アプリ: youtube または vnd.youtube
  • Google マップ: comgooglemaps
  • Apple マップ: maps
  • Spotify: spotify
  • Slack: slack

これ以外のアプリは公式ドキュメントで「URL Scheme」と検索するのがいちばん早いです。サードパーティが勝手にまとめているリストはバージョンで変わっているので、引用前に実機で canOpenURL を呼んで確認しています。

修正 3: EAS Build を再ビルドしないと反映されない

ここでつまずく方がとても多いので強調しておきます。app.json を編集しただけでは、開発中の Expo Go や既存の Development Build には反映されません。infoPlistネイティブビルドに焼き込まれる設定 なので、最低でも次のいずれかが必要です。

# 開発用 Dev Client を作り直す
eas build --profile development --platform ios
 
# 本番ビルドを作り直す
eas build --profile production --platform ios
 
# ローカル prebuild + 実機転送
npx expo prebuild --clean
npx expo run:ios --device

expo prebuild --clean を打つと ios/ ディレクトリが再生成されるので、独自に追加したファイルがある場合は事前に差分を退避しておきます。私は CI 上でビルドする運用なので、app.json の変更を push してから 15 分待つ、というのを習慣にしています。

修正 4: Linking.canOpenURL のフォールバックを書き直す

設定が入っても、コード側で「失敗時にウェブ版に飛ばす」処理がないと、URL Scheme が変わったり Apple の挙動が変わったりした瞬間に静かに壊れます。以下のように書いておくと、安全に運用できます。

// utils/openExternalApp.ts
import { Linking, Platform } from "react-native";
 
type AppLink = {
  /** ネイティブアプリを開くための URL(Scheme またはユニバーサルリンク) */
  appUrl: string;
  /** インストールされていない、または開けない場合のウェブフォールバック */
  webUrl: string;
};
 
export async function openExternalApp({ appUrl, webUrl }: AppLink): Promise<void> {
  try {
    const supported = await Linking.canOpenURL(appUrl);
    if (supported) {
      await Linking.openURL(appUrl);
      return;
    }
  } catch (e) {
    // iOS では LSApplicationQueriesSchemes 未宣言時に例外が出ることがある
    // ログは送るが、ユーザー体験を止めないようウェブにフォールバックする
    if (__DEV__) {
      console.warn("[openExternalApp] canOpenURL threw", e);
    }
  }
  await Linking.openURL(webUrl);
}
 
// 使い方
// await openExternalApp({
//   appUrl: "tiktok://user?username=dolice",
//   webUrl: "https://www.tiktok.com/@masaki.hirokawa",
// });

try/catch を必ず外側に置く点が肝です。LSApplicationQueriesSchemes 未宣言のスキームに canOpenURL を投げると例外まで飛ぶことがあり、リリース後にクラッシュレポートで気づくことになりかねません。

修正 5: 50 件の上限に気づいておく

LSApplicationQueriesSchemes には 最大 50 件まで という Apple 側の制限があります。50 件を超えても審査でリジェクトされるわけではないものの、51 件目以降は黙って無視されます。50 件は多いように見えますが、ソーシャル・地図・決済・配車・出会い系まで網羅し始めると意外と早く到達します。

grep -c '"' app.json で要素数の目安は取れますが、私は次のような小さなチェックを package.jsonscripts.predeploy に挟んでいます。

// scripts/check-ios-queries.mjs
import fs from "node:fs";
 
const cfg = JSON.parse(fs.readFileSync("app.json", "utf8"));
const list = cfg?.expo?.ios?.infoPlist?.LSApplicationQueriesSchemes ?? [];
 
if (list.length > 50) {
  console.error(
    `LSApplicationQueriesSchemes has ${list.length} entries (Apple limit is 50).`
  );
  process.exit(1);
}
 
const dup = list.filter((x, i) => list.indexOf(x) !== i);
if (dup.length > 0) {
  console.error(`Duplicate scheme(s) detected: ${dup.join(", ")}`);
  process.exit(1);
}
 
console.log(`OK: ${list.length} scheme(s).`);

ストア配布の直前にこれが落ちることで、過去 2 回ほど審査直前のトラブルを未然に防げました。

それでも canOpenURL が false の時に疑う 3 つのこと

ここまでやってもなお false が返るときは、次の 3 点を順に確認します。

  1. ビルドにキャッシュが残っている: eas build を走らせる前に Xcode の DerivedData を消す、もしくは expo prebuild --clean を打って ios/ を再生成します。Rork の場合は EAS のキャッシュをクリアするオプションを付けて再実行します。
  2. iOS 14 以降のローカルネットワーク許諾と混同している: 自社アプリ間連携でカスタムスキームを使う場合、ローカルネットワーク許諾ダイアログとは別物です。Info.plistNSAppTransportSecurity も同時に疑わず、まず LSApplicationQueriesSchemes だけに集中します。
  3. App Store Connect 上で古いビルドが配信されている: TestFlight の Internal Testing で「最新ビルド」が緑になっているか、ビルド番号がコードと一致しているかを必ず照合します。私は壁紙アプリの審査で、app.json を直したのに古いビルドを Promote しただけで再提出してしまい、半日無駄にしたことがあります。

次にやるべきこと

Linking.canOpenURL の挙動を理解できると、ディープリンク経由のキャンペーン計測や、他アプリ連動のオンボーディングなど、ストアで差別化しやすい体験を安全に作れるようになります。今日のうちに、お使いの Rork プロジェクトの app.json を開き、外部アプリへ飛ばしているスキームが一つでも LSApplicationQueriesSchemes に登録されていないか確認してみてください。

シェア

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

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

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

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

関連記事

開発ツール2026-05-21
RorkでビルドしたiOSアプリがTestFlightで「ITMS-90683」拒否される — Info.plistの使用目的文字列の埋め方
Rork書き出しのiOSアプリをApp Store Connectに提出した直後、メールで「ITMS-90683: Missing Purpose String in Info.plist」を受け取る現象について、原因とapp.jsonからの恒久的な修正手順を、12年間の個人開発で繰り返しハマってきた立場から具体的に説明します。
開発ツール2026-05-02
Rork で StatusBar の色・スタイルが反映されない時の対処法
Rork で生成したアプリの StatusBar が iOS と Android で意図通りに表示されない問題を、実装パターン別に切り分けて解決する手順をまとめました。
開発ツール2026-04-24
Rork アプリの WebView が真っ白になる・ページが表示されないときに確認する 6 つの原因
Rork で WebView を組み込んだら画面が真っ白になる、ページが読み込まれない、JavaScript が動かない ─ そんな症状を切り分けて確実に直すためのチェックリストです。
📚RECOMMENDED BOOKS
大規模言語モデル入門
山田育矢
LLM開発
生成AIプロンプトエンジニアリング入門
我妻幸長
プロンプト
Claude CodeによるAI駆動開発入門
平川知秀
AI駆動開発
※ アフィリエイトリンクを含みます
もっと見る →