ios – AVAudioPlayer multiple errors – BAD_ACCESS, unrecognized selector, DataSource read failed, No factory id registered for id

0
57


In trying to add sound effects to my app with AVFoundation/AVAudioPlayer, I have encountered multiple issues. Some of these are constant; others only occur when sounds are supposed to be played in fast succession, in response to user interaction. This can be seen by tapping the square view in the center of the screen in the MCVE; below a certain rate of tapping, only Errors 1 and 2 occur, while if you tap fast enough you will (in addition) alternately encounter a crash caused by Error 3 or 4. Although I suspect the rate-related errors may have something to do with generating too many separate threads and/or these threads resulting in simultaneous access to the same variable (specifically, when setting the booleans inside the tuple values of the soundEffects dictionary), it isn’t clear to me why the error is different between different trials.

Some of these errors have already been discussed here on SO or elsewhere, but there doesn’t seem to be a definite working solution to any of them. I’ve linked these discussions at the relevant points below, and provided commentary on why they don’t solve my app’s problems.
Unfortunately, from this 6 month old unanswered question, as well as the lack of consensus on the other issues, it doesn’t seem like this will be a question with a straightforward solution. I believe this question is still worth asking in order to bring new attention to this set of related problems, and also because the code example here somehow manages to encounter all of them at once. (That wasn’t intentional, just a coincidence! :D) If someone searches for one of the errors and ends up here, there will be a handy collection of linked posts for them to check out. Any edits are welcome (I intended to make this a Community Wiki, but that option doesn’t seem to be available for questions, only answers). Feel free to add in any additional insights/context/details that you think would improve this question, or remove anything that detracts or isn’t relevant.

Error 1 (Shows as soon as app launches, before soundIsAvailable becomes true):
It isn’t just on the simulator like this discussion; it also occurs on a real iPhone 12. Moving the AVAudioPlayer declarations to global scope didn’t fix anything for me. The slow start has also been discussed here and here, but while playing the silent sound file (I do this inside viewDidLoad) as suggested by several answers does provide a convenient ‘timer’ for setting the soundIsAvailable boolean, it does nothing to avoid the ~15 second delay before the first sound will play.

2022-09-20 20:46:57.640005-0500 Sound Errors[32793:2252821]  DataSource read failed
2022-09-20 20:46:57.706245-0500 Sound Errors[32793:2252828] [plugin] AddInstanceForFactory: No factory registered for id <CFUUID 0x600001169da0> F8BB1C28-BAE8-11D6-9C31-00039315CD46
2022-09-20 20:46:57.808740-0500 Sound Errors[32793:2252899]  AudioObjectPropertiesChanged: no such object

Error 2 (Occurs after some time, but doesn’t depend on user interaction):

2022-09-20 20:47:12.805329-0500 Sound Errors[32793:2252828] [aqme]                AQMEIO.cpp:199   timed out after 15.000s (0 0); suspension count=0 (IOSuspensions: )
2022-09-20 20:47:12.805850-0500 Sound Errors[32793:2252828]  AudioDeviceStop: no device with given ID
2022-09-20 20:47:12.806364-0500 Sound Errors[32793:2252828]  AudioDeviceStop: no device with given ID
2022-09-20 20:47:12.807407-0500 Sound Errors[32793:2252828] [aqme]  MEDeviceStreamClient.cpp:431   AQME Default-InputOutput: client stopping after failed start: <CA_UISoundClientBase@0x153904f00>; running count now 0
2022-09-20 20:47:12.808272-0500 Sound Errors[32793:2252828]      CA_UISoundClient.cpp:285   CA_UISoundClientBase::StartPlaying: AddRunningClient failed (status = -66681).

Error 3: Bad Access (the thread number is not consistent across trials, and nothing is printed to the console except (11db))

Thread 6: EXC_BAD_ACCESS (code=1, address=0x10)

Error 4: Unrecognized Selector (it isn’t always __NSTaggedDate, but it does seem to be consistently 0x8000000000000000)

