5

I am using this code to play audio. My code works fine on iOS 14 with all headphones model, but when customers have updated their devices to iOS 15 and are using AirPods Pro, no audio files play. On other AirPods models and when playing audio files through the iPhone speaker, everything works. What's happened. How to fix it?

Update:

After a long wait, I was given AirPods Pro. And at first I removed that line setupMediaPlayerNotificationView(true) and the app played a sound fine. But some of the functions on Lock Screen were removed. And with this line in the app there was no sound. In the App Store, I had 3 apps with the same code. And after ios 15 only one worked. And I did not understand in any way what is the reason if the code is the same. Why aren't the others working? But it turned out that the app that worked had 1 word in its name - Build Settings -> Product Name -> "myAppName". And the rest had a few words. And when I renamed them to 1 word everything working fine. Sound play fine. What was it? I still don't understand? If anyone has a version, share it.

code:

 let url = Bundle.main.url(forResource: "\(masterIndex)0", withExtension: "m4a")!
            
     do {
                
     audioPlayer = try AVAudioPlayer(contentsOf: url)
     audioPlayer.delegate = self
     audioPlayer.prepareToPlay()
     play(sender:AnyObject.self as AnyObject)
                
     setupMediaPlayerNotificationView(true)
     lockScreen()
                
     } catch {
                
 }

other code:

func lockScreen() {
        
    var albumArtwork : MPMediaItemArtwork!
    let image:UIImage = UIImage(named: "infoImage")!
        
    albumArtwork = MPMediaItemArtwork.init(boundsSize: image.size, requestHandler: { (size) -> UIImage in
        return image
    })
        
    let infotitle = "\(firstArray[index])"
        
    MPNowPlayingInfoCenter.default().nowPlayingInfo = [
        MPMediaItemPropertyArtist : "",
        MPMediaItemPropertyTitle : infotitle,
        MPMediaItemPropertyArtwork : albumArtwork,
        MPMediaItemPropertyAlbumTitle : "",
        MPNowPlayingInfoPropertyElapsedPlaybackTime : Int(audioPlayer.currentTime),
        MPMediaItemPropertyPlaybackDuration: Int(audioPlayer.duration)]
        
}
    
@objc func lockScreenPlay(_ event: MPRemoteCommandEvent) -> MPRemoteCommandHandlerStatus {
    self.audioPlayer.play()
    self.lockScreen()
    self.playButton.setImage(UIImage(named: "pause.png"), for: UIControlState.normal)
    return .success
}
    
@objc func lockScreenPause(_ event: MPRemoteCommandEvent) -> MPRemoteCommandHandlerStatus {
    self.audioPlayer.pause()
    self.lockScreen()
    self.playButton.setImage(UIImage(named: "play.png"), for: UIControlState.normal)
    return .success
}
    
@objc func lockScreenFastForward(_ event: MPRemoteCommandEvent) -> MPRemoteCommandHandlerStatus {
    var time: TimeInterval = audioPlayer.currentTime
    time += 15.0
    if time > audioPlayer.duration {
        audioPlayerDidFinishPlaying(audioPlayer, successfully: true)
    } else {
        audioPlayer.currentTime = time
        updateTime()
    }
        self.lockScreen()
        return .success
    }
    
@objc func lockScreenFastBackward(_ event: MPRemoteCommandEvent) -> MPRemoteCommandHandlerStatus {
    var time: TimeInterval = audioPlayer.currentTime
    time -= 15.0
    if time < 0 {
        audioPlayer.currentTime = 0
        updateTime()
    } else {
        audioPlayer.currentTime = time
        updateTime()
    }
        self.lockScreen()
        return .success
    }
    
@objc func changedThumbSlider(_ event: MPChangePlaybackPositionCommandEvent) -> MPRemoteCommandHandlerStatus {
    let time = event.positionTime
    audioPlayer.currentTime = TimeInterval(time)
    self.lockScreen()
    return .success
}
    
