Welcome to the Treehouse Community

The Treehouse Community is a meeting place for developers, designers, and programmers of all backgrounds and skill levels to get support. Collaborate here on code errors or bugs that you need feedback on, or asking for an extra set of eyes on your latest project. Join thousands of Treehouse students and alumni in the community today. (Note: Only Treehouse students can comment or ask questions, but non-students are welcome to browse our conversations.)

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and a supportive community. Start your free trial today.

iOS Build an Interactive Story App with Swift Adding Sound Effects Playing a System Sound

I have tried various methods however I cannot get the sounds to play. Any help would be greatly appreciated.

I have copied exactly (Two Attempts) what Pasan has done to add sound to the app however the app crashes.

It is logged as a fatal error due to nil being found while unwrapping the Bundle.main.path optional string values.

I understand it is forcefully unwrapped however I have tried using a guard statement to return a 'safe option' that I know exists.

Also experimented with other options however nothing has worked and the same fatal error is thrown every time.

Here is the code snippet for the app:

import Foundation
import AudioToolbox

extension Story {

    var soundEffectName: String {
        switch self {
        case .droid, .home: return "HappyEnding"
        case .monster: return "Ominous"
        default: return "PageTurn"
        }
    }

    var soundEffectURL: URL {
        let path = Bundle.main.path(forResource: soundEffectName, ofType: "wav")!
        return URL(fileURLWithPath: path)
    }
}

class SoundEffectsPlayer {
    var sound: SystemSoundID = 0 // Stores sound in byte location in 32 bit integer

    func playSound(for story: Story) {
        let soundURL = story.soundEffectURL as CFURL
        AudioServicesCreateSystemSoundID(soundURL, &sound)
        AudioServicesPlaySystemSound(sound)
    }

}

Any help would be greatly appreciated and I look forward to hearing from you all.

Thank you in advance,

Mitch

5 Answers

Jaroslaw Adamowicz
Jaroslaw Adamowicz
11,634 Points

Hi Mitch,

my basic understanding is that group is like folder, but only inside of the project (visible as folder icon in Project Navigator on left side of XCode), so no real folder on disk is created. And as you said this is when you choose New Group without Folder option in Project Navigator.

But when creating group by New Group, folder on disk will be created as well and your files for that group will be there.

This of course may affect how XCode will see path for that files in your project.

The only problem is that when we are talking aboud application bundle that is created for your App for device, some processing is done automatically by XCode and not visible for us.

I beleive that in your case this could result with issue you faced (let's say your files were not in the bundle created by XCode).

This might be related to cache, specifically created for your app/project, to help XCode work faster. There are known issues that sometimes this cache might be outdated and XCode is not aware it should be recreated.

But that is only my guess and it's actually vary rare issue, very hard to find.

Most importantly: you made it through and can continue! Congrats!

BR,

Jarek

Jaroslaw Adamowicz
Jaroslaw Adamowicz
11,634 Points

Hi,

this is where filenames of wave files comes from, right?

    var soundEffectName: String {
        switch self {
        case .droid, .home: return "HappyEnding"
        case .monster: return "Ominous"
        default: return "PageTurn"
        }
    }

So please make sure you have follwing files added to your project:

  • HappyEnding.wav,
  • Ominous.wav,
  • PageTurn.wav

Also if that's not the case, you can try to simply print out what is in your path constant:

    var soundEffectURL: URL {
        let path = Bundle.main.path(forResource: soundEffectName, ofType: "wav")!
    print("In my path : \(path)")
        return URL(fileURLWithPath: path)
    }

Or add breakpoint on this return (after my print), and check constant path in debuger. First approach with print is called amateur debbuging, second is actually how pro should do it :)

Good luck!

BR,

Jarek

Hi Jarek,

Thank you for your reply.

I do have the files present and spelled correctly in the project.

I have tried what you have suggested but with no luck. The contents of the path constant is simply still nil.

Is there anything else you can suggest?

Mitch

Jaroslaw Adamowicz
Jaroslaw Adamowicz
11,634 Points

Hi Mitch,

I've downloaded project files from this course:

try_with_new_project_files

And it worked without any issue...

Do you have newest XCode installed?

Have you tried to play theese wav files and see if they are not corrupted?

Maybe try to download project files in fresh place and see if it works, it works for me with latest updates for macOS and XCode, so if it won't work, there might be problem with your system.

This kind are always tricky to find and fix.

Good luck!

BR,

Jarek

Okay I found the problem!

When created the Resource file I didn't 'create group without folder'.

I am unsure of what this means so if you explain it would be great however it appears to have fixed the issue.

Finally!

Thank you Jarek for your help!

Mitch