2022-09-20 21:57:33.690905-0500 Sound Errors[33833:2316174] -[__NSTaggedDate count]: unrecognized selector sent to instance 0x8000000000000000
2022-09-20 21:57:33.698566-0500 Sound Errors[33833:2316174] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSTaggedDate count]: unrecognized selector sent to instance 0x8000000000000000'
*** First throw call stack:
(
    0   CoreFoundation                      0x000000018040c304 __exceptionPreprocess + 172
    1   libobjc.A.dylib                     0x000000018005131c objc_exception_throw + 56
    2   CoreFoundation                      0x000000018041afbc +[NSObject(NSObject) instanceMethodSignatureForSelector:] + 0
    3   CoreFoundation                      0x0000000180410204 ___forwarding___ + 1308
    4   CoreFoundation                      0x000000018041268c _CF_forwarding_prep_0 + 92
    5   libswiftCore.dylib                  0x000000018bcb611c $sSD8_VariantVyq_SgxciM + 164
    6   libswiftCore.dylib                  0x000000018bcb6000 $sSDyq_SgxciM + 132
    7   Sound Errors                        0x00000001008a7094 $s12Sound_Errors14ErrorGeneratorV10playEffect5namedySS_tFZyycfU_ + 132
    8   Sound Errors                        0x00000001008a7148 $sIeg_IeyB_TR + 48
    9   libdispatch.dylib                   0x0000000100ef5d5c _dispatch_client_callout + 16
    10  libdispatch.dylib                   0x0000000100ef9210 _dispatch_continuation_pop + 756
    11  libdispatch.dylib                   0x0000000100f108c4 _dispatch_source_invoke + 1684
    12  libdispatch.dylib                   0x0000000100f0a8ac _dispatch_root_queue_drain + 440
    13  libdispatch.dylib                   0x0000000100f0b53c _dispatch_worker_thread2 + 248
    14  libsystem_pthread.dylib             0x00000001ae55eb04 _pthread_wqthread + 224
    15  libsystem_pthread.dylib             0x00000001ae55d904 start_wqthread + 8
)
libc++abi: terminating with uncaught exception of type NSException
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSTaggedDate count]: unrecognized selector sent to instance 0x8000000000000000'
terminating with uncaught exception of type NSException
CoreSimulator 857.7 - Device: iPhone 12 (D510B935-5295-43DC-AC72-E779D87B1D64) - Runtime: iOS 16.0 (20A360) - DeviceType: iPhone 12
(lldb)

Error 5 (this seems to be just log noise, since it gets printed even when the sounds are playing correctly):

2022-09-20 20:48:54.755785-0500 Sound Errors[32793:2252630]  DataSource read failed

Additional Details: The sound files all use the .m4a format, and are all between 1 and 2 seconds long. I know the issue isn’t that the app can’t find the files, since they do play correctly in the time between when the AVAudioPlayer loads and when the crash happens. All relevant code (except for the sound files) is included here; the rest is just a default App template Xcode project. I have BlackHole Audio Driver installed (that’s what I used to record the sounds), but don’t believe that’s responsible for any of these errors.

ViewController file

import UIKit

class ViewController: UIViewController {
    @IBOutlet weak var tappableView: UIView!
    
    let colors = [UIColor.systemGreen, UIColor.systemPink]
    var colorIndex = true
    
    override func viewDidLoad() {
        super.viewDidLoad()
        ErrorGenerator.setUpSound()
    }

    
    @IBAction func viewTapped(_ sender: UITapGestureRecognizer) {
        // Shows that the square view has recognized a tap by toggling its color
        colorIndex.toggle()
        tappableView.backgroundColor = colors[Int(truncating: NSNumber(value: colorIndex))]
        
        // Call the sound generating function from the ErrorGenerator struct
        ErrorGenerator.playTapSounds()
    }
}

ErrorOrigin file

import Foundation
import AVFoundation

struct ErrorGenerator {
    // The first time AVAudioPlayer is used, it takes FOREVER (> 15 seconds) to start.  This initializer is here so that we don't attempt to call the playEffect function until this delay is over and soundIsReady has been set to true.
    static var AVInitializer = AVAudioPlayer()
    static var soundIsReady = false
    
    // Tuple items are:  AVAudioPlayer, whether it is currently playing a sound effect, and the duration of the sound effect (in seconds)
    static var audioPlayers: [String: (AVAudioPlayer?, Bool, Double)] = ["Sound 1": (nil, true, 1.39), "Sound 2": (nil, true, 1.1), "Sound 3": (nil, true, 1.28), "Sound 4": (nil, true, 1.06)]
    
    static func playEffect(named fileName: String) {
        if soundIsReady && audioPlayers[fileName]!.1 {
            let url = Bundle.main.url(forResource: fileName, withExtension: "m4a")
            do {
                audioPlayers[fileName]?.0 = try AVAudioPlayer(contentsOf: url!)
                audioPlayers[fileName]?.0?.play()
                // Don't let the same sound effect be restarted until it has finished playing.  Otherwise, it will cut itself off with a static sound.
                audioPlayers[fileName]?.1 = false
                DispatchQueue.global(qos: .utility).asyncAfter(deadline: .now() + (audioPlayers[fileName]?.2 ?? 1.39)) {
                    audioPlayers[fileName]?.1 = true
                }
            }
            catch {
                print("Error playing sound effect file: \(error)")
            }
        } else {
            print("Sound is not yet ready")
        }
    }
    
    static func setUpSound() {
        DispatchQueue.global(qos: .utility).async {
            let url = Bundle.main.url(forResource: "Empty", withExtension: "m4a")
            AVInitializer = try! AVAudioPlayer(contentsOf: url!)
            AVInitializer.play()
            soundIsReady = true
        }
    }
    
    static func playTapSounds() {
        let s = "Sound \(Int.random(in: 1...4))"
        print("Sound selected: \(s)")
        playEffect(named: s)
    }
}

Images: I’ve included these in addition to the text error messages above, because they highlight the specific lines where the problems occur, and because the Xcode sidebar has more information about the thread structure than appears in the console.

Error 3 – Bad Access

Bad Access Thread 1

Error 3 – Bad Access (with high thread number)

Bad Access Thread 25

Error 4 – Unrecognized Selector

Unrecognized Selector image 1
Unrecognized Selector image 2