Reputation: 177
I learn an iOS course in Udacity. I don't know why running this code as below. It will show the message of Thread 1: EXC_BAD_ACCESS (code=1, address=0x0) in the line of try! audioRecorder = AVAudioRecorder(url: filePath!, settings: [:])
import UIKit
import AVFoundation
class RecordViewController: UIViewController, AVAudioRecorderDelegate {
var audioRecorder = AVAudioRecorder()
@IBOutlet weak var recordingLabel: UITextField!
@IBOutlet weak var recordButton: UIButton!
@IBOutlet weak var stopRecordingButton: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
stopRecordingButton.isEnabled = false
// Do any additional setup after loading the view, typically from a nib.
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
print("viewWillAppear called")
}
@IBAction func recordAudio(_ sender: AnyObject) {
recordingLabel.text = "Recording in Progress"
stopRecordingButton.isEnabled = true
recordButton.isEnabled = false
let dirPath = NSSearchPathForDirectoriesInDomains(.documentDirectory,.userDomainMask, true)[0] as String
let recordingName = "recordedVoice.wav"
let pathArray = [dirPath, recordingName]
let filePath = URL(string: pathArray.joined(separator: "/"))
let session = AVAudioSession.sharedInstance()
try! session.setCategory(AVAudioSessionCategoryPlayAndRecord, with:AVAudioSessionCategoryOptions.defaultToSpeaker)
try! audioRecorder = AVAudioRecorder(url: filePath!, settings: [:])
audioRecorder.delegate = self
audioRecorder.isMeteringEnabled = true
audioRecorder.prepareToRecord()
audioRecorder.record()
}
@IBAction func stopRecording(_ sender: Any) {
recordButton.isEnabled = true
stopRecordingButton.isEnabled = false
recordingLabel.text = "Tap to Record"
audioRecorder.stop()
let audioSession = AVAudioSession.sharedInstance()
try! audioSession.setActive(false)
}
func audioRecorderDidFinishRecording(_ recorder: AVAudioRecorder, successfully flag: Bool) {
if flag{
performSegue(withIdentifier: "stopRecording", sender: audioRecorder.url)
}else {
print("recording wasn't successful")
}
}
}
Upvotes: 0
Views: 605
Reputation: 285250
You are using the wrong API.
URL(string:
is for strings representing a full URL including the scheme (http://
, ftp://
, file://
).
The correct API for file paths starting with a slash is URL(fileURLWithPath
.
Secondly NSSearchPathForDirectoriesInDomains
and concatenating path components manually is outdated. Use the URL related API, this solves the error by the way.
let documentsURL = try! FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false)
let fileURL = documentsURL.appendingPathComponent("recordedVoice.wav")
This try!
cannot crash because the OS creates always the documents folder if it doesn't exist.
For API which can really throw
errors add error handling
do {
try session.setCategory(AVAudioSessionCategoryPlayAndRecord, with:AVAudioSessionCategoryOptions.defaultToSpeaker)
try audioRecorder = AVAudioRecorder(url: filePath!, settings: [:])
audioRecorder.delegate = self
...
} catch { print(error) }
Upvotes: 1
Reputation: 72
i think you must use try like this AVAudioPlayer
var resourcePath = url //your url
var objectData = Data(contentsOf: NSURL(string: resourcePath)!)
var error: Error!
do {
audioPlayer = try AVAudioPlayer(objectData)
}
catch let error {
}
audioPlayer.numberOfLoops = 0
audioPlayer.volume = 1.0
audioPlayer.prepareToPlay()
if audioPlayer == nil {
print("\(error.description)")
}
else {
audioPlayer.play()
}
Upvotes: 1