◉RORK LABEN
●GPT-6.1 SOL — Rork のモデルメニューに追加(09-29)。Low/Medium/High を選べ、Pro・Max に含まれます●SONNET 5.5 — UI づくりが得意で、Sonnet 5 より出力が速いモデルが選べます(09-28)●SONNET 4.5 — Claude API での提供終了は 11/30、残り26日。API 連携を足したアプリは移行先の確認を●SDK 58 — React Native 0.88 に更新されました。Android のリリース版で R8 が既定オンになり、iOS は SceneDelegate を生成します●OBSERVE — EAS Observe がネイティブクラッシュも記録します(SDK 57.0.21 以降・10/07)●NEW — 起動広告が、背面から戻った回にしか出ていませんでした。「前面に戻った」合図が、…●GPT-6.1 SOL — Rork のモデルメニューに追加(09-29)。Low/Medium/High を選べ、Pro・Max に含まれます●SONNET 5.5 — UI づくりが得意で、Sonnet 5 より出力が速いモデルが選べます(09-28)●SONNET 4.5 — Claude API での提供終了は 11/30、残り26日。API 連携を足したアプリは移行先の確認を●SDK 58 — React Native 0.88 に更新されました。Android のリリース版で R8 が既定オンになり、iOS は SceneDelegate を生成します●OBSERVE — EAS Observe がネイティブクラッシュも記録します(SDK 57.0.21 以降・10/07)●NEW — 起動広告が、背面から戻った回にしか出ていませんでした。「前面に戻った」合図が、…
記事一覧/AIモデル
◉ AIモデル/2026-06-14上級

Rork(Expo)製アプリから Apple Foundation Models を呼ぶ — オンデバイスAIをネイティブモジュールで橋渡しする

Rork が生成する Expo(React Native)アプリから iOS のオンデバイスAI、Apple Foundation Models を呼ぶには、Swift 側のネイティブモジュールを挟む必要があります。Expo Modules API で橋渡しを書き、未対応端末ではクラウドへ逃がす構成を実装します。

Rork611Expo234Foundation Models4オンデバイスAI13ネイティブモジュール9React Native242

✦ プレミアム記事

Rork で説明文からアプリを生成すると、出てくるのは Expo(React Native)のプロジェクトです。一方で iOS のオンデバイスAI、Apple Foundation Models は Swift の framework として提供されます。つまり「Rork で作ったアプリにオンデバイスLLMを入れたい」と思った瞬間、JavaScript からは直接触れない壁に当たります。

私自身、壁紙アプリや癒し系アプリを個人開発で長く運用してきましたが、新しい OS の機能を「全ユーザーに配ること」と「最新端末だけで動かすこと」は別物だと何度も痛感してきました。Foundation Models は iOS 26 以降のオンデバイス機能なので、素朴に呼ぶと古い端末を使う読者を切り捨ててしまいます。そこで Expo Modules API で Swift の Foundation Models を橋渡しし、未対応の環境では静かにクラウドへ逃がす——という実運用に耐える構成を、配線の一本ずつまで具体的に組み立てていきます。

オンデバイス推論を一次経路にしてクラウドへ逃がす「ルーター」の設計思想そのものはオンデバイスAI推論ルーターの設計で、Foundation Models を Swift ネイティブから使う前提知識はApple FoundationModels 実装ガイドで扱っています。本稿はその二つの間にある「Expo アプリから、どうやって実際にこの framework を呼ぶのか」という配線の話に絞ります。

なぜ Expo の JS からは直接呼べないのか

Foundation Models は import FoundationModels で使う Swift 専用の API です。React Native のブリッジは JavaScript と Objective-C/Swift の間で JSON 相当の値しかやり取りできないので、LanguageModelSession のような Swift の型をそのまま JS へ渡すことはできません。

ここで多くの人が expo-apple-intelligence のような既製パッケージを探しますが、Foundation Models は登場が新しく、純粋な Expo アプリ向けの薄いラッパーは安定したものがまだ揃っていません。私は「他人のラッパーがブラックボックスでバージョン追従に振り回されるくらいなら、自分で 100 行のモジュールを書いて握っておく」判断をすることが多く、ここでもその方針を採ります。やることは三つです。プロンプトを文字列で受け取り、Swift 側で Foundation Models を呼び、結果の文字列を Promise で返す。これだけなら自作モジュールの方が読みやすく、壊れたときに自分で直せます。

