2017-05-18 77 views
0

我有一个与longPressGestureRecognizer UIButton,如果用户点击并按住按钮,语音识别开始,释放按钮和口语文本出现在textField 它工作正常,但语音框架来自Apple需要有效的互联网连接。出于这个原因,我想,用户通过警报获得适当的消息。 就是那样,我尝试处理它我的自我:处理没有互联网连接语音中的错误

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在飞行模式下,启动应用程序,按下按钮了很多次,应用程序崩溃,内部消除了一些有用的崩溃报告

enter image description here 有些想法?

+0

什么是您的控制台输出? – brimstone

+0

这就是要点:没​​什么。正如你在图片中看到的那样,我发布了我的问题。该应用程序崩溃,AppDelegate出现与“线程1:信号SIGABRT” –

+0

这不是控制台,点击右下角的其他面板显示控制台。 – brimstone

回答

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) 
}