How to add music to a game in SpriteKit - ios

I ran into an issue when trying to add sound to my game. I added this below to the view controller and when I build and run, I would get an error. When I ran the code below:
var interstitialAd : GADInterstitial!
var player: AVAudioPlayer!
override func viewDidLoad() {
super.viewDidLoad()
let path = Bundle.main.path(forResource: "gameMusic.mp3", ofType:"mp3")!
let url = URL(fileURLWithPath: path)
do {
let sound = try AVAudioPlayer(contentsOf: url)
player = sound
sound.play()
} catch {
print("file not found")
}
if let view = self.view as! SKView? {
// Load the SKScene from 'GameScene.sks'
I got the following error:
fatal error: unexpectedly found nil while unwrapping an Optional value
2017-05-21 17:35:01.262683 gameTest2[1660:363851] fatal error:
unexpectedly found nil while unwrapping an Optional value
Can anyone help?

When you use Bundle.main.path(forResource:,ofType:) the first part should be the name of the resource, the second part should be its type. That means your code should be:
let path = Bundle.main.path(forResource: "gameMusic", ofType:"mp3")!

Related

The app worked perfectly for 6-8 taps, after that it crashes

i am very new to iOS coding. I am trying to build an app for my kids. I have some pictures with animals and the sound that these animals do. I've managed to code the app: each time I tap on the screen, the picture changes and the sound related to the picture changes also. After some time, I get this error and the app hangs:
2020-05-01 12:21:31.111411+0200 Animals For Kids[1758:47571] Fatal error: Unexpectedly found nil while unwrapping an Optional value: file /Users/andreitomescu/Desktop/iOS Developing - Udemy/Proiecte diverse/Animals For Kids/Animals For Kids/ViewController.swift, line 21
the code at line 21 is:
func playSound(animalName: String) {
let url = Bundle.main.url(forResource: animalName, withExtension: "wav", subdirectory: "Sounds")
**player = try! AVAudioPlayer(contentsOf: url!)** / this is the line where the error points to
player.play()
}
Can you please help me figure this one out?
Code part 1:
#IBAction func imageButton(_ sender: UIButton) {
func playSound(animalName: String) {
let url = Bundle.main.url(forResource: animalName, withExtension: "wav", subdirectory: "Sounds")
player = try! AVAudioPlayer(contentsOf: url!)
player.play()
}
Code part 2:
let fileManager = FileManager.default
let bundleURL = Bundle.main.bundleURL
let assetURL = bundleURL.appendingPathComponent("Pictures")
do {
let contents = try fileManager.contentsOfDirectory(at: assetURL, includingPropertiesForKeys: [URLResourceKey.nameKey, URLResourceKey.isDirectoryKey], options: .skipsHiddenFiles)
for item in contents
{
fileName.append(String(item.lastPathComponent.dropLast(4)))
animalName = fileName.randomElement()!
Code part 3:
let imageName = animalName
let image = UIImage(named: imageName)
let imageView = UIImageView(image: image!)
imageView.frame = CGRect(x: 0, y: 360, width: 414, height: 414)
view.addSubview(imageView)
}
}
catch let error as NSError {
print(error)
}
// playSound(animalName: animalName)
print(animalName)
It's due to force-unwrapping a nil value as error clearly states that
error: Unexpectedly found nil while unwrapping an Optional value
But why did the app worked for aprox 8 taps and then suddenly crashed? All the files are in the URL ?
Its because first 8 urls are good ad load 9th url is corrupted that specified URL location or couldn't load the contents.
So checkout the url on which your app crash ..
Remove force casting from your code .. update play sound method with the following and check print statement and let me know
var player: AVAudioPlayer?
func playSound(animalName: String) {
guard let url = Bundle.main.url(forResource: animalName, withExtension: "wav", subdirectory: "Sounds") else {
print("path not correct")
return
}
do {
player = try AVAudioPlayer(contentsOf: url)
player?.play()
} catch {
print("url is not correct")
}
}
It's due to force-unwrapping a nil value. It could be either due to no resource at the specified URL location or couldn't load the contents.
To understand more on the crash please check this link

Play/Pause Audio Button Swift

I'm new to swift and can't seem to figure this out. I am trying to have one button act as both a play button which loops audio and as a pause button if clicked again. I've tried using an if/else statement but I keep getting this error "fatal error: unexpectedly found nil while unwrapping an Optional value"
The code works without the if/else statement, however, in that case it loops indefinitely without a way to pause it.
Any suggestions?
var hihat16: AVAudioPlayer!
#IBAction func hat16(_ sender: Any) {
if hihat16.isPlaying == false {
let path = Bundle.main.path(forResource: "Hat 017-1.aif", ofType:nil)!
let url = URL(fileURLWithPath: path)
do {
let sound = try AVAudioPlayer(contentsOf: url)
hihat16 = sound
sound.play()
hihat16.numberOfLoops = -1
} catch {
// couldn't load file :(
}
}else{ hihat16.stop()}
Picture of the code and error message :
Try this.
Do it in your viewDidLoad
let path = Bundle.main.path(forResource: "Hat 017-1.aif", ofType:nil)!
let url = URL(fileURLWithPath: path)
do {
hihat16 = try AVAudioPlayer(contentsOf: url)
hihat16.numberOfLoops = -1
} catch {}
Then in your #IBAction you can do this.
if !hihat16.isPlaying {
hithat16.play()
}
else{ hithat.stop()}

Error: fatal error: unexpectedly found nil while unwrapping an Optional value

I am fairly new to this and trying to figure out the correct format to solve the error in the title. I get on the line: let audioPath = NSBundle.mainBundle().pathForResource("Pugs.m4a", ofType: nil)!
I know I must be missing something just not sure where.
import UIKit
import AVFoundation
class ViewController: UIViewController {
#IBOutlet var playButton: UIButton!
var playPug = 1
var player: AVAudioPlayer!
#IBAction func playPressed(sender: AnyObject) {
let audioPath = NSBundle.mainBundle().pathForResource("Pugs.m4a", ofType: nil)!
let url = NSURL(fileURLWithPath: audioPath)
do {
if playPug == 1 {
let sound = try AVAudioPlayer(contentsOfURL: url)
player = sound
sound.play()
playPug = 2
playButton.setImage(UIImage(named:"pause_Icon.png"),forState:UIControlState.Normal)
} else {
player.pause()
playPug = 1
playButton.setImage(UIImage(named:"play_Icon.png"),forState:UIControlState.Normal)
}
} catch {
print(error)
}
}
The reason you're getting fatal error: unexpectedly found nil while unwrapping an Optional value is because of the ! in this line of code:
let audioPath = NSBundle.mainBundle().pathForResource("Pugs.m4a", ofType: nil)!
It's crashing because you're using ! to force unwrap the value returned by pathForResource(_:ofType:), which is unsafe. If the value is nil, you get the unexpectedly found nil error. You should really only force unwrap things when you know they're not going to be nil.
Try doing something like this instead:
Option 1:
guard let audioPath = NSBundle.mainBundle().pathForResource("Pugs.m4a", ofType: nil) else {
// The resource does not exist, so the path is nil.
// Deal with the problem in here and then exit the method.
}
// The resource exists, so you can use the path.
Option 2:
Use optional binding, like this:
if let audioPath = NSBundle.mainBundle().pathForResource("Pugs.m4a", ofType: nil) {
// The resource exists, and now you have the path, so you can use it.
let url = NSURL(fileURLWithPath: audioPath)
do {
if playPug == 1 {
let sound = try AVAudioPlayer(contentsOfURL: url)
player = sound
sound.play()
playPug = 2
playButton.setImage(UIImage(named:"pause_Icon.png"),forState:UIControlState.Normal)
} else {
player.pause()
playPug = 1
playButton.setImage(UIImage(named:"play_Icon.png"),forState:UIControlState.Normal)
}
} catch {
print(error)
}
} else {
// The path was nil, so deal with the problem here.
}

OSStatus error 2003334207 when using AVAudioPlayer

I am trying to play an MP3 file (works when played via VLC/iTunes) when a button is pressed. Here is my code:
var audioPlayer: AVAudioPlayer!
#IBAction func playEpisode(sender: AnyObject) {
println("now playing")
let indexPath = NSIndexPath(forRow: sender.tag, inSection: 0)
let data: CDEpisode = fetchedResultsController.objectAtIndexPath(indexPath!) as! CDEpisode
var err: NSError?
let url = NSURL(string: data.localPath)
println("The url is \(url)")
audioPlayer = AVAudioPlayer(contentsOfURL: url, error: &err)
if audioPlayer == nil {
if let e = err {
println(e.localizedDescription)
}
}
audioPlayer.delegate = self
audioPlayer.prepareToPlay()
audioPlayer.play()
}
Here is the log:
now playing
The url is Optional(file:///var/mobile/Containers/Data/Application/4747A71E-A63F-4EFC-B2DF-8B361361080B/Documents/serial-s01-e12.mp3)
The operation couldn’t be completed. (OSStatus error 2003334207.)
fatal error: unexpectedly found nil while unwrapping an Optional value
The EXC_BREAKPOINT happens on the audioPlayer.delegate = self.
Other threads on StackoOverflow do not help. Any ideas?
Thanks
Edit: I have tried passing a localURL to contentsOfURL (instead of a CDEpisode object) and it still fails.
This is probably caused by trying to load a file that doesn't exist. If that helps someone adding the call to url.checkResourceIsReachable() will log more descriptive message.
Example code:
do {
let url = URL(fileURLWithPath: dbObject.path)
let isReachable = try url.checkResourceIsReachable()
// ... you can set breaking points after that line, and if you stopped at them it means file exist.
} catch let e {
print("couldnt load file \(e.localizedDescription)")
}
It looks like your trying to unwrap a variable that has a nil value. You should safely unwrap your variables to prevent this.
if let data: CDEpisode = fetchedResultsController.objectAtIndexPath(indexPath!) as! CDEpisode
{
var err: NSError?
let url = NSURL(string: data.localPath)
println("The url is \(url)")
//rest of code
}
You will still need to figure out why it is returning nil but this is a safer way to unwrap variables and prevent crashing as there would need to be more context to resolve that issue.
Some questions to look into:
Are you sure the fetchedResultsController is returning an object at
all?
Are you sure it is of CDEpisode?
try this one
var player: AVAudioPlayer = AVAudioPlayer()
#IBAction func playX(_ sender: Any) {
let urlstring = "https://file-examples-com.github.io/uploads/2017/11/file_example_MP3_700KB.mp3"
let url = URL(string: urlstring)
let data = try! Data(contentsOf: url!)
player = try! AVAudioPlayer(data: data)
player.prepareToPlay()
player.volume = 1.0
player.play()
}
You're checking if audioPlayer is nil but then you go on to use it as if it wasn't anyway. You probably want something like:
if audioPlayer == nil {
if let e = err {
println(e.localizedDescription)
}
} else {
audioPlayer.delegate = self
audioPlayer.prepareToPlay()
audioPlayer.play()
}
And do something to actually handle the error case rather than just printing the error.
In my case I was having the same issue and I found out that I needed to set this before start recording
try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayAndRecord)
Hope it helps anyone
I also got this problem, after checking up the audio file url, found that it is stored in Cache directory. so audio player probably couldn't find audio file according to your "url".
please ensure, the url path is under Document directory.
As others have said, the audio player couldn't find the file.
This helped me: Document directory path change when rebuild application
Basically, you cannot load files with an absolute reference, as the sandbox environment regenerates the absolute file url each time. So you will need to add a small bit of code (see above) to get the correct urls to use.

