Posts

Post not yet marked as solved
0 Replies
302 Views
Hello,I'm new in programming and I'm trying to make a recording app but I've been stuck with an error; Fatal error: Unexpectedly found nil while unwrapping an optional value . I searched all over the internet and found so much answers but some how I can't fix it. I want to learn how to fix this error.The error happens in line 41, before I add the ? to audioFile. Now The error happens in line 91.Please note I can record and get the recorded file from directory, but the app crashes at that pointAlso in the console I'm receiving this error but the app isn't crashing:Optional(/Users/belal/Library/Developer/CoreSimulator/Devices/ADD7FEB7-F61B-4999-B148-8951C0B2F6A3/data/Containers/Data/Applicati ... oice.wav)2019-08-06 19:12:44.994689+0300 Sound Recorder[1289:26015] 317: ca_debug_string: inPropertyData == NULLThanks in advance.Here is my code:// // PlaySoundsViewController=Audio.swift // Sound Recorder // // Created by Belal Gawish on 8/3/19. // Copyright © 2019 Belal Gawish. All rights reserved. // import UIKit import AVFoundation // MARK: - PlaySoundsViewController: AVAudioPlayerDelegate extension PlaySoundsViewController: AVAudioPlayerDelegate { // MARK: Alerts struct Alerts { static let DismissAlert = "Dismiss" static let RecordingDisabledTitle = "Recording Disabled" static let RecordingDisabledMessage = "You've disabled this app from recording your microphone, Check your Settings." static let RecordingFailedTitle = "Recording Failed" static let RecordingFailedMessage = "Something went wrong with your recording." static let AudioRecorderError = "Audio Recorder Error" static let AudioSessionError = "Audio Session Error" static let AudioRecordingError = "Audio Recording Error" static let AudioFileError = "Audio File Error" static let AudioEngineError = "Audio Engine Error" } // MARK: PlayingState (raw values correspond to sender tags) enum PlayingState { case playing, notPlaying } // MARK: Audio Functions func setupAudio() { // initialize (recording) audio file do { audioFile? = try AVAudioFile(forReading: recordedAudioURL as URL) } catch { showAlert(Alerts.AudioFileError, message: String(describing: error)) } } func playSound(rate: Float? = nil, pitch: Float? = nil, echo: Bool = false, reverb: Bool = false) { // initialize audio engine components audioEngine = AVAudioEngine() // node for playing audio audioPlayerNode = AVAudioPlayerNode() audioEngine.attach(audioPlayerNode) // node for adjusting rate/pitch let changeRatePitchNode = AVAudioUnitTimePitch() if let pitch = pitch { changeRatePitchNode.pitch = pitch } if let rate = rate { changeRatePitchNode.rate = rate } audioEngine.attach(changeRatePitchNode) // node for echo let echoNode = AVAudioUnitDistortion() echoNode.loadFactoryPreset(.multiEcho1) audioEngine.attach(echoNode) // node for reverb let reverbNode = AVAudioUnitReverb() reverbNode.loadFactoryPreset(.cathedral) reverbNode.wetDryMix = 50 audioEngine.attach(reverbNode) // connect nodes if echo == true && reverb == true { connectAudioNodes(audioPlayerNode, changeRatePitchNode, echoNode, reverbNode, audioEngine.outputNode) } else if echo == true { connectAudioNodes(audioPlayerNode, changeRatePitchNode, echoNode, audioEngine.outputNode) } else if reverb == true { connectAudioNodes(audioPlayerNode, changeRatePitchNode, reverbNode, audioEngine.outputNode) } else { connectAudioNodes(audioPlayerNode, changeRatePitchNode, audioEngine.outputNode) } // schedule to play and start the engine! audioPlayerNode.stop() audioPlayerNode.scheduleFile(audioFile, at: nil) { var delayInSeconds: Double = 0 if let lastRenderTime = self.audioPlayerNode.lastRenderTime, let playerTime = self.audioPlayerNode.playerTime(forNodeTime: lastRenderTime) { if let rate = rate { delayInSeconds = Double(self.audioFile.length - playerTime.sampleTime) / Double(self.audioFile.processingFormat.sampleRate) / Double(rate) } else { delayInSeconds = Double(self.audioFile.length - playerTime.sampleTime) / Double(self.audioFile.processingFormat.sampleRate) } } // schedule a stop timer for when audio finishes playing self.stopTimer = Timer(timeInterval: delayInSeconds, target: self, selector: #selector(PlaySoundsViewController.stopAudio), userInfo: nil, repeats: false) RunLoop.main.add(self.stopTimer!, forMode: RunLoop.Mode.default) } do { try audioEngine.start() } catch { showAlert(Alerts.AudioEngineError, message: String(describing: error)) return } // play the recording! audioPlayerNode.play() } @objc func stopAudio() { if let audioPlayerNode = audioPlayerNode { audioPlayerNode.stop() } if let stopTimer = stopTimer { stopTimer.invalidate() } configureUI(.notPlaying) if let audioEngine = audioEngine { audioEngine.stop() audioEngine.reset() } } // MARK: Connect List of Audio Nodes func connectAudioNodes(_ nodes: AVAudioNode...) { for x in 0.. audioEngine.connect(nodes[x], to: nodes[x+1], format: audioFile?.processingFormat) } } // MARK: UI Functions func configureUI(_ playState: PlayingState) { switch(playState) { case .playing: setPlayButtonsEnabled(false) stopButton.isEnabled = true case .notPlaying: setPlayButtonsEnabled(true) stopButton.isEnabled = false } } func setPlayButtonsEnabled(_ enabled: Bool) { snailButton.isEnabled = enabled chipmunkButton.isEnabled = enabled rabbitButton.isEnabled = enabled vaderButton.isEnabled = enabled echoButton.isEnabled = enabled reverbButton.isEnabled = enabled } func showAlert(_ title: String, message: String) { let alert = UIAlertController(title: title, message: message, preferredStyle: .alert) alert.addAction(UIAlertAction(title: Alerts.DismissAlert, style: .default, handler: nil)) self.present(alert, animated: true, completion: nil) } }
Posted
by Bill_G212.
Last updated
.