2017-05-18 97 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) 
}