RORK LABEN
FUNDING — RorkがLeft Lane Capital主導で$15Mのシードを調達。Peak XV・True Ventures・Goodwater・a16z Speedrunが参加しましたENGINE — Rork MaxはClaude CodeとClaude Opus 4.6で駆動。X で800万超のビューを集め、2週間で年間売上を倍増させましたSWIFT — Rork MaxはWebで初めてSwiftアプリを生成できるビルダーで、Apple伝統のXcodeを置き換える位置づけですPRODUCT — Rork MaxはiPhone・iPad・Apple Watch・Apple TV・Vision Pro・iMessageまでApple全域に対応しますCLASSIC — 通常のRorkはReact Native(Expo)で、英語の説明だけからiOS/Androidアプリを生成しストア配信できますPRICING — 無料で始められ、有料は月25ドル〜。Rork Maxは月200ドルですFUNDING — RorkがLeft Lane Capital主導で$15Mのシードを調達。Peak XV・True Ventures・Goodwater・a16z Speedrunが参加しましたENGINE — Rork MaxはClaude CodeとClaude Opus 4.6で駆動。X で800万超のビューを集め、2週間で年間売上を倍増させましたSWIFT — Rork MaxはWebで初めてSwiftアプリを生成できるビルダーで、Apple伝統のXcodeを置き換える位置づけですPRODUCT — Rork MaxはiPhone・iPad・Apple Watch・Apple TV・Vision Pro・iMessageまでApple全域に対応しますCLASSIC — 通常のRorkはReact Native(Expo)で、英語の説明だけからiOS/Androidアプリを生成しストア配信できますPRICING — 無料で始められ、有料は月25ドル〜。Rork Maxは月200ドルです
記事一覧/開発ツール
開発ツール/2026-06-24上級

電話・イヤホン抜き・他アプリ再生に強い、音声アプリの中断ハンドリング

AVAudioSession の中断通知とルート変更通知を正しく扱い、電話やイヤホン抜き差しで再生が破綻しない音声アプリを、Swift の実装コードとともに整理します。

Rork Max184AVFoundationオーディオSwiftUI53バックグラウンド再生2

プレミアム記事

瞑想や学習向けの音声を再生する小さなアプリを個人開発で出したとき、最初に届いた不具合報告が「電話が来た後、音が戻ってこない」というものでした。再生中に着信があると音が止まるのは当然なのですが、通話が終わってもアプリは止まったまま、画面の再生ボタンは「再生中」の見た目のまま固まっていたのです。

原因は、AVAudioSession の中断を一切ハンドリングしていなかったことでした。再生は AVAudioPlayer に任せきりで、OS から「いま中断したよ」「もう戻っていいよ」という通知が来ていることに、私のコードがまったく耳を傾けていなかったのです。音声アプリの品質は、機能が一通り動くかどうかよりも、この種の割り込みにどれだけ丁寧に応えるかで決まると、その時に痛感しました。

ここから、電話・Siri による中断、イヤホンの抜き差しによるルート変更を正しく扱い、再生が破綻しない実装を、Rork Max が生成するネイティブ Swift にそのまま組み込める形で見ていきます。

まずオーディオセッションのカテゴリを決める

何より先に、アプリがどういう音を出すアプリなのかを OS に宣言します。これを怠ると、サイレントスイッチで音が消えたり、他アプリの音楽を不必要に止めてしまったりします。

import AVFoundation
 
func configureAudioSession() {
    let session = AVAudioSession.sharedInstance()
    do {
        // 再生主体のアプリ。サイレントスイッチに影響されず再生する
        try session.setCategory(.playback, mode: .default)
        try session.setActive(true)
    } catch {
        print("Audio session setup failed: \(error)")
    }
}

.playback は「このアプリの音はコンテンツそのものである」という宣言で、ロック中やバックグラウンドでも鳴らせます。逆に、他アプリの音楽の上に短い効果音を重ねたいだけなら .ambient を選ぶ、というように、用途に応じてカテゴリを変えます。最初の宣言を正しく選ぶことが、後の挙動すべての土台になります。

