每个网络请求成功后如何播放声音?

时间:2019-06-30 09:03:53

标签: swift avfoundation avplayer

每个网络请求成功后,我想播放声音。我有一些要使用for循环发送到服务器的对象。在每次迭代中,我都向服务器发送一个请求,每个请求完成后,我想播放声音。

我已经尝试过了:

for object in objects {
   sendObjectToServer(object)
}

func playSound() {
  let url = Bundle.main.url(forResource: "sound", withExtension: "mp3")!
  let player = try! AVAudioPlayer(url)
  player.play()
}

func sendObjectToServer(object: Object) {
   URLSession.shared.dataTask(with url: object.url) {(data,response,error) in
     DispatchQueue.main.async {
          playSound() // doesn't play sound synchronously
        }  
    }
 }

1 个答案:

答案 0 :(得分:0)

为什么要使用主线程进行与背景相关的操作。仅使用Dispatch.main.async代码更新您的UI:

在物理设备上(经过测试和工作)尝试

import AVFoundation

for object in objects {
   DispatchQueue.global(qos: .background).async {
     sendObjectToServer(object)
   }
}


var player: AVAudioPlayer?

func playSound() {
    guard let url = Bundle.main.url(forResource: "sound", withExtension: "mp3") else { return }

    do {
        try AVAudioSession.sharedInstance().setCategory(.playback, mode: .default)            
        try AVAudioSession.sharedInstance().setActive(true)

        /* The following line is required for the player to work on iOS 11. Change the file type accordingly*/
        player = try AVAudioPlayer(contentsOf: url, fileTypeHint: AVFileType.mp3.rawValue)

        /* iOS 10 and earlier require the following line:
        player = try AVAudioPlayer(contentsOf: url, fileTypeHint: AVFileTypeMPEGLayer3) */

        guard let player = player else { return }

        player.play()

    } catch let error {
        print(error.localizedDescription)
    }
}

func sendObjectToServer(object: Object) {
   URLSession.shared.dataTask(with url: object.url) {(data,response,error) in
      // Custom Logic
      playSound()
    }
 }