user5284663
user5284663

Reputation:

How to use audio in iOS application with Swift 2?

I made a Game on Xcode 7 beta using SpriteKit and Swift, I tried to put Audio in it but it's not posible because Xcode found 3 errors, I'm beginner and I don't know how to fix them.

import AVFoundation

    var audioPlayer = AVAudioPlayer()


    func playAudio() {
        // Set the sound file name & extension
        var alertSound = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("Flip 02", ofType: "wav")!)

        // Preperation
        AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback, error: nil)
        AVAudioSession.sharedInstance().setActive(true, error: nil)

        // Play the sound
        var error: NSError?
        audioPlayer = AVAudioPlayer(contentsOfURL: alertSound, error: &error)
        audioPlayer.prepareToPlay()
        audioPlayer.play()
}

The error of code are here:

Code 1:

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

Error 1:

Extra argument 'error' in call

Code 2:

AVAudioSession.sharedInstance().setActive(true, error: nil)

Error 2:

Extra argument 'error' in call

Code 3:

audioPlayer = AVAudioPlayer(contentsOfURL: alertSound, error: &error)

Error 3:

Cannot find an initializer for type 'AVAudioPlayer' that accepts an argument list of type '(contentsOfURL: NSURL, error: inout NSError?)'

Your contribution may will help me. Thanks.

Upvotes: 10

Views: 11780

Answers (3)

Alvin George
Alvin George

Reputation: 14296

The idea is to make an extension of AVAudioPlayer and use a method to call in any class.

1) Make an empty swift class named 'AppExtensions'. Add the following.

 //  AppExtensions.swift

    import Foundation
    import UIKit
    import SpriteKit
    import AVFoundation   

    //Audio
    var audioPlayer = AVAudioPlayer()

    extension AVAudioPlayer {

        func playMusic(audioFileName:String,audioFileType:String)
        {    
            do {

            let alertSound = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource(audioFileName, ofType: audioFileType)!)

           // Removed deprecated use of AVAudioSessionDelegate protocol
            try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
            try AVAudioSession.sharedInstance().setActive(true)
            try audioPlayer = AVAudioPlayer(contentsOfURL: alertSound)
            audioPlayer.prepareToPlay()
            audioPlayer.play()

            }
            catch {
                print(error)
            }
    }
    }

2) Call the extension method in any class.

var audioPlayer1 = AVAudioPlayer()
audioPlayer1.playMusic(audioFileName:"tik",audioFileType:"wav")

Upvotes: 0

Eric Aya
Eric Aya

Reputation: 70094

Use the functions inside do catch and use try for the throwing ones:

var audioPlayer = AVAudioPlayer()

func playAudio() {
    do {
        if let bundle = NSBundle.mainBundle().pathForResource("Flip 02", ofType: "wav") {
            let alertSound = NSURL(fileURLWithPath: bundle)
            try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
            try AVAudioSession.sharedInstance().setActive(true)
            try audioPlayer = AVAudioPlayer(contentsOfURL: alertSound)
            audioPlayer.prepareToPlay()
            audioPlayer.play()
        }
    } catch {
        print(error)
    }
}

See this answer for complete Swift 2 error handling explanations.

Upvotes: 24

Said Sikira
Said Sikira

Reputation: 4533

Handling errors in Swift 2.0 has changed. Foundation and other system frameworks now use new type of error handling that uses try and catch mechanism.

In Cocoa, methods that produce errors take an NSError pointer parameter last parameter, which populates its argument with an NSError object if an error occurs. Swift automatically translates Objective-C methods that produce errors into methods that throw an error according to Swift’s native error handling functionality.

If you look at the definition of functions you use you can see that they now throw. For example:

public func setActive(active: Bool) throws

You can see that there is no error parameter since function throws error. This greatly reduces NSError handling pain and it also reduces amount of code you need to write.

So wherever you see error as the last parameter in the function, delete it and write try! in front of it. One example is this:

try! AVAudioSession.sharedInstance().setActive(true)

Since error handling is not scope of this question, you can read more about it here.

This is corrected version of the code you've written:

import AVFoundation

var audioPlayer = AVAudioPlayer()

func playAudio() {
    // Set the sound file name & extension
    let alertSound = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("Flip 02", ofType: "wav")!)

    // Preperation
    try! AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback, withOptions: [])
    try! AVAudioSession.sharedInstance().setActive(true)

    // Play the sound
    do {
        try audioPlayer = AVAudioPlayer(contentsOfURL: alertSound)
        audioPlayer.prepareToPlay()
        audioPlayer.play()
    } catch {
        print("there is \(error)")
    }
}

Upvotes: 6

Related Questions