我有一个带有longPressGestureRecognizer的UIButton,如果用户点击并按住按钮,语音识别开始,释放按钮,语音文本出现在textField中 它工作正常,但Apple的Speech Framework需要有效的互联网连接。出于这个原因,我希望用户通过警报获得相应的消息。 就是这样,我试着自己处理它:
enum InternetConnectionError: Error {
case noInternet
case lowInternetSpeed
}
// start the recognition
@IBAction func longPressAddArticles(_ sender: UILongPressGestureRecognizer) {
if sender.state == .began {
do {
try startSession()
} catch InternetConnectionError.noInternet {
displayInformationAlert(message: "Sorry, please check your internet connection!")
} catch InternetConnectionError.lowInternetSpeed {
displayInformationAlert(message: "Sorry your internet is to slow!")
// catch All other errors
} catch let error as Error {
displayInformationAlert(message: "Unknown error!")
}
} else if sender.state == .ended {
if audioEngine.isRunning {
audioEngine.stop()
speechRecognitionRequest?.endAudio()
}
}
}
func displayInformationAlert(message: String) {
let alert = UIAlertController(title: "Attention", message: message, preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: .cancel))
present(alert, animated: true)
}
private func startSession() throws {
// check if a previous recognition task is running, and if so cancel it
if let recognitionTask = speechRecognitionTask {
recognitionTask.cancel()
self.speechRecognitionTask = nil
}
let audioSession = AVAudioSession.sharedInstance()
try audioSession.setCategory(AVAudioSessionCategoryRecord)
speechRecognitionRequest = SFSpeechAudioBufferRecognitionRequest()
guard let recognitionRequest = speechRecognitionRequest else {
throw InternetConnectionError.noInternet
}
guard let inputNode = audioEngine.inputNode else {
throw InternetConnectionError.lowInternetSpeed
}
let recordingFormat = inputNode.outputFormat(forBus: 0)
inputNode.installTap(onBus: 0, bufferSize: 1024, format: recordingFormat) { buffer, _ in
self.speechRecognitionRequest?.append(buffer)
}
audioEngine.prepare()
do {
try audioEngine.start()
} catch {
displayInformationAlert(message: "The recognition could'n start!")
}
speechRecognitionRequest?.shouldReportPartialResults = false
speechRecognitionTask = speechRecognizer.recognitionTask(with: recognitionRequest) { result, error in
var finished = false
if let result = result {
let articleName = result.bestTranscription.formattedString
if (self.checkIfShopExists(name:articleName)) {
self.delegate?.openExistShopWith(name: articleName)
} else {
self.createNewArticle(name: articleName)
}
finished = result.isFinal
}
if error != nil || finished {
self.audioEngine.stop()
inputNode.removeTap(onBus: 0)
self.speechRecognitionRequest = nil
self.speechRecognitionTask = nil
self.btnRecordButton.isEnabled = true
}
}
}
如果我在飞行模式下开启iPhone,启动应用程序,多次按下按钮,应用程序崩溃,无需一些有用的崩溃报告
答案 0 :(得分:0)
我使用此功能检查互联网是否是您功能的第一行。然后只使用一个保护声明,只有在有互联网的情况下才能继续。
func isInternetAvailable() -> Bool
{
var zeroAddress = sockaddr_in()
zeroAddress.sin_len = UInt8(MemoryLayout.size(ofValue: zeroAddress))
zeroAddress.sin_family = sa_family_t(AF_INET)
let defaultRouteReachability = withUnsafePointer(to: &zeroAddress) {
$0.withMemoryRebound(to: sockaddr.self, capacity: 1) {zeroSockAddress in
SCNetworkReachabilityCreateWithAddress(nil, zeroSockAddress)
}
}
var flags = SCNetworkReachabilityFlags()
if !SCNetworkReachabilityGetFlags(defaultRouteReachability!, &flags) {
return false
}
let isReachable = (flags.rawValue & UInt32(kSCNetworkFlagsReachable)) != 0
let needsConnection = (flags.rawValue & UInt32(kSCNetworkFlagsConnectionRequired)) != 0
return (isReachable && !needsConnection)
}