Fixing bugs with audio records.

Editing plate numbers in audio records
This commit is contained in:
Selim Mustafaev 2020-07-17 01:04:50 +03:00
parent 6a53f7d953
commit c5e5a343d3
4 changed files with 71 additions and 10 deletions

View File

@ -99,6 +99,10 @@ class RecordsController: UIViewController, UITableViewDelegate {
activity.becomeCurrent() activity.becomeCurrent()
} }
func stopRecording() {
self.recorder?.stopRecording()
}
// MARK: - Bar button handlers // MARK: - Bar button handlers
@objc func onAddVoiceRecord(_ sender: UIBarButtonItem) { @objc func onAddVoiceRecord(_ sender: UIBarButtonItem) {
@ -150,6 +154,7 @@ class RecordsController: UIViewController, UITableViewDelegate {
.replacingOccurrences(of: " ", with: "") .replacingOccurrences(of: " ", with: "")
.uppercased() .uppercased()
.replacingOccurrences(of: "Ф", with: "В") .replacingOccurrences(of: "Ф", with: "В")
.replacingOccurrences(of: "НОЛЬ", with: "0")
var result = "" var result = ""
if let range = trimmed.range(of: #"\S\d\d\d\S\S\d\d\d?"#, options: .regularExpression) { if let range = trimmed.range(of: #"\S\d\d\d\S\S\d\d\d?"#, options: .regularExpression) {
@ -172,13 +177,20 @@ class RecordsController: UIViewController, UITableViewDelegate {
} }
func valid(number: String) -> Bool { func valid(number: String) -> Bool {
guard number.count >= 8 else { return false }
let first = String(number.prefix(1)) let first = String(number.prefix(1))
let second = number.substring(with: 4..<5) let second = number.substring(with: 4..<5)
let third = number.substring(with: 5..<6) let third = number.substring(with: 5..<6)
let digits = Int(number.substring(with: 1..<4))
let region = Int(number.substring(from: 6))
return self.validLetters.contains(first) return self.validLetters.contains(first)
&& self.validLetters.contains(second) && self.validLetters.contains(second)
&& self.validLetters.contains(third) && self.validLetters.contains(third)
&& digits != nil
&& region != nil
&& region! < 1000
} }
func makeStartSoundIfNeeded(completion: @escaping () throws -> Void) throws { func makeStartSoundIfNeeded(completion: @escaping () throws -> Void) throws {
@ -257,6 +269,11 @@ class RecordsController: UIViewController, UITableViewDelegate {
let showText = UIAlertAction(title: "Show recognized text", style: .default) { action in let showText = UIAlertAction(title: "Show recognized text", style: .default) { action in
self.showAlert(title: "Recognized text", message: record.rawText) self.showAlert(title: "Recognized text", message: record.rawText)
} }
let editNumber = UIAlertAction(title: "Edit plate number", style: .default) { action in
self.edit(record: record)
}
sheet.addAction(editNumber)
sheet.addAction(showText) sheet.addAction(showText)
sheet.addAction(share) sheet.addAction(share)
sheet.addAction(cancel) sheet.addAction(cancel)
@ -270,4 +287,27 @@ class RecordsController: UIViewController, UITableViewDelegate {
ad.quickAction = .checkNumber(number) ad.quickAction = .checkNumber(number)
self.tabBarController?.selectedIndex = 0 self.tabBarController?.selectedIndex = 0
} }
func edit(record: AudioRecord) {
let alert = UIAlertController(title: "Edit plate number", message: nil, preferredStyle: .alert)
let done = UIAlertAction(title: "Done", style: .default) { action in
guard let tf = alert.textFields?.first else { return }
if let realm = try? Realm() {
try? realm.write {
record.number = tf.text?.uppercased()
}
}
}
alert.addAction(done)
alert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: { action in
alert.dismiss(animated: true)
}))
alert.addTextField { tf in
tf.text = record.number ?? record.rawText
NotificationCenter.default.addObserver(forName: UITextField.textDidChangeNotification, object: tf, queue: OperationQueue.main) { _ in
done.isEnabled = self.valid(number: tf.text?.uppercased() ?? "")
}
}
self.present(alert, animated: true)
}
} }

View File

@ -58,8 +58,19 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
// Use this method to save data, release shared resources, and store enough scene-specific state information // Use this method to save data, release shared resources, and store enough scene-specific state information
// to restore the scene back to its current state. // to restore the scene back to its current state.
if let split = self.window?.rootViewController as? MainSplitController, let tabvc = split.viewControllers.first as? UITabBarController {
if tabvc.selectedIndex == 1 {
if let nav = tabvc.selectedViewController as? UINavigationController, let child = nav.topViewController {
print(type(of: child))
if let record = child as? RecordsController {
record.stopRecording()
}
}
}
}
do { do {
try AVAudioSession.sharedInstance().setActive(false) try AVAudioSession.sharedInstance().setActive(false, options: .notifyOthersOnDeactivation)
} catch { } catch {
print("sceneDidEnterBackground failed to deactivate audio session: \(error.localizedDescription)") print("sceneDidEnterBackground failed to deactivate audio session: \(error.localizedDescription)")
} }

View File

@ -34,7 +34,7 @@ class AudioPlayer: NSObject, AVAudioPlayerDelegate {
if let player = self.player { if let player = self.player {
if player.isPlaying { if player.isPlaying {
player.pause() player.pause()
try AVAudioSession.sharedInstance().setActive(false) try self.deactivateSession()
self.state.accept(.paused) self.state.accept(.paused)
} else { } else {
try AVAudioSession.sharedInstance().setCategory(.playback, mode: .default, options: [.duckOthers]) try AVAudioSession.sharedInstance().setCategory(.playback, mode: .default, options: [.duckOthers])
@ -56,7 +56,7 @@ class AudioPlayer: NSObject, AVAudioPlayerDelegate {
func pause() { func pause() {
if let player = self.player { if let player = self.player {
player.pause() player.pause()
try? AVAudioSession.sharedInstance().setActive(false) try? self.deactivateSession()
self.state.accept(.paused) self.state.accept(.paused)
} }
} }
@ -64,7 +64,7 @@ class AudioPlayer: NSObject, AVAudioPlayerDelegate {
func stop() { func stop() {
if let player = self.player { if let player = self.player {
player.stop() player.stop()
try? AVAudioSession.sharedInstance().setActive(false) try? self.deactivateSession()
self.state.accept(.stopped) self.state.accept(.stopped)
self.progressTimer?.invalidate() self.progressTimer?.invalidate()
self.progressTimer = nil self.progressTimer = nil
@ -95,10 +95,14 @@ class AudioPlayer: NSObject, AVAudioPlayerDelegate {
return self.progress.asObservable() return self.progress.asObservable()
} }
func deactivateSession() throws {
try AVAudioSession.sharedInstance().setActive(false, options: .notifyOthersOnDeactivation)
}
// MARK: - AVAudioPlayerDelegate // MARK: - AVAudioPlayerDelegate
func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool) { func audioPlayerDidFinishPlaying(_ player: AVAudioPlayer, successfully flag: Bool) {
try? AVAudioSession.sharedInstance().setActive(false) try? self.deactivateSession()
self.progress.accept(1) self.progress.accept(1)
self.stop() self.stop()
self.state.accept(.stopped) self.state.accept(.stopped)

View File

@ -85,14 +85,14 @@ class Recorder {
self.result = transcription.formattedString self.result = transcription.formattedString
self.endRecognitionTimer?.invalidate() self.endRecognitionTimer?.invalidate()
self.endRecognitionTimer = Timer.scheduledTimer(withTimeInterval: 2, repeats: false) { timer in self.endRecognitionTimer = Timer.scheduledTimer(withTimeInterval: 2, repeats: false) { timer in
self.stopRecording() self.finishRecording()
completion(self.result) completion(self.result)
} }
} }
} }
self.endRecognitionTimer = Timer.scheduledTimer(withTimeInterval: 5, repeats: false) { timer in self.endRecognitionTimer = Timer.scheduledTimer(withTimeInterval: 5, repeats: false) { timer in
self.stopRecording() self.finishRecording()
completion(self.result) completion(self.result)
} }
@ -101,20 +101,26 @@ class Recorder {
} }
func cancelRecording() { func cancelRecording() {
self.stopRecording() self.finishRecording()
self.endRecognitionTimer?.invalidate() self.endRecognitionTimer?.invalidate()
self.endRecognitionTimer = nil self.endRecognitionTimer = nil
} }
func stopRecording() { func finishRecording() {
self.engine.stop() self.engine.stop()
self.engine.inputNode.removeTap(onBus: 0) self.engine.inputNode.removeTap(onBus: 0)
self.request.endAudio() self.request.endAudio()
self.recognitionTask?.cancel() self.recognitionTask?.cancel()
try? AVAudioSession.sharedInstance().setActive(false) try? AVAudioSession.sharedInstance().setActive(false, options: .notifyOthersOnDeactivation)
if let fileRef = self.fileRef { if let fileRef = self.fileRef {
ExtAudioFileDispose(fileRef) ExtAudioFileDispose(fileRef)
} }
} }
func stopRecording() {
self.finishRecording()
self.endRecognitionTimer?.fire()
self.endRecognitionTimer = nil
}
} }