Michael Burke
Michael Burke

Reputation: 133

In Swift, how do I let other apps continue to play audio when my app is open?

I looked around and found vaguely similar questions but nothing quite the same...I do apologize if I missed the answer somewhere.

I am finishing up a game I wrote in Swift using SpriteKit.

Most other games that I've played, I can have itunes or something playing music in the background, and still hear it while I am playing a game.

As I am playing my game, I'm noticing that it automatically shuts of the audio from other apps.

I am not using AVAudioPlayer for the sound, as I currently only have a small amount of audio effects so I was just using an SKAction.playsoundfilenamed action instead.

I do have logic in there to turn my sounds on and off, but that is simply using some internal if/else logic.

I'm wondering if perhaps there is some AVAudio property I can set that will allow other apps audio to continue playing when mine is open? I can't find this in the documentation.

Thanks!

Upvotes: 8

Views: 5751

Answers (5)

Emil Korngold
Emil Korngold

Reputation: 602

In Xcode 8.2.1, Swift 3 (latest syntax), this worked for me:

import AVFoundation

override func viewDidLoad() {
    super.viewDidLoad()

    let audioSession = AVAudioSession.sharedInstance()
    do {
        try audioSession.setCategory(AVAudioSessionCategoryPlayback, with: [.mixWithOthers])
        try audioSession.setActive(true)
    }catch{
        // handle error
    }

    // the rest of your code
}

Upvotes: 10

Jozey
Jozey

Reputation: 1740

As of xCode 7 October 14, 2015, this works for me.

Put this on the GameViewController.swift depending which Swift version you're using.

//Swift 2.2
import AVFoundation.AVAudioSession
//Swift 3.0
import AVFoundation

And put this code in the ViewDidLoad:

try! AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryAmbient)

The use of "try" is when you want the program to do something and then catch an error. It's an error handler. By adding the exclamation point, you're pretty much saying "I know this won't fail."

This works for me. I'm playing background music as my app is too.

Upvotes: 4

helgetan
helgetan

Reputation: 1407

Set your AVAudioSession category to Ambient.

import AVFoundation.AVAudioSession

AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryAmbient, error: nil)

This category is also appropriate for “play along” style apps, such as a virtual piano that a user plays while the Music app is playing. When you use this category, audio from other apps mixes with your audio. Your audio is silenced by screen locking and by the Silent switch (called the Ring/Silent switch on iPhone).

Upvotes: 5

Adrian
Adrian

Reputation: 16735

I'm not sure if the architecture of your viewController, but you could try running this in viewDidLoad or create a standalone method that is called within viewDidLoad.

There might be a better spot for this code, but without knowing what your app's code looks like, you could stick it there to see if you can get it working.

// this goes at the top w/ your import statements
import AVFoundation



// you could put this in your viewDidLoad or wherever it's appropriate for your code

    let session = AVAudioSession.sharedInstance()
    session.setCategory(AVAudioSessionCategoryAmbient, withOptions: nil, error: nil)
    session.setActive(true, withOptions: nil, error: nil)

Example code from GitHub

AVAudioSession class reference

Upvotes: 0

keji
keji

Reputation: 5990

Call this code on app launch so that your AVAudioSession lets other apps chime in:

let audioSession = AVAudioSession.sharedInstance()    
audioSession.setCategory(AVAudioSessionCategoryPlayback, withOptions:AVAudioSessionCategoryOptions.MixWithOthers, error: nil);
audioSession.setActive(true, error: nil)

Upvotes: 2

Related Questions