I try to play sound with Swift 2.0
If I write 'try' without '!' I got error
"Errors thrown from here are not handled"
And AVAudioPlayer is not Optional why Xcode request 'try!'
If I write 'try!' my app crash
"unexpectedly found nil while unwrapping an Optional value"
class TouchViewController: UIViewController {
var soundPath:NSURL?
...................
//Play Bipsound
do { soundPath = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("Bipsound", ofType: "wav")!)
var sound = try! AVAudioPlayer(contentsOfURL: soundPath!, fileTypeHint: nil)
sound.prepareToPlay()
sound.play() }
Pretend you've never seen the ! force-unwrapping operator in Swift before and stop using it entirely. It's basically the "Crash if this optional contains nil" operator. Use "if let" style optional binding or try/catch as outlined by #LLooggaann in his excellent answer. (voted)
var soundPath:NSURL?
if let path = Bundle.main.path(forResource: "Bipsound", ofType: "wav") {
soundPath = NSURL(fileURLWithPath: path)
do {
let sound = try AVAudioPlayer(contentsOfURL: soundPath!, fileTypeHint:nil)
sound.prepareToPlay()
sound.play()
} catch {
//Handle the error
}
}
Related
I've had this bug where i use avfoundation to make a path to my audio file so when i use this line of code
audioPlayer = try AVAudioPlayer(contentsOf: URL.init(fileURLWithPath: Bundle.main.path(forResource: "Alone", ofType: "m4r")!))
audioPlayer.prepareToPlay()
It crashes and gives me
fatal error: unexpectedly found nil while unwrapping an Optional value
I have all the code right as the compiler dosen't show any errors.
I am using Xcode 9 and swift 4
This happen because you do forced unwrapping of non-existed path. Generally it's a bad practice. Try to avoid forced unwrapping.
Try this:
guard let path = Bundle.main.path(forResource: "Alone", ofType: "m4r") else {
print("wrong path")
return
}
let url = URL(fileURLWithPath: path)
audioPlayer = try AVAudioPlayer(contentsOf: url)
audioPlayer.prepareToPlay()
Then if you see a "wrong path" in debug console that means the resource with filename "Alone" and extension "m4r" doesn't exist in your app bundle.
Hope this help.
I ve just upgrade from Swift 2 to Swift 3, and i m facing a new challenge...
I have a player which run perfectly before, but now i have this following issue : "unexpectedly found nil while unwrapping an Optional value"
Here is my code :
print(audioselectionne)
let alertSound = URL(fileURLWithPath: Bundle.main.path(forResource: audioselectionne as String, ofType: "mp3")!)
I ve got : Optional("tiesto") and the crash...
I really dont understand where is the issue...
Thanks for the help.
You should unwrap the optional, perhaps with optional binding.
BTW, you shouldn't be use path strings at all anymore. Just use the URL directly, e.g.
guard let resource = audioselectionne, let alertSound = Bundle.main.url(forResource: resource, withExtension: "mp3") else {
// handle file not found here
return
}
// use alertSound here
I think the Bundle.main.path method returns an optional String. When that’s nil (because the resource was not found), force-unwrapping it causes your error. If you want to handle it correctly, you have to check for the nil:
guard let path = Bundle.main.path(…) else {
// resource not found, handle error
}
// now `path` is guaranteed to be non-nil
let alertSound = URL(fileURLWithPath: path)
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.
}
Current code:
#IBAction func sound1(sender: UIButton)
{
var sound = NSURL(fileURLWithPath: NSBundle.mainBundle().pathForResource("Sound1", ofType: "wav")!)
do {
try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
} catch _ {
}
do {
try AVAudioSession.sharedInstance().setActive(true)
} catch _ {
}
var error: NSError?
do {
audioPlayer = try AVAudioPlayer(contentsOfURL: sound)
} catch var error1 as NSError {
error = error1
audioPlayer = nil
}
audioPlayer.prepareToPlay()
audioPlayer.volume = 1
audioPlayer.play()
}
This is the current code I had before updating this project to Swift 2.
audioPlayer = nil
The issue I get when trying to run the app is this:
Cannot assign a value of type 'NilLiteralConvertible' to a value of type 'AVAudioPlayer'
It means that your variable audioplayer is not an Optional and so can not be set to nil.
Either make it an Optional then use it with try? (note the ?) without do catch, or do not attempt to set it to nil if you want to continue using try inside do catch.
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")
}