Swift 側:Expo Module で Foundation Models を包む

Expo Modules API では、Module を継承したクラスに AsyncFunction を定義するだけで JS から await できる関数が生えます。ローカルモジュールを作るなら npx create-expo-module --local on-device-ai が出発点です。生成された ios/OnDeviceAIModule.swift を次のように書き換えます。

import ExpoModulesCore
import FoundationModels
 
public class OnDeviceAIModule: Module {
  public func definition() -> ModuleDefinition {
    Name("OnDeviceAI")
 
    // 端末がオンデバイスLLMを使えるかを JS に返す。
    // "available" 以外を返したら、JS 側はクラウドへ切り替える。
    AsyncFunction("availability") { () -> String in
      if #available(iOS 26.0, *) {
        switch SystemLanguageModel.default.availability {
        case .available:
          return "available"
        case .unavailable(.deviceNotEligible):
          return "device_not_eligible"
        case .unavailable(.appleIntelligenceNotEnabled):
          return "not_enabled"
        case .unavailable(.modelNotReady):
          return "model_not_ready"
        case .unavailable:
          return "unavailable"
        }
      } else {
        return "os_too_old"   // iOS 26 未満
      }
    }
 
    // プロンプトを受け取り、生成テキストを返す。
    // promise を使うことで Swift の async/throws をそのまま JS の例外に橋渡しできる。
    AsyncFunction("generate") { (prompt: String, promise: Promise) in
      guard #available(iOS 26.0, *) else {
        promise.reject("UNSUPPORTED", "iOS 26 未満ではオンデバイス生成を利用できません")
        return
      }
      Task {
        do {
          let session = LanguageModelSession()
          let response = try await session.respond(to: prompt)
          promise.resolve(response.content)
        } catch {
          promise.reject("GENERATION_FAILED", error.localizedDescription)
        }
      }
    }
  }
}

ここで一番大事なのは if #available(iOS 26.0, *) のガードです。FoundationModels を import したコードでも、ガードの外側に Foundation Models 固有の型を置かなければ、framework は弱リンク(weak link)され、iOS 26 未満の端末でもアプリ自体は起動します。availability を関数として独立させ、generate の冒頭でも必ずガードしているのは、JS 側が「呼ぶ前に availability で分岐する」と「うっかり古い端末で generate を叩いてしまう」の両方に耐えるためです。実運用では後者が必ず起きるので、二重に守ります。

✦

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

この記事の続きを読む

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

この記事で得られること
✦Expo で出したアプリに『オンデバイスAIを入れたいが Swift の framework を JS から触れない』で止まっていた状態から、自分で書いた Expo Module 経由で呼べる構成を手に入れられる
✦iOS 26 未満や非対応端末で落ちる素朴な実装を、availability ゲートとクラウドフォールバックで全ユーザーに配信できる形へ作り替えられる
✦EAS Build で system framework を弱リンクさせ、審査と段階公開まで通すまでの実装判断を、5,000万DL運用の端末分布の感覚込みで判断できる
Stripe による安全な決済 · いつでもキャンセル可能
✦

この記事を購入する

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

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

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

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

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

関連記事

◉ AI モデル2026-08-07
MCP のツールを減らしても軽くならない — 定義 2,377 バイトと応答 110,298 バイトを測り直した記録
壁紙カタログ用のMCPサーバを依存なしの最小構成で書き直し、ツール定義2,377バイトと応答110,298バイトを実測した記録です。削るべきは応答側であること、ツール統合の本当の理由が見分けやすさにあることを、測定ハーネスと3つの設計ルールとともに示します。
⬡ 開発ツール2026-05-06
Rork アプリに Expo Dev Client を導入する手順 — ネイティブモジュールが Expo Go で動かなくなったときの最初の一手
Rork で生成したアプリにネイティブモジュールを足したら Expo Go で開けなくなった。そんなときの Expo Dev Client(カスタム開発ビルド)の導入手順と、prebuild の落とし穴・リビルドの判断基準・EAS Update との関係を整理します。
◉ AI モデル2026-10-25
Rork で作ったアプリが Sonnet 4.5 を呼んでいないか、11月30日の前に洗い出します
Claude Sonnet 4.5 の API 提供終了は 2026年11月30日の予定です。アプリ内に残ったモデル ID を数分で洗い出すスクリプトと、見つかった場所ごとの直し方・順番をまとめました。