diff --git a/AutoCat.xcodeproj/project.pbxproj b/AutoCat.xcodeproj/project.pbxproj index b30ac4c..2cf5a56 100644 --- a/AutoCat.xcodeproj/project.pbxproj +++ b/AutoCat.xcodeproj/project.pbxproj @@ -76,6 +76,7 @@ 7A7547DE2403180A004E8406 /* SectionHeader.xib in Resources */ = {isa = PBXBuildFile; fileRef = 7A7547DC2403180A004E8406 /* SectionHeader.xib */; }; 7A7547E024032CB6004E8406 /* VehiclePhotoCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A7547DF24032CB6004E8406 /* VehiclePhotoCell.swift */; }; 7A813DBE2506A57100CC93B9 /* AuthenticationServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7A813DBD2506A57100CC93B9 /* AuthenticationServices.framework */; }; + 7A813DC12508C4D900CC93B9 /* ExceptionCatcher in Frameworks */ = {isa = PBXBuildFile; productRef = 7A813DC02508C4D900CC93B9 /* ExceptionCatcher */; }; 7A8A2209248D10EC0073DFD9 /* ResizeImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A8A2208248D10EC0073DFD9 /* ResizeImage.swift */; }; 7A8A220B248D67B60073DFD9 /* VehicleReportImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A8A220A248D67B60073DFD9 /* VehicleReportImage.swift */; }; 7A96AE2A246AFD6200297C33 /* Eureka in Frameworks */ = {isa = PBXBuildFile; productRef = 7A96AE29246AFD6200297C33 /* Eureka */; }; @@ -185,6 +186,7 @@ 7A813DBE2506A57100CC93B9 /* AuthenticationServices.framework in Frameworks */, 7AF58D342402A91C00CE01A0 /* Kingfisher in Frameworks */, 7A0516162414EC1200FC55AC /* Differentiator in Frameworks */, + 7A813DC12508C4D900CC93B9 /* ExceptionCatcher in Frameworks */, 7A96AE2F246B2BCD00297C33 /* WebKit.framework in Frameworks */, 7A11472823FEA1F400B424AF /* RealmSwift in Frameworks */, 7A11472123FEA18700B424AF /* RxCocoa in Frameworks */, @@ -431,6 +433,7 @@ 7A0516152414EC1200FC55AC /* Differentiator */, 7A0516172414EC1200FC55AC /* RxDataSources */, 7A96AE29246AFD6200297C33 /* Eureka */, + 7A813DC02508C4D900CC93B9 /* ExceptionCatcher */, ); productName = AutoCat; productReference = 7A1146FD23FDE7E500B424AF /* AutoCat.app */; @@ -470,6 +473,7 @@ 7A05160F241412CA00FC55AC /* XCRemoteSwiftPackageReference "SwiftDate" */, 7A0516142414EC1200FC55AC /* XCRemoteSwiftPackageReference "RxDataSources" */, 7A96AE28246AFD6200297C33 /* XCRemoteSwiftPackageReference "Eureka" */, + 7A813DBF2508C4D900CC93B9 /* XCRemoteSwiftPackageReference "ExceptionCatcher" */, ); productRefGroup = 7A1146FE23FDE7E500B424AF /* Products */; projectDirPath = ""; @@ -711,7 +715,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_ENTITLEMENTS = AutoCat/AutoCat.entitlements; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 26; + CURRENT_PROJECT_VERSION = 28; DEVELOPMENT_TEAM = 46DTTB8X4S; INFOPLIST_FILE = AutoCat/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 13.0; @@ -733,7 +737,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_ENTITLEMENTS = AutoCat/AutoCat.entitlements; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 26; + CURRENT_PROJECT_VERSION = 28; DEVELOPMENT_TEAM = 46DTTB8X4S; INFOPLIST_FILE = AutoCat/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 13.0; @@ -821,6 +825,14 @@ minimumVersion = 3.0.0; }; }; + 7A813DBF2508C4D900CC93B9 /* XCRemoteSwiftPackageReference "ExceptionCatcher" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/sindresorhus/ExceptionCatcher"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 1.1.0; + }; + }; 7A96AE28246AFD6200297C33 /* XCRemoteSwiftPackageReference "Eureka" */ = { isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/xmartlabs/Eureka"; @@ -903,6 +915,11 @@ package = 7A530B89240181F500CBFE6E /* XCRemoteSwiftPackageReference "RxRealm" */; productName = RxRealm; }; + 7A813DC02508C4D900CC93B9 /* ExceptionCatcher */ = { + isa = XCSwiftPackageProductDependency; + package = 7A813DBF2508C4D900CC93B9 /* XCRemoteSwiftPackageReference "ExceptionCatcher" */; + productName = ExceptionCatcher; + }; 7A96AE29246AFD6200297C33 /* Eureka */ = { isa = XCSwiftPackageProductDependency; package = 7A96AE28246AFD6200297C33 /* XCRemoteSwiftPackageReference "Eureka" */; diff --git a/AutoCat.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/AutoCat.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index e3323e5..ffef2dc 100644 --- a/AutoCat.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/AutoCat.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -10,6 +10,15 @@ "version": "5.2.1" } }, + { + "package": "ExceptionCatcher", + "repositoryURL": "https://github.com/sindresorhus/ExceptionCatcher", + "state": { + "branch": null, + "revision": "3787f25119e1406b4c5e47fc654626a9d5d7e111", + "version": "1.1.0" + } + }, { "package": "InputMask", "repositoryURL": "https://github.com/RedMadRobot/input-mask-ios", diff --git a/AutoCat/Controllers/RecordsController.swift b/AutoCat/Controllers/RecordsController.swift index 9dfe0d7..b16e4fd 100644 --- a/AutoCat/Controllers/RecordsController.swift +++ b/AutoCat/Controllers/RecordsController.swift @@ -7,6 +7,7 @@ import RxDataSources import Intents import CoreSpotlight import MobileCoreServices +import os.log class RecordsController: UIViewController, UITableViewDelegate { @@ -113,6 +114,8 @@ class RecordsController: UIViewController, UITableViewDelegate { return } + self.addButton.isEnabled = false + var alert: UIAlertController? var url: URL! @@ -134,12 +137,11 @@ class RecordsController: UIViewController, UITableViewDelegate { } self.audioSessionObserver = NotificationCenter.default.addObserver(forName: AVAudioSession.routeChangeNotification, object: nil, queue: .main) { notification in guard let dict = notification.userInfo as? [String: Any], - let prev = dict["AVAudioSessionRouteChangePreviousRouteKey"] as? AVAudioSessionRouteDescription, let reasonInt = dict["AVAudioSessionRouteChangeReasonKey"] as? NSNumber, let reason = AVAudioSession.RouteChangeReason(rawValue: reasonInt.uintValue), let session = notification.object as? AVAudioSession else { return } - if reason == .categoryChange && session.category == .playAndRecord && prev.inputs.isEmpty && !session.currentRoute.inputs.isEmpty { + if reason == .categoryChange && session.category == .playAndRecord { alert = self.showRecordingAlert() } } @@ -163,6 +165,7 @@ class RecordsController: UIViewController, UITableViewDelegate { realm?.add(record) } alert?.dismiss(animated: true) + self.addButton.isEnabled = true }) { error in if let alert = alert { alert.dismiss(animated: true) { @@ -171,6 +174,7 @@ class RecordsController: UIViewController, UITableViewDelegate { } else { IHProgressHUD.show(error: error) } + self.addButton.isEnabled = true } } diff --git a/AutoCat/Controllers/ReportController.swift b/AutoCat/Controllers/ReportController.swift index 156bed6..2625f09 100644 --- a/AutoCat/Controllers/ReportController.swift +++ b/AutoCat/Controllers/ReportController.swift @@ -87,7 +87,7 @@ class ReportController: UIViewController, UICollectionViewDataSource, UICollecti private let fullWidth = MagazineLayoutItemSizeMode(widthMode: .fullWidth(respectsHorizontalInsets: true), heightMode: .dynamic) private var reportImageUrl: URL? - private var vehicle: Vehicle? { + var vehicle: Vehicle? { didSet { loadViewIfNeeded() self.collection.reloadData() @@ -275,6 +275,7 @@ class ReportController: UIViewController, UICollectionViewDataSource, UICollecti else if let events = self.vehicle?.events, indexPath.row == ReportGeneralSection.events.rawValue && events.count > 0 { let controller = sb.instantiateViewController(identifier: "EventsController") as EventsController controller.events = Array(events) + controller.title = self.vehicle?.number ?? "Events" self.navigationController?.pushViewController(controller, animated: true) } } diff --git a/AutoCat/Controllers/SearchController.swift b/AutoCat/Controllers/SearchController.swift index eda2e89..d2a7f4b 100644 --- a/AutoCat/Controllers/SearchController.swift +++ b/AutoCat/Controllers/SearchController.swift @@ -67,7 +67,7 @@ class SearchController: UIViewController, UISearchResultsUpdating { if let detail = detail { detail.popToRootViewController(animated: true) let report = detail.viewControllers.first as? ReportController - report?.number = vehicle.number + report?.vehicle = vehicle splitViewController.showDetailViewController(detail, sender: self) //self.performSegue(withIdentifier: "OpenDetailSegue", sender: self) } diff --git a/AutoCat/Utils/Constants.swift b/AutoCat/Utils/Constants.swift index 5afbb1c..0ce0772 100644 --- a/AutoCat/Utils/Constants.swift +++ b/AutoCat/Utils/Constants.swift @@ -3,9 +3,9 @@ import Foundation enum Constants { static var baseUrl: String { #if DEBUG - return "http://127.0.0.1:3000/" + //return "http://127.0.0.1:3000/" //return "http://192.168.1.67:3000/" - //return "https://vps.aliencat.pro:8443/" + return "https://vps.aliencat.pro:8443/" #else return "https://vps.aliencat.pro:8443/" #endif diff --git a/AutoCat/Utils/Recorder.swift b/AutoCat/Utils/Recorder.swift index f8e5cfe..ea12b8e 100644 --- a/AutoCat/Utils/Recorder.swift +++ b/AutoCat/Utils/Recorder.swift @@ -4,6 +4,7 @@ import AVFoundation import AudioToolbox import RxSwift import os.log +import ExceptionCatcher class Recorder { @@ -93,9 +94,11 @@ class Recorder { let inFormat = self.engine.inputNode.outputFormat(forBus: 0) ExtAudioFileSetProperty(fileRef, kExtAudioFileProperty_ClientDataFormat, UInt32(MemoryLayout.size), inFormat.streamDescription) - self.engine.inputNode.installTap(onBus: 0, bufferSize: 1024, format: inFormat) { buffer, time in - self.request.append(buffer) - ExtAudioFileWrite(fileRef, buffer.frameLength, buffer.audioBufferList) + try ExceptionCatcher.catch { + self.engine.inputNode.installTap(onBus: 0, bufferSize: 1024, format: inFormat) { buffer, time in + self.request.append(buffer) + ExtAudioFileWrite(fileRef, buffer.frameLength, buffer.audioBufferList) + } } self.recognitionTask = self.recognizer!.recognitionTask(with: self.request) { result, error in @@ -138,6 +141,7 @@ class Recorder { self.request.endAudio() self.recognitionTask?.cancel() try? AVAudioSession.sharedInstance().setActive(false, options: .notifyOthersOnDeactivation) + try? AVAudioSession.sharedInstance().setCategory(.soloAmbient) if let fileRef = self.fileRef { ExtAudioFileDispose(fileRef)