How to initialize AVAudioPlayer using Swift

I'm creating a game using Swift and SpriteKit in Xcode 6.1 and I can't
get AVAudioPlayer to initialize. I have an SKScene for my menu, and I
want to run music in my "Sounds" folder called "menu.mp3." However, it
crashes every time I run my game. My code is below:
let filePath:NSURL = NSURL(fileURLWithPath: "menu.mp3")!
var er:NSError?
let audioPlayer:AVAudioPlayer = AVAudioPlayer(contentsOfURL: filePath, error: &er)
if (er != nil) {
} else {
audioPlayer.play()
}
I put this in my initializer right after my super.init call. The error I get follows:
fatal error: unexpectedly found nil while unwrapping an Optional value
I've tried a lot of fixes, but I can't figure out what's going wrong.
I've added the AVFoundation framework and imported it to this scene,
but it continues to crash. Is there something wrong with my filePath
that makes my audioPlayer not initialize or something? I've tried
switching to other ways and making different parts optional, but I
can't get it to work. Thanks!
let documentsUrl = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask).first as NSURL
func preparePlayer(name:String){
var error:NSError?
let fileUrl = documentsUrl.URLByAppendingPathComponent(name)
// or
// let fileUrl = NSBundle.mainBundle().bundleURL.URLByAppendingPathComponent(name)
let audioPlayer = AVAudioPlayer(contentsOfURL: fileUrl, error: &error)
if error == nil {
audioPlayer.play()
}
}
override func viewDidLoad() {
super.viewDidLoad()
preparePlayer("menu.mp3")
}

Categories

Resources