0

I created an array that is my data for my collection view. I am attempting to tap on the CollectionViewCell and play the sound contained in the file component of my array. I dont't know how to play the sound and can't even get started because I get a null value for the files, which are in my xcode project.

Error: Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value

If I don't force unwrap the file it gives me an error...

class ViewController: UIViewController {

let sounds : [Sounds] = [Sounds(statement: "A", file: Bundle.main.url(forResource: "A", withExtension: "aifc")!),
                            Sounds(statement: "B", file: Bundle.main.url(forResource: "B", withExtension: "aifc")!),
                            Sounds(statement: "C", file: Bundle.main.url(forResource: "C", withExtension: "aifc")!),
                            Sounds(statement: "D", file: Bundle.main.url(forResource: "D", withExtension: "aifc")!)]

}

extension ViewController: UICollectionViewDelegate, UICollectionViewDataSource {
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return sounds.count
    }

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {

        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "soundCell", for: indexPath) as! CollectionViewCell
        let Soundz = sounds[indexPath.item]
        cell.cellLabel.text = Soundz.statement

        return cell
    }

}

struct Sounds{
    var statement : String
    var file : URL 
}

alex00x0
  • 27
  • 6

3 Answers3

1

Looks like your files isn`t attached to the project. Check bundle resources and targets for attached files. And in this case better to use 'lazy var' instead of 'let'

vlad_sh
  • 46
  • 6
0

First of all, you should not force-unwrap! in your sound array when you are trying to get URL to your file. This is causing the crash. You should take an optional URL.

struct Sounds{
    var statement : String
    var file : URL?
}


let sounds : [Sounds] = [Sounds(statement: "A", file: Bundle.main.url(forResource: "A", withExtension: "aifc")),
                            Sounds(statement: "B", file: Bundle.main.url(forResource: "B", withExtension: "aifc")),
                            Sounds(statement: "C", file: Bundle.main.url(forResource: "C", withExtension: "aifc")),
                            Sounds(statement: "D", file: Bundle.main.url(forResource: "D", withExtension: "aifc"))]

}

This will resolve the crash first. When you access the file to play just check first if the URL is there or its nil.

Second, make sure all your sound files are added to your Target. Check the property-inspector of the file and make sure your app target checkbox is selected.

Vimalkumar N.M.
  • 493
  • 2
  • 4
  • 16
Aks
  • 1,567
  • 13
  • 23
  • Why not? Files in the bundle cannot be changed at runtime so the crash reveals a **design** mistake which can be fixed immediately. On the other hand if you use optionals and the files don't exist then nothing will happen which is also not intended. An optional URL is pointless in this case since you **want** to use the sound. – vadian Apr 01 '19 at 10:25
  • It depends on how you handle this case. I generally use a default resource in these cases. It's a matter of choice. Both approaches are ok IMO. – Aks Apr 01 '19 at 10:32
0

Don't Keep Bundle.main.url(forResource: "", withExtension: "") in an Array as if Array size will increase, this statement will take a lot of memory.

Instead of your approach, Keep fileName in your object and when you need path of that file, just call filePath instance variable of your object.

 let sounds = [Sounds(statement: "A", fileName: "A")]

Your struct will be like below

struct Sounds {
    var statement : String
    var fileName: String
    var filePath : URL? {
        return Bundle.main.url(forResource: fileName, withExtension: "html")
    }
}

Hope this will help you.

Community
  • 1
  • 1
Muhammad Waqas Bhati
  • 2,775
  • 20
  • 25