◉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 — 起動広告が、背面から戻った回にしか出ていませんでした。「前面に戻った」合図が、…
記事一覧/アプリ開発
◇ アプリ開発/2026-06-18上級

Rork Max で Apple TV のアンビエント表示アプリを組み立てる

Rork Max が生成するネイティブ Swift を土台に、Apple TV で静かに流し続けるアンビエント表示アプリを設計します。Top Shelf・フォーカスエンジン・途切れない映像ループの実装を、運用で気づいた勘どころとともにまとめました。

Rork Max235tvOSApple TVSwift48AVPlayer

✦ プレミアム記事

居間のテレビに、自分の壁紙アプリの絵がそのまま流れていたら——そう思ったのは、iPhone 向けの壁紙アプリを個人開発で何年か運用してきて、ふと大きな画面で見たくなったときでした。Apple TV は普段ノーコードやクロスプラットフォームの話題から外れがちですが、Rork Max がネイティブ Swift を生成するようになって、ようやく現実的な選択肢になりました。

tvOS は iPhone とは作法がかなり違います。タッチがなく、指で触れない代わりにフォーカスという概念で操作します。常時点けっぱなしにされる前提もあり、消費電力や焼き付きへの配慮も要ります。ここでは、静かな映像をただ流し続ける「アンビエント表示アプリ」を題材に、Rork Max の生成コードへ手を入れていく流れを追います。

なぜ Apple TV を Rork Max で作るのか

標準の Rork は React Native(Expo)でクロスプラットフォームに作りますが、tvOS の本領であるフォーカスエンジンや Top Shelf、AVPlayer の低レベル制御は、ネイティブ Swift でないと素直に届きません。Rork Max は iPhone・iPad・Apple Watch・Apple TV・Vision Pro 向けにネイティブ Swift を生成するため、Apple TV を狙うならこちらが土台になります。

私自身の使い分けは単純です。素早く iOS と Android を同時に出したいときは React Native 版、Apple のハードウェアや OS 統合に踏み込みたいときは Rork Max。Apple TV は後者の典型で、クロスプラットフォームのうまみがそもそも存在しません。なお Rork Max は月 $200、標準の Rork は無料で始められ有料は月 $25 からと、価格差は小さくありません。2クリックで App Store に出せる手軽さを含め、Rork Max でしか届かない領域でこそ、この $200 を活かしたいところです。

観点React Native 版 RorkRork Max(ネイティブ Swift)
tvOS 対応実質的に非対応正式対応
フォーカスエンジン抽象化が薄く扱いにくいSwiftUI が標準対応
Top Shelf 拡張困難App Extension として実装可能
映像の低レベル制御限定的AVFoundation を直接利用

Rork Max に「Apple TV 向けに、フルスクリーンで映像をループ再生し続けるアンビエントアプリを作って」と頼むと、SwiftUI ベースの雛形が返ってきます。ただしそのままでは「再生はするが継ぎ目で一瞬黒くなる」「フォーカスが想定外に動く」といった粗が残ります。ここから先が手作業の領域です。

継ぎ目のない映像ループを組む

最初に直面するのが、ループの継ぎ目です。AVPlayer に同じ動画を seek(to: .zero) で巻き戻す素朴な実装だと、巻き戻しのたびにわずかな黒フレームが挟まります。テレビの大画面では、この一瞬がはっきり気になります。

解決策は AVQueuePlayer と AVPlayerLooper の組み合わせです。これは内部で次の再生アイテムを先読みしておき、切れ目なく繋いでくれます。

import AVFoundation
import SwiftUI
 
final class AmbientPlayerModel: ObservableObject {
    let player: AVQueuePlayer
    private var looper: AVPlayerLooper?
 
    init(resourceName: String) {
        guard let url = Bundle.main.url(forResource: resourceName, withExtension: "mp4") else {
            self.player = AVQueuePlayer()
            return
        }
        let item = AVPlayerItem(url: url)
        let queue = AVQueuePlayer()
        // AVPlayerLooper が継ぎ目のループを担う
        self.looper = AVPlayerLooper(player: queue, templateItem: item)
        self.player = queue
        queue.isMuted = true
        queue.actionAtItemEnd = .advance
    }
 
    func start() { player.play() }
    func stop() { player.pause() }
}

ポイントは AVPlayerLooper をプロパティとして保持し続けることです。ローカル変数にすると解放されてループが止まります。Rork Max の初期生成ではここがローカル変数になっていることが多く、私は毎回プロパティへ昇格させています。ループが突然止まるときは、まずここを疑うのが近道です。見落としやすい注意点だと感じています。

SwiftUI 側は VideoPlayer を使わず、AVPlayerLayer を薄くラップした方が制御しやすいです。VideoPlayer は再生コントロールの UI を抱えてしまい、アンビエント用途では邪魔になります。

struct PlayerLayerView: UIViewRepresentable {
    let player: AVQueuePlayer
 
    func makeUIView(context: Context) -> PlayerUIView {
        let view = PlayerUIView()
        view.playerLayer.player = player
        view.playerLayer.videoGravity = .resizeAspectFill
        return view
    }
    func updateUIView(_ uiView: PlayerUIView, context: Context) {}
}
 
final class PlayerUIView: UIView {
    override class var layerClass: AnyClass { AVPlayerLayer.self }
    var playerLayer: AVPlayerLayer { layer as! AVPlayerLayer }
}

videoGravity を .resizeAspectFill にしておくと、テレビの比率に合わせて余白なく敷き詰められます。私の壁紙素材は縦横比がまちまちなので、ここを .resizeAspect にすると左右に黒帯が出てしまい、アンビエントの没入感が削がれました。

✦

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

この記事の続きを読む

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

この記事で得られること
✦AVQueuePlayer と AVPlayerLooper で継ぎ目のない映像ループを組む具体的なコード
✦Top Shelf 拡張でホーム最上段に作品を出し、起動前から体験を始める設計
✦連続再生の上限を4時間に置くなど、省電力と常時表示を両立させる判断基準
Stripe による安全な決済 · いつでもキャンセル可能
✦

この記事を購入する

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

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

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

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

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

関連記事

⬡ 開発ツール2026-04-05
Rork Max × WidgetKit・ライブアクティビティ実装ガイド 2026 — Dynamic Island 対応まで
Rork Max で iOS Widget・ロック画面ウィジェット・Dynamic Island 対応のライブアクティビティを実装した記録。Timeline の焼き込み設計、APNs のヘッダーと優先度、push-to-start、stale-date の扱いまで実運用の判断を残します。
◇ アプリ開発2026-10-31
EAS Build が「Project archive is too big」で止まったら、上がるファイルを大きい順に数えます
EAS Build のアップロードは 150 MiB で警告、2 GiB で失敗します。送る前に同梱ファイルを大きい順に並べる手順と、原因の見つけ方、.easignore に書く内容の決め方をまとめました。
◇ アプリ開発2026-10-29
アップロード前に一度だけ取りにいかれた画像が、エッジで 404 のまま残りました。保持の規則をステータス別に分け、アップロードと消去を一組にしました
新しい壁紙が、一部の地域でだけ 404 のまま表示されない。原因は、アップロード前に一度だけ取りにいかれた 404 を、CDN が画像と同じ長さで保持していたことでした。ステータス別の保持、診断の二本立て、アップロードと消去の一組を、手元で動かして確かめた記録です。