func setupMediaPlayerNotificationView(_ enable: Bool)  {
    let commandCenter = MPRemoteCommandCenter.shared()
    if enable {
        commandCenter.playCommand.addTarget(self, action: #selector(lockScreenPlay))
        commandCenter.pauseCommand.addTarget(self, action: #selector(lockScreenPause))
        commandCenter.skipForwardCommand.preferredIntervals = [15]
        commandCenter.skipForwardCommand.addTarget(self, action: #selector(lockScreenFastForward))
        commandCenter.skipBackwardCommand.preferredIntervals = [15]
        commandCenter.skipBackwardCommand.addTarget(self, action: #selector(lockScreenFastBackward))
        commandCenter.changePlaybackPositionCommand.addTarget(self, action: #selector(self.changedThumbSlider(_:)))
    } else {
        commandCenter.playCommand.removeTarget(self, action: #selector(lockScreenPlay))
        commandCenter.pauseCommand.removeTarget(self, action: #selector(lockScreenPause))
        commandCenter.skipForwardCommand.removeTarget(self, action: #selector(lockScreenFastForward))
        commandCenter.skipBackwardCommand.removeTarget(self, action: #selector(lockScreenFastBackward))
        commandCenter.changePlaybackPositionCommand.removeTarget(self, action: #selector(self.changedThumbSlider(_:)))
    }
}

@IBAction func play(sender: AnyObject) {
        if !audioPlayer.isPlaying{
            
            animationStatus()
            
            audioPlayer.play()
            slider.maximumValue = Float(audioPlayer.duration)
            timer = Timer(timeInterval: 0.1, target: self, selector: #selector(self.updateTime), userInfo: nil, repeats: true)
            RunLoop.main.add(timer!, forMode: .commonModes)
            restorePlayerCurrentTime()
            playButton.setImage(UIImage(named: "pause.png"), for: UIControlState.normal)
        } else {
            
            animationStatus()
            
            audioPlayer.pause()
            playButton.setImage(UIImage(named: "play.png"), for: UIControlState.normal)
            timer?.invalidate()
        }
    }
    
    @IBAction func fastForward(sender: AnyObject) {
        var time: TimeInterval = audioPlayer.currentTime
        time += 15.0 // Go Forward by 15 Seconds
        if time > audioPlayer.duration {
            audioPlayerDidFinishPlaying(audioPlayer, successfully: true)
        } else {
            audioPlayer.currentTime = time
            updateTime()
        }
        self.lockScreen()
    }
    
    @IBAction func fastBackward(sender: AnyObject) {
        var time: TimeInterval = audioPlayer.currentTime
        time -= 15.0 // Go Back by 15 Seconds
        if time < 0 {
            audioPlayer.currentTime = 0
            updateTime()
        } else {
            audioPlayer.currentTime = time
            updateTime()
        }
        self.lockScreen()
    } 

private func restorePlayerCurrentTime() {
        let currentTimeFromUserDefaults : Double? = UserDefaults.standard.value(forKey: "currentTime\(masterIndex)\(index)") as! Double?
        if let currentTimeFromUserDefaultsValue = currentTimeFromUserDefaults {
            audioPlayer.currentTime = currentTimeFromUserDefaultsValue
            slider.value = Float.init(audioPlayer.currentTime)
        }
    }
    
    @objc func updateTime() {
        let currentTime = Int(audioPlayer.currentTime)
        let minutes = currentTime/60
        let seconds = currentTime - minutes * 60
        
        let durationTime = Int(audioPlayer.duration) - Int(audioPlayer.currentTime)
        let minutes1 = durationTime/60
        let seconds1 = durationTime - minutes1 * 60
        
        timeElapsed.text = NSString(format: "%02d:%02d", minutes,seconds) as String
        timeDuration.text = NSString(format: "-%02d:%02d", minutes1,seconds1) as String
        
        UserDefaults.standard.set(currentTime, forKey: "currentTime\(masterIndex)\(index)")
        UserDefaults.standard.set(durationTime, forKey: "durationTime\(masterIndex)\(index)")
        
        slider.value = Float.init(audioPlayer.currentTime)
    }
    
    func audioPlayerDidFinishPlaying(_ audioPlayer: AVAudioPlayer, successfully flag: Bool) {
        
        let currentTime = 0
        let durationTime = 0.1
        UserDefaults.standard.set(currentTime, forKey: "currentTime\(masterIndex)\(index)")
        UserDefaults.standard.set(durationTime, forKey: "durationTime\(masterIndex)\(index)")
        slider.value = Float.init(audioPlayer.currentTime)
        timer?.invalidate()
        
        let path = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.documentDirectory, FileManager.SearchPathDomainMask.userDomainMask, true)
        let documentDirectoryPath:String = path[0]
        let fileManager = FileManager()
        let destinationURLForFile = URL(fileURLWithPath: documentDirectoryPath.appendingFormat("/\(masterIndex)/\(index+1).mp3"))
        
        if fileManager.fileExists(atPath: destinationURLForFile.path){
            
            if endOfChapterSleepTimer == true {
                endOfChapterSleepTimer = false
            } else {
                index = index + 1
                viewDidLoad()
            }
            
        } else {
            
        }
    }

func animationStatus() {
        let vinylLayer = vinylView.layer
        pause = !pause
        if pause {
            pauseLayer(layer: vinylLayer)
        } else {
            if vinylStatus == "true" {
                resumeLayer(layer: vinylLayer)
            } else {
                rotateImageView()
                resumeLayer(layer: vinylLayer)
            }
        }
    }
    
    private func rotateImageView() {
        vinylStatus = "true"
        
        UIView.animate(withDuration: 3, delay: 0, options: .curveLinear, animations: {
            self.vinylView.transform = self.vinylView.transform.rotated(by: .pi / 2)
        }) { (finished) in
            if finished {
                self.rotateImageView()
            }
        }
    }
  • can you show some more of the code? like `play()`, `setupMediaPlayerNotificationView()` and `lockScreen()`? – Rhythmic Fistman Nov 09 '21 at 10:36
  • @RhythmicFistman Do you need even more code? Because I don't understand what the problem is. An internet search also gave no results. –  Nov 10 '21 at 06:49
  • @RhythmicFistman Maybe the problem is in "m4a"? Maybe I need to use "mp3"? Unfortunately, I do not have AirPods Pro and cannot test it. –  Nov 10 '21 at 06:53
  • are there any error in logs? If not.. apple provides technical support on code. You can try to raise TSI with them using your developer account ( i think 2 TSI are included yearly with your developer account and need to pay addtional fees ) – Amod Gokhale Nov 10 '21 at 07:04
  • Breaking only with pro air pods? Definitely get some equipment so you can reproduce. – danh Nov 12 '21 at 23:05
  • @danh I am updating the question, please check –  Nov 14 '21 at 18:08
  • @AmodGokhale I am updating the question, please check –  Nov 14 '21 at 18:08
  • @RhythmicFistman I am updating the question, please check –  Nov 14 '21 at 18:08

1 Answers1

1

May be it is a problem of iOS 15?
I've found some papers for search query: "sound doesn't play AirPods Pro on ios 15": one, tow, three .
As I understand, this problem was fixed in iOS 15.1. Sometimes Apple makes mistakes (for example, every updating of Xcode :) )

Andrew Romanov
  • 4,774
  • 3
  • 25
  • 40
  • I got AirPods Pro. There is a problem. I have 2 applications written according to the template but with different topics. In one there is sound, in the second there is no. Rather, it breaks when I rewind the application. –  Nov 14 '21 at 11:42
  • If I delete this line `setupMediaPlayerNotificationView(true)` all works fine but this removes the rewind function. –  Nov 14 '21 at 11:43
  • Did I write this function correctly? `setupMediaPlayerNotificationView ` –  Nov 14 '21 at 11:47
  • Update question please check –  Nov 14 '21 at 12:33
  • I think it is correct implementation of the registration method. But try to store instances of MBRemoteCommands into some array. It is strange, but may help. Can you share your example project on Github? – Andrew Romanov Nov 14 '21 at 13:29
  • Do you have airpods pro? I would share two projects. Working and not working. Although the code is the same. –  Nov 14 '21 at 13:56
  • No, I do not have AirPods at all. – Andrew Romanov Nov 14 '21 at 14:01
  • I am updating the question, please check –  Nov 14 '21 at 18:07