Reputation: 3
I am trying to play a mp3 file(5 seconds) when app launched and I keep getting the error:
Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value
import UIKit
import AudioToolbox
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
//create SystemSoundID
var soundID:SystemSoundID = 0
let path = Bundle.main.path(forResource: "iPhone100Voice", ofType: "mp3")
let baseURL = NSURL(fileURLWithPath: path!)
AudioServicesCreateSystemSoundID(baseURL, &soundID)
//play
AudioServicesPlaySystemSound(soundID)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Can anyone explain why and how I can fix this?
Upvotes: 0
Views: 2415
Reputation: 427
It may be help's to you to play video. While adding video file into project make sure target checkbox selected or not in file inspector.
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(true)
if let path = Bundle.main.path(forResource: "video_1523966087401 (1)", ofType: ".mp4"){
let player = AVPlayer(url: URL(fileURLWithPath: path))
let playerController = AVPlayerViewController()
playerController.player = player
present(playerController, animated: true) {
player.play()
}
}else{
//show dialog to user
print("Error: File not found")
}
}
Upvotes: 0
Reputation: 285059
Check these points, all conditions must be true:
Target Membership
checkbox checked in the File Inspector (to get it select the file and press ⌥⌘1)iPhone100Voice.mp3
)?Upvotes: 1
Reputation: 3494
Please check your file name, maybe filename is incorrect or not in the bundle
So please check file name with extension.
Use if let
or guard
to unwrap
the path:
override func viewDidLoad() {
super.viewDidLoad()
var soundID:SystemSoundID = 0
if let path = Bundle.main.path(forResource: "iPhone100Voice", ofType: "mp3") {
let baseURL = NSURL(fileURLWithPath: path)
AudioServicesCreateSystemSoundID(baseURL, &soundID)
AudioServicesPlaySystemSound(soundID)
} else {
let alert = UIAlertController(title: "Alert", message: "File not found in your bundle", preferredStyle: UIAlertControllerStyle.alert)
alert.addAction(UIAlertAction(title: "OK", style: UIAlertActionStyle.cancel, handler: nil))
self.present(alert, animated: true, completion: nil)
}
}
Upvotes: 0
Reputation: 2315
!
means crash operator, it unwraps optional value. Value there works as like Optional(53) , for say. So the variable should contain value except nil, when path!
tries to unwrap optional and appends value 53 in path variable.
to fix this we can use two ways
Using guard,
guard let pathValue = path else {
return
}
let baseURL = NSURL(fileURLWithPath: pathValue) //no need to use pathValue, if you use then you have to use path!, although it makes no crash now.
AudioServicesCreateSystemSoundID(baseURL, &soundID)
//play
AudioServicesPlaySystemSound(soundID)
if path is nil, it enters the block and return , if it has value , it continues to next line.
using if-let, knowing optional binding
if let pathValue = path {
let baseURL = NSURL(fileURLWithPath: pathValue) //same comment
AudioServicesCreateSystemSoundID(baseURL, &soundID)
//play
AudioServicesPlaySystemSound(soundID)
}
Now, if path is optional , can't reach the block and pass to next line
Upvotes: -1