中断通知を購読する

中断は AVAudioSession.interruptionNotification で届きます。.began(中断開始)と .ended(中断終了)の二つの局面があり、終了時には「自分から再開してよいか」のヒントが付いてきます。

final class PlaybackController {
    private var wasPlayingBeforeInterruption = false
 
    func observeInterruptions() {
        NotificationCenter.default.addObserver(
            self, selector: #selector(handleInterruption),
            name: AVAudioSession.interruptionNotification, object: nil)
    }
 
    @objc private func handleInterruption(_ note: Notification) {
        guard let info = note.userInfo,
              let raw = info[AVAudioSessionInterruptionTypeKey] as? UInt,
              let type = AVAudioSession.InterruptionType(rawValue: raw) else { return }
 
        switch type {
        case .began:
            // 電話やSiriが割り込んだ。状態を覚えておく
            wasPlayingBeforeInterruption = player.isPlaying
            player.pause()
 
        case .ended:
            guard let optsRaw = info[AVAudioSessionInterruptionOptionKey] as? UInt else { return }
            let options = AVAudioSession.InterruptionOptions(rawValue: optsRaw)
            // shouldResume が立っていて、かつ中断前に再生中だったときだけ再開
            if options.contains(.shouldResume), wasPlayingBeforeInterruption {
                try? AVAudioSession.sharedInstance().setActive(true)
                player.play()
            }
 
        @unknown default:
            break
        }
    }
}

ここで肝になるのが shouldResume の扱いです。OS は「再開してよい中断」と「再開すべきでない中断」を区別しています。たとえば他の音楽アプリがユーザー操作で前面に出てきたときは、勝手に再生を奪い返すべきではありません。shouldResume が立っていないのに再生を再開すると、ユーザーの意図に反してしまいます。中断前に再生中だったかどうかも併せて確認し、両方を満たすときだけ静かに戻すのが行儀の良い実装です。

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

この記事の続きを読む

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

この記事で得られること
AVAudioSession の中断通知(電話・Siri)とルート変更通知(イヤホン抜き差し)を正しく購読し、再生を破綻させない実装ができます
中断後に自分から再開してよい場合と、ユーザー操作を待つべき場合を shouldResume フラグで切り分けられます
Now Playing とリモートコマンドに連動させ、ロック画面やコントロールセンターから操作できる本番品質の音声アプリを組めます
Stripe による安全な決済 · いつでもキャンセル可能

この記事を購入する

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

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

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

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

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

関連記事

開発ツール2026-06-24
発熱と省電力モードに合わせて、重い処理を静かに落とす設計
ProcessInfo の thermalState と省電力モードを監視し、発熱時やバッテリー残量が少ないときに重い処理を段階的に落とす実装を、Swift のコードとともに整理します。
開発ツール2026-06-18
Rork Max で Apple Watch のコンプリケーションを WidgetKit で実装する
Rork Max が生成した SwiftUI アプリに、watchOS のコンプリケーションと Smart Stack 対応を後から足す実装手順を、データ共有と Timeline 設計まで具体的にまとめました。
開発ツール2026-06-16
Rork Max が生成した SwiftUI アプリに SwiftData を後付けする
Rork Max が出力した SwiftUI コードは画面は作れても永続化が @State 止まりになりがちです。SwiftData を後付けする際のモデル設計、ContainerとViewの接続、スキーマ移行の実装パターンを手を動かしながら整理しました。
📚RECOMMENDED BOOKS
大規模言語モデル入門
山田育矢
LLM開発
生成AIプロンプトエンジニアリング入門
我妻幸長
プロンプト
Claude CodeによるAI駆動開発入門
平川知秀
AI駆動開発
※ アフィリエイトリンクを含みます
もっと見る →