27

I have a set of audio files inside a folder. I am able to access the file when the file is placed at main bundle, but if the files are moved inside the folder I am not able to access the files.

Code:

let audioFileName:String = "audioFiles/" + String(index)
let audioFile = NSBundle.mainBundle().pathForResource(audioFileName, ofType: "mp3")!

I have an audio file inside the folder audioFiles and I would want to get its path.

Error:

fatal error: unexpectedly found nil while unwrapping an Optional value

rmaddy
  • 314,917
  • 42
  • 532
  • 579
Rahul Krishna
  • 339
  • 1
  • 4
  • 7

2 Answers2

63

First make sure when you drag your folder audioFiles to your project to check copy items if needed and select create folder references. Make sure it shows a blue folder if your project.

enter image description here

enter image description here

Also NSBundle method pathForResource has an initialiser that you can specify in which directory your files are located:

let audioFileName = "audioName" 

if let audioFilePath = Bundle.main.path(forResource: audioFileName, ofType: "mp3", inDirectory: "audioFiles") {
    print(audioFilePath)
}

If you would like to get that file URL you can use NSBundle method URLForResource(withExtension:, subdirectory:)

if let audioFileURL = Bundle.main.url(forResource: audioFileName, withExtension: "mp3", subdirectory: "audioFiles") {
    print(audioFileURL)
}
Leo Dabus
  • 229,809
  • 59
  • 489
  • 571
  • Thank You for the help, I did exactly the same way you have told. let audioFileName:String = String(index) let audioFilePath = NSBundle.mainBundle().pathForResource(audioFileName, ofType: "mp3", inDirectory: "audioFiles") print(audioFilePath) do { try player = AVAudioPlayer(contentsOfURL: NSURL(fileURLWithPath: audioFilePath!)) } For the print(audioFilePath) , it prints nil and in the next statement I get this error fatal error: unexpectedly found nil while unwrapping an Optional value – Rahul Krishna Dec 31 '15 at 17:30
  • try printing your audioFileName before the crash to check the fileName it is returning – Leo Dabus Dec 31 '15 at 17:36
  • Try providing screenshots showing the name of the file and the folder color and location in your project – Leo Dabus Dec 31 '15 at 17:37
  • I have these audioFileName : 1, audioFilePath : nil – Rahul Krishna Dec 31 '15 at 17:38
  • My question is your actual file name. Your code it is expecting a file named "1.jpg" inside audioFiles folder and it should be blue folder – Leo Dabus Dec 31 '15 at 17:41
  • Why don't you use URLForResouce with extension in subdirectory and get the URL directly ? – Leo Dabus Dec 31 '15 at 17:44
  • I wasn't able to put the screenshots on the comments So I have uploaded it to the following link (http://imgur.com/a/3Wvxk) – Rahul Krishna Dec 31 '15 at 17:44
  • 1
    You folder it is yellow and should be a blue folder located in the same folder as your swift files – Leo Dabus Dec 31 '15 at 17:45
  • I tried this let audioFilepath = NSBundle.mainBundle().URLForResource("1", withExtension: "mp3", subdirectory: "audioFiles") Still I get the same result, for audioFilepath - nil – Rahul Krishna Dec 31 '15 at 17:49
  • 2
    Nothing will help if you don't copy the files as I said. BLUE FOLDER below AppDelegate.swift – Leo Dabus Dec 31 '15 at 17:50
  • 1
    Thank You. It worked. Initially I have created the folder within the Xcode and then added the files the way you have explained. Now I have cleared everything and added the complete folder the way you have explained and it worked. Thanks a lot ! – Rahul Krishna Dec 31 '15 at 17:55
  • 1
    Example for swift 3. if let indexFilePath = Bundle.main.path(forResource: "index", ofType: "html", inDirectory: "homeless-help-web") { print(indexFilePath) } – Keith John Hutchison Feb 20 '17 at 06:20
  • If the given answer still does not work for you it might be because you are in a playground. In that case, see my answer [here](http://stackoverflow.com/a/43140844/4041795) – Montmons Mar 31 '17 at 12:37
  • In Xcode 9, importing a 1.9MB text file from my desktop does not allow me to get a path. Creating an empty text file from within Xcode and copying the contents of the original text file into it will allow me to return a path. – Adrian Sep 23 '17 at 02:30
  • 2
    Doesn't work, and I have no glue why. Filename and fold name is right, but program doesn't see it. – surfrider Oct 01 '17 at 09:12
1

The answer by Leo should work, the critical step is checking "Copy Items if Needed". However, what do you do if you already created a file or forgot that critical step?

Its easy to fix.

Go to Project -> Build Phases -> Copy Bundle Resources

enter image description here

Here you will see a handy list of all the files you've added to your bundle (including all your xcassets!)

Click the add button, and find your missing unlinked file.

Your code will now work (I built my own example, so it won't be same as yours in name):

        if let url = Bundle.main.url(forResource: "testData2", withExtension: "txt") {
            do {

                let myData = try Data(contentsOf: url)
                print(myData.count)
            } catch {
                print(error)
            }
        }

So why weren't we finding the file to begin with? Simple. We were asking the bundle. "Hey where is my file". Bundle was like... I don't know about that file, and if you checked the list of what was part of it (the Bundle Resources that are being copied) it wasn't there. taDa!

Unome
  • 6,750
  • 7
  • 45
  • 87