1

I am using an AVQueuePlayer to play local audio files which I have added to my Xcode project by dragging and dropping the .mp3 files into my folder in the project navigator pane. I then use this code to search thru my files and extract the files that I want, which I then use to fill a table view and to create AVPlayerItems for to play in my AVQueuePlayer.

My code works fine when I run the app on simulator but when i run the app on my iPhone, an error occurs and returns

fatal error: unexpectedly found nil while unwrapping an Optional value

Here is the code causing the issue...

var songNameArray: Array<String> = [String]()
let fileManager = NSFileManager.defaultManager()
let enumerator:NSDirectoryEnumerator = fileManager.enumeratorAtPath("/Users/UsersName/Desktop/Xcode Projects Folder/LocalAudioFilePlayer/LocalAudioFilePlayer")!

while let element = enumerator.nextObject() as? String {
    if element.hasSuffix("mp3") {
        songNameArray.append(element)
        print(element)
    }
}

Are the files not being properly copied into the bundle which is then deployed to the iPhone? If so, what is the proper way to add the audio files?

I also tried this...

var songNameArray: Array<String> = [String]()
let path = String(NSBundle.mainBundle().resourcePath)
let songFiles = try!      NSFileManager.defaultManager().contentsOfDirectoryAtPath(path)

for item in songFiles {
    if item.hasSuffix("mp3"){
        songNameArray.append(item)
        print("appended to songNameArray \(item)")
    }
}

But I get the error

The folder “LocalAudioFilePlayer.app")” doesn’t exist

Any help is greatly appreciated

Fabio Berger
  • 1,921
  • 2
  • 24
  • 29
MikeG
  • 3,745
  • 1
  • 29
  • 51
  • your first `Path` is definitely wrong as that won't be on the device. With regard to the content, have you checked that the files are included in the build? Click the file in Xcode and look at the Target Membership – Flexicoder Jan 19 '16 at 08:16
  • Ok, do you know what path to use that will be on the device? And yes the files are included in the build. – MikeG Jan 19 '16 at 08:20
  • 1
    What error do you get with your second block of code? Is it just not finding anything? Have you included them in a sub folder? This might help http://stackoverflow.com/questions/6398937/getting-a-list-of-files-in-the-resources-folder-ios – Flexicoder Jan 19 '16 at 08:27
  • @Flexicoder the error I get with the second block of code is... `fatal error: 'try!' expression unexpectedly raised an error: Error Domain=NSCocoaErrorDomain Code=260 "The folder “LocalAudioFilePlayer.app")” doesn’t exist."` .They are in a subfolder of the project. – MikeG Jan 19 '16 at 08:36
  • to me the .app implies that its something to do with the app bundle. The linked answer mentions sub folders, have a look through that. Sorry nothing else springs to mind – Flexicoder Jan 19 '16 at 08:41

3 Answers3

1

Did you select "Copy files if needed" then dragged mp3s into Project?

Try to load files as following:

let path = NSBundle.mainBundle().pathForResource("filename", ofType: "ext")
let url = NSURL.fileURLWithPath(path!)
var audioPlayer: AVAudioPlayer?
do {
    try audioPlayer = AVAudioPlayer(contentsOfURL: url)
} catch {
    print("Unable to load file")
}

Note: use only filename here, not the whole path.

Andrey Gershengoren
  • 896
  • 1
  • 5
  • 18
  • I dragged the mp3s into the project then I did select "copy items if needed". And I am not using an AVAudioPlayer i am using an AVQueuePlayer (subclass of AVPlayer). So I need to iterate through multiple files and grab them then put them into an array. I then use the array to create an array of AVPlayerItems, which is then loaded into my AVQueuePlayer prior to playing the items. – MikeG Jan 19 '16 at 08:23
1

It sounds like you haven't added your sound file to your target in the Xcode project. If they don't "belong" to a target, they won't get copied into the "resources" folder during building.

Select the sound files you want to use in the project navigator, and check the file inspector (view->Utilities->File Inspector, and make sure that the appropriate target is selected under "target membership".

edit: this is definitely not the problem in this case. Leaving this answer, as it may be useful for others running into a similar issue.

Mark Bessey
  • 19,598
  • 4
  • 47
  • 69
1
let path = String(NSBundle.mainBundle().resourcePath)

This line is not doing what you might think it does. NSBundle.mainBundle().resourcePath returns String?, which is an optional type. When you create a string from that by wrapping String() around it, it doesn't unwrap the optional, it creates a string describing the optional, which looks like this:

Optional("/Users/markbes/Library/Developer/CoreSimulator/Devices/18D62628-5F8A-4277-9045-C6DE740078CA/data/Containers/Bundle/Application/3DDC064C-0DD1-4BE9-8EA4-C151B65ED1E1/Resources.app")

What you want there is something more like

var path = NSBundle.mainBundle().resourcePath!

That unwraps the String? type, and gives you a string (or throws an error).

Mark Bessey
  • 19,598
  • 4
  • 47
  • 69
  • This helped! Now, when I load the view on my iPhone, I am able to print all the items with the "mp3" suffix and append them to an array accordingly. No more error. However, the audio isn't playing on my iPhone (works fine on simulator tho). I take `[songNameArray]`, convert those to `"fullSongPaths"` by concatenating each one to the end of `/Users/userName/Desktop/Xcode Projects Folder/LocalAudioFilePlayer/LocalAudioFilePlayer/` , and then I take `[fullSongPaths]` and convert them to NSURLs which are then used to create an array of `[AVPlayerItems]`, then used to play in the `queuePlayer`. – MikeG Jan 19 '16 at 18:07
  • Probably worth filing a new question. – Mark Bessey Jan 19 '16 at 18:30
  • When I test this on iPhone, it successfully appends the proper files to `songNameArray`, however it does not play any audio as it should. When I call `queuePlayer.play()` on the simulator, it works fine. On iPhone, no audio comes out. I hooked up a button to call `queuePlayer.currentItem.currentTime` after calling the play function and the app crashes on that line when i tap the button. Should I make this a separate question of its own? – MikeG Jan 19 '16 at 19:13