diff --git a/AutoCat.xcodeproj/project.pbxproj b/AutoCat.xcodeproj/project.pbxproj index 1bb90c5..38a0c76 100644 --- a/AutoCat.xcodeproj/project.pbxproj +++ b/AutoCat.xcodeproj/project.pbxproj @@ -54,6 +54,7 @@ 7A6DD90A24329541009DE740 /* RoadNumbers2.0.otf in Resources */ = {isa = PBXBuildFile; fileRef = 7A6DD90924329541009DE740 /* RoadNumbers2.0.otf */; }; 7A6DD90C24335A6D009DE740 /* FlagLayer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A6DD90B24335A6D009DE740 /* FlagLayer.swift */; }; 7A6DD90E24337930009DE740 /* PlateNumber.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A6DD90D24337930009DE740 /* PlateNumber.swift */; }; + 7A6E03282485951700DB22ED /* OwnersController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A6E03272485951700DB22ED /* OwnersController.swift */; }; 7A7547DD2403180A004E8406 /* SectionHeader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A7547DB2403180A004E8406 /* SectionHeader.swift */; }; 7A7547DE2403180A004E8406 /* SectionHeader.xib in Resources */ = {isa = PBXBuildFile; fileRef = 7A7547DC2403180A004E8406 /* SectionHeader.xib */; }; 7A7547E024032CB6004E8406 /* VehiclePhotoCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A7547DF24032CB6004E8406 /* VehiclePhotoCell.swift */; }; @@ -111,6 +112,7 @@ 7A6DD90924329541009DE740 /* RoadNumbers2.0.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = RoadNumbers2.0.otf; sourceTree = ""; }; 7A6DD90B24335A6D009DE740 /* FlagLayer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FlagLayer.swift; sourceTree = ""; }; 7A6DD90D24337930009DE740 /* PlateNumber.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlateNumber.swift; sourceTree = ""; }; + 7A6E03272485951700DB22ED /* OwnersController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OwnersController.swift; sourceTree = ""; }; 7A7547DB2403180A004E8406 /* SectionHeader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SectionHeader.swift; sourceTree = ""; }; 7A7547DC2403180A004E8406 /* SectionHeader.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = SectionHeader.xib; sourceTree = ""; }; 7A7547DF24032CB6004E8406 /* VehiclePhotoCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VehiclePhotoCell.swift; sourceTree = ""; }; @@ -202,6 +204,7 @@ 7AEFE727240455E200910EB7 /* SettingsController.swift */, 7A3F07AC2436350B00E59687 /* SearchController.swift */, 7A96AE2C246B2B7400297C33 /* GoogleSignInController.swift */, + 7A6E03272485951700DB22ED /* OwnersController.swift */, ); path = Controllers; sourceTree = ""; @@ -438,6 +441,7 @@ 7A64AE7F2469E16100ABE48E /* IndefiniteAnimatedView.swift in Sources */, 7A11471A23FE839000B424AF /* AuthController.swift in Sources */, 7A530B7A24001D3300CBFE6E /* CheckController.swift in Sources */, + 7A6E03282485951700DB22ED /* OwnersController.swift in Sources */, 7A64AE742469DFB600ABE48E /* MediaContentView.swift in Sources */, 7A7547DD2403180A004E8406 /* SectionHeader.swift in Sources */, 7AF58D58240309CA00CE01A0 /* VehicleTextParamCell.swift in Sources */, @@ -603,7 +607,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_ENTITLEMENTS = AutoCat/AutoCat.entitlements; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 8; + CURRENT_PROJECT_VERSION = 10; DEVELOPMENT_TEAM = 46DTTB8X4S; INFOPLIST_FILE = AutoCat/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 13.0; @@ -625,7 +629,7 @@ ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_ENTITLEMENTS = AutoCat/AutoCat.entitlements; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 8; + CURRENT_PROJECT_VERSION = 10; DEVELOPMENT_TEAM = 46DTTB8X4S; INFOPLIST_FILE = AutoCat/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 13.0; diff --git a/AutoCat/AppDelegate.swift b/AutoCat/AppDelegate.swift index 2bd49ef..4bdeede 100644 --- a/AutoCat/AppDelegate.swift +++ b/AutoCat/AppDelegate.swift @@ -19,7 +19,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate { func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { let config = Realm.Configuration( - schemaVersion: 5, + schemaVersion: 6, migrationBlock: { migration, oldSchemaVersion in if oldSchemaVersion <= 3 { var numbers: [String] = [] diff --git a/AutoCat/Base.lproj/Main.storyboard b/AutoCat/Base.lproj/Main.storyboard index 3f83ecb..f09052e 100644 --- a/AutoCat/Base.lproj/Main.storyboard +++ b/AutoCat/Base.lproj/Main.storyboard @@ -1,5 +1,5 @@ - + @@ -180,6 +180,21 @@ + + + + + + + + + + + + + + + @@ -193,14 +208,14 @@ - + - + - + diff --git a/AutoCat/Controllers/OwnersController.swift b/AutoCat/Controllers/OwnersController.swift new file mode 100644 index 0000000..3efa15a --- /dev/null +++ b/AutoCat/Controllers/OwnersController.swift @@ -0,0 +1,40 @@ +import UIKit +import Eureka + +class OwnersController: FormViewController { + + public var owners: [VehicleOwnershipPeriod] = [] + + private var formatter = DateFormatter() + + override func viewDidLoad() { + super.viewDidLoad() + + self.formatter.dateStyle = .long + self.formatter.timeStyle = .none + + self.title = "\(self.owners.count) owner(s)" + + for (index, owner) in self.owners.enumerated() { + form +++ Section(header: "", footer: owner.lastOperation) + <<< LabelRow("Owner\(index)") { row in + row.title = "Owner type" + row.value = owner.ownerType + } + <<< LabelRow("From\(index)") { row in + row.title = "From" + let date = Date(timeIntervalSince1970: TimeInterval(owner.from/1000)) + row.value = self.formatter.string(from: date) + } + <<< LabelRow("To\(index)") { row in + row.title = "To" + if owner.to == 0 { + row.value = "now" + } else { + let date = Date(timeIntervalSince1970: TimeInterval(owner.to/1000)) + row.value = self.formatter.string(from: date) + } + } + } + } +} diff --git a/AutoCat/Controllers/ReportController.swift b/AutoCat/Controllers/ReportController.swift index 8d563a9..8cf1910 100644 --- a/AutoCat/Controllers/ReportController.swift +++ b/AutoCat/Controllers/ReportController.swift @@ -22,16 +22,20 @@ enum ReportSection: Int, CaseIterable, CustomStringConvertible { enum ReportGeneralSection: Int, CaseIterable, CustomStringConvertible { case year = 0 - case category = 1 - case wheelPosition = 2 - case japanese = 3 + case color = 1 + case category = 2 + case wheelPosition = 3 + case japanese = 4 + case owners = 5 var description: String { switch self { case .year: return "Year" + case .color: return "Color" case .category: return "Category" case .wheelPosition: return "Steering wheel position" case .japanese: return "Japanese" + case .owners: return "Owners (from PTS)" } } } @@ -145,6 +149,9 @@ class ReportController: UIViewController, UICollectionViewDataSource, UICollecti case .year: cell?.configure(param: generalSection.description, value: String(vehicle.year)) break + case .color: + cell?.configure(param: generalSection.description, value: vehicle.color ?? "") + break case .category: cell?.configure(param: generalSection.description, value: vehicle.category ?? "") break @@ -153,6 +160,10 @@ class ReportController: UIViewController, UICollectionViewDataSource, UICollecti break case .japanese: cell?.configure(param: generalSection.description, value: vehicle.isJapanese ? "Yes" : "No") + break + case .owners: + cell?.configure(param: generalSection.description, value: String(vehicle.ownershipPeriods.count)) + break } } return cell ?? UICollectionViewCell() @@ -217,12 +228,21 @@ class ReportController: UIViewController, UICollectionViewDataSource, UICollecti } func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { - guard indexPath.section == ReportSection.photos.rawValue else { return } - - let mediaBrowser = MediaBrowserViewController(index: indexPath.item, dataSource: self, delegate: self) - mediaBrowser.shouldShowTitle = true - mediaBrowser.title = self.vehicle?.photos[indexPath.item].description - present(mediaBrowser, animated: true, completion: nil) + if indexPath.section == ReportSection.photos.rawValue { + let mediaBrowser = MediaBrowserViewController(index: indexPath.item, dataSource: self, delegate: self) + mediaBrowser.shouldShowTitle = true + mediaBrowser.title = self.vehicle?.photos[indexPath.item].description + present(mediaBrowser, animated: true, completion: nil) + } + + if indexPath.section == ReportSection.general.rawValue { + if indexPath.row == ReportGeneralSection.owners.rawValue { + let sb = UIStoryboard(name: "Main", bundle: nil) + let controller = sb.instantiateViewController(identifier: "OwnersController") as OwnersController + controller.owners = self.vehicle?.ownershipPeriods.toArray() ?? [] + self.navigationController?.pushViewController(controller, animated: true) + } + } } // MARK: - UICollectionViewDelegateMagazineLayout diff --git a/AutoCat/Models/Vehicle.swift b/AutoCat/Models/Vehicle.swift index 7bd9084..aac3814 100644 --- a/AutoCat/Models/Vehicle.swift +++ b/AutoCat/Models/Vehicle.swift @@ -40,6 +40,18 @@ class VehiclePhoto: Object, Decodable { } } +enum OwnerType: String { + case legal + case individual +} + +class VehicleOwnershipPeriod: Object, Decodable { + @objc dynamic var lastOperation: String + @objc dynamic var ownerType: String + @objc dynamic var from: Int64 + @objc dynamic var to: Int64 +} + class Vehicle: Object, Decodable, IdentifiableType { @objc dynamic var brand: VehicleBrand? @objc dynamic var model: VehicleModel? @@ -57,6 +69,7 @@ class Vehicle: Object, Decodable, IdentifiableType { @objc dynamic var addedDate: TimeInterval = 0 @objc dynamic var addedBy: String = "" let photos = List() + let ownershipPeriods = List() var identity: String { number } @@ -77,6 +90,7 @@ class Vehicle: Object, Decodable, IdentifiableType { case addedDate case addedBy case photos + case ownershipPeriods } required init(from decoder: Decoder) throws { @@ -100,6 +114,10 @@ class Vehicle: Object, Decodable, IdentifiableType { if let photosArray = try container.decodeIfPresent([VehiclePhoto].self, forKey: .photos) { self.photos.append(objectsIn: photosArray) } + + if let ownersipsArray = try container.decodeIfPresent([VehicleOwnershipPeriod].self, forKey: .ownershipPeriods) { + self.ownershipPeriods.append(objectsIn: ownersipsArray) + } } required init() { diff --git a/AutoCat/ThirdParty/Api.swift b/AutoCat/ThirdParty/Api.swift index 078bf3d..5a7ded9 100644 --- a/AutoCat/ThirdParty/Api.swift +++ b/AutoCat/ThirdParty/Api.swift @@ -7,7 +7,7 @@ class Api { } private static func createRequest(api: String, method: String, body: [String: T]? = nil) -> URLRequest? where T: LosslessStringConvertible { - guard var urlComponents = URLComponents(string: Constants.debugBaseUrl + api) else { return nil } + guard var urlComponents = URLComponents(string: Constants.baseUrl + api) else { return nil } if let body = body, method.uppercased() == "GET" { urlComponents.queryItems = body.map { URLQueryItem(name: $0, value: String($1)) }