web-dev-qa-db-fra.com

Comment utiliser l'audio dans une application iOS avec Swift 2?

J'ai créé un jeu sur Xcode 7 beta en utilisant SpriteKit et Swift, j'ai essayé d'y mettre de l'audio mais ce n'est pas posible car Xcode a trouvé 3 erreurs, je suis débutant et je ne sais pas comment les réparer.

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()
}

Les erreurs de code sont ici:

Code 1:

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

Erreur 1:

Argument supplémentaire 'erreur' dans l'appel

Code 2:

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

Erreur 2:

Argument supplémentaire 'erreur' dans l'appel

Code 3:

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

Erreur 3:

Impossible de trouver un initialiseur pour le type 'AVAudioPlayer' qui accepte une liste d'arguments de type '(contentsOfURL: NSURL, erreur: inout NSError?)'

Votre contribution peut m'aider. Merci.

10
user5284663

Utilisez les fonctions à l'intérieur de do catch et utilisez try pour les lancer:

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)
    }
}

Voir cette réponse pour des explications complètes sur la gestion des erreurs Swift 2.

24
ayaio

La gestion des erreurs dans Swift 2.0 a changé. Les frameworks Foundation et autres systèmes utilisent maintenant un nouveau type de traitement des erreurs qui utilise le mécanisme try and catch. 

Dans Cocoa, les méthodes qui produisent des erreurs prennent un dernier paramètre de pointeur NSError, qui remplit son argument avec un objet NSError si une erreur se produit. Swift convertit automatiquement les méthodes Objective-C qui produisent des erreurs en méthodes émettant une erreur conformément à la fonctionnalité de gestion des erreurs native de Swift.

Si vous regardez la définition des fonctions que vous utilisez, vous pouvez voir qu'elles jettent maintenant. Par exemple:

public func setActive(active: Bool) throws

Vous pouvez voir qu'il n'y a pas de paramètre d'erreur puisque la fonction génère une erreur. Cela réduit considérablement la douleur liée à la manipulation de NSError et réduit également la quantité de code que vous devez écrire.

Donc, chaque fois que vous voyez une erreur comme dernier paramètre de la fonction, supprimez-la et écrivez essayez! devant elle. Voici un exemple:

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

La gestion des erreurs ne faisant pas partie de cette question, vous pouvez en lire plus à ce sujet here .

Ceci est la version corrigée du code que vous avez écrit:

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)")
    }
}
6
Said Sikira

L'idée est de créer une extension de AVAudioPlayer et d'utiliser une méthode pour appeler dans n'importe quelle classe. 

1) Créez une classe Swift vide nommée 'AppExtensions'. Ajouter ce qui suit.

 //  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) Appelez la méthode d'extension dans n'importe quelle classe. 

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