Switching from CoreData to Realm
This commit is contained in:
parent
21d396b311
commit
18f1a00d82
@ -49,6 +49,9 @@
|
|||||||
7A36E56027FB5A2F0025AACB /* MockURLProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A558AAE27FA3CCF001A18EE /* MockURLProtocol.swift */; };
|
7A36E56027FB5A2F0025AACB /* MockURLProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A558AAE27FA3CCF001A18EE /* MockURLProtocol.swift */; };
|
||||||
7A36E56127FB5A330025AACB /* ApiMethodMockProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A558AAF27FA3CCF001A18EE /* ApiMethodMockProtocol.swift */; };
|
7A36E56127FB5A330025AACB /* ApiMethodMockProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A558AAF27FA3CCF001A18EE /* ApiMethodMockProtocol.swift */; };
|
||||||
7A36E56327FB5BEB0025AACB /* TestError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A36E56227FB5BEB0025AACB /* TestError.swift */; };
|
7A36E56327FB5BEB0025AACB /* TestError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A36E56227FB5BEB0025AACB /* TestError.swift */; };
|
||||||
|
7A39D0772998F25600A6F6FC /* PlaceholderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A39D0762998F25600A6F6FC /* PlaceholderView.swift */; };
|
||||||
|
7A39D07A2998FF3500A6F6FC /* RealmDecoding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A39D0792998FF3500A6F6FC /* RealmDecoding.swift */; };
|
||||||
|
7A39D07D299904B700A6F6FC /* SidebarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A39D07C299904B700A6F6FC /* SidebarView.swift */; };
|
||||||
7A48B26727D9442A004D1A4B /* PKHUD in Frameworks */ = {isa = PBXBuildFile; productRef = 7A48B26627D9442A004D1A4B /* PKHUD */; };
|
7A48B26727D9442A004D1A4B /* PKHUD in Frameworks */ = {isa = PBXBuildFile; productRef = 7A48B26627D9442A004D1A4B /* PKHUD */; };
|
||||||
7A4951B7288D3A6100C644B6 /* AutoCat2SUIApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A4951B6288D3A6100C644B6 /* AutoCat2SUIApp.swift */; };
|
7A4951B7288D3A6100C644B6 /* AutoCat2SUIApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A4951B6288D3A6100C644B6 /* AutoCat2SUIApp.swift */; };
|
||||||
7A4951B9288D3A6100C644B6 /* RootView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A4951B8288D3A6100C644B6 /* RootView.swift */; };
|
7A4951B9288D3A6100C644B6 /* RootView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A4951B8288D3A6100C644B6 /* RootView.swift */; };
|
||||||
@ -87,9 +90,10 @@
|
|||||||
7A49F51027D406CB00AEAAE0 /* MainSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A49F50927D406CB00AEAAE0 /* MainSettings.swift */; };
|
7A49F51027D406CB00AEAAE0 /* MainSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A49F50927D406CB00AEAAE0 /* MainSettings.swift */; };
|
||||||
7A49F51127D406CB00AEAAE0 /* PlateNumber.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A49F50A27D406CB00AEAAE0 /* PlateNumber.swift */; };
|
7A49F51127D406CB00AEAAE0 /* PlateNumber.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A49F50A27D406CB00AEAAE0 /* PlateNumber.swift */; };
|
||||||
7A49F51227D406CB00AEAAE0 /* VName.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A49F50B27D406CB00AEAAE0 /* VName.swift */; };
|
7A49F51227D406CB00AEAAE0 /* VName.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A49F50B27D406CB00AEAAE0 /* VName.swift */; };
|
||||||
7A49F51527D40C6100AEAAE0 /* AutoCat2.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 7A49F51327D40C6100AEAAE0 /* AutoCat2.xcdatamodeld */; };
|
|
||||||
7A558AB027FA3CCF001A18EE /* SettingsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A558AA527FA3CCF001A18EE /* SettingsTests.swift */; };
|
7A558AB027FA3CCF001A18EE /* SettingsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A558AA527FA3CCF001A18EE /* SettingsTests.swift */; };
|
||||||
7A558AB127FA3CCF001A18EE /* ApiTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A558AA627FA3CCF001A18EE /* ApiTests.swift */; };
|
7A558AB127FA3CCF001A18EE /* ApiTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A558AA627FA3CCF001A18EE /* ApiTests.swift */; };
|
||||||
|
7A91E8112986DE9C0008A982 /* Realm in Frameworks */ = {isa = PBXBuildFile; productRef = 7A91E8102986DE9C0008A982 /* Realm */; };
|
||||||
|
7A91E8132986DE9C0008A982 /* RealmSwift in Frameworks */ = {isa = PBXBuildFile; productRef = 7A91E8122986DE9C0008A982 /* RealmSwift */; };
|
||||||
7A9471BD28C52DD80054CB0A /* PlateViewItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A9471BC28C52DD80054CB0A /* PlateViewItem.swift */; };
|
7A9471BD28C52DD80054CB0A /* PlateViewItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A9471BC28C52DD80054CB0A /* PlateViewItem.swift */; };
|
||||||
7A9F2AC327E71531006492A9 /* ACTabBarController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A9F2AC227E71531006492A9 /* ACTabBarController.swift */; };
|
7A9F2AC327E71531006492A9 /* ACTabBarController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A9F2AC227E71531006492A9 /* ACTabBarController.swift */; };
|
||||||
7A9FD4072857AF590057ECFA /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A9FD4062857AF590057ECFA /* AppDelegate.swift */; };
|
7A9FD4072857AF590057ECFA /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A9FD4062857AF590057ECFA /* AppDelegate.swift */; };
|
||||||
@ -246,6 +250,9 @@
|
|||||||
7A2B6CD527FCEC8600519F1E /* XCUIApplication.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XCUIApplication.swift; sourceTree = "<group>"; };
|
7A2B6CD527FCEC8600519F1E /* XCUIApplication.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XCUIApplication.swift; sourceTree = "<group>"; };
|
||||||
7A36E55B27FB55570025AACB /* Testing.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Testing.swift; sourceTree = "<group>"; };
|
7A36E55B27FB55570025AACB /* Testing.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Testing.swift; sourceTree = "<group>"; };
|
||||||
7A36E56227FB5BEB0025AACB /* TestError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestError.swift; sourceTree = "<group>"; };
|
7A36E56227FB5BEB0025AACB /* TestError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestError.swift; sourceTree = "<group>"; };
|
||||||
|
7A39D0762998F25600A6F6FC /* PlaceholderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlaceholderView.swift; sourceTree = "<group>"; };
|
||||||
|
7A39D0792998FF3500A6F6FC /* RealmDecoding.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RealmDecoding.swift; sourceTree = "<group>"; };
|
||||||
|
7A39D07C299904B700A6F6FC /* SidebarView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SidebarView.swift; sourceTree = "<group>"; };
|
||||||
7A4951B4288D3A6100C644B6 /* AutoCat2SUI.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = AutoCat2SUI.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
7A4951B4288D3A6100C644B6 /* AutoCat2SUI.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = AutoCat2SUI.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
7A4951B6288D3A6100C644B6 /* AutoCat2SUIApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AutoCat2SUIApp.swift; sourceTree = "<group>"; };
|
7A4951B6288D3A6100C644B6 /* AutoCat2SUIApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AutoCat2SUIApp.swift; sourceTree = "<group>"; };
|
||||||
7A4951B8288D3A6100C644B6 /* RootView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RootView.swift; sourceTree = "<group>"; };
|
7A4951B8288D3A6100C644B6 /* RootView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RootView.swift; sourceTree = "<group>"; };
|
||||||
@ -286,7 +293,6 @@
|
|||||||
7A49F50927D406CB00AEAAE0 /* MainSettings.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MainSettings.swift; sourceTree = "<group>"; };
|
7A49F50927D406CB00AEAAE0 /* MainSettings.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MainSettings.swift; sourceTree = "<group>"; };
|
||||||
7A49F50A27D406CB00AEAAE0 /* PlateNumber.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PlateNumber.swift; sourceTree = "<group>"; };
|
7A49F50A27D406CB00AEAAE0 /* PlateNumber.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PlateNumber.swift; sourceTree = "<group>"; };
|
||||||
7A49F50B27D406CB00AEAAE0 /* VName.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = VName.swift; sourceTree = "<group>"; };
|
7A49F50B27D406CB00AEAAE0 /* VName.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = VName.swift; sourceTree = "<group>"; };
|
||||||
7A49F51427D40C6100AEAAE0 /* Shared.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = Shared.xcdatamodel; sourceTree = "<group>"; };
|
|
||||||
7A558AA527FA3CCF001A18EE /* SettingsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SettingsTests.swift; sourceTree = "<group>"; };
|
7A558AA527FA3CCF001A18EE /* SettingsTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SettingsTests.swift; sourceTree = "<group>"; };
|
||||||
7A558AA627FA3CCF001A18EE /* ApiTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ApiTests.swift; sourceTree = "<group>"; };
|
7A558AA627FA3CCF001A18EE /* ApiTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ApiTests.swift; sourceTree = "<group>"; };
|
||||||
7A558AA927FA3CCF001A18EE /* LoginMethodMock.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LoginMethodMock.swift; sourceTree = "<group>"; };
|
7A558AA927FA3CCF001A18EE /* LoginMethodMock.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LoginMethodMock.swift; sourceTree = "<group>"; };
|
||||||
@ -367,6 +373,8 @@
|
|||||||
isa = PBXFrameworksBuildPhase;
|
isa = PBXFrameworksBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
|
7A91E8132986DE9C0008A982 /* RealmSwift in Frameworks */,
|
||||||
|
7A91E8112986DE9C0008A982 /* Realm in Frameworks */,
|
||||||
7A1D80E627F20FCB007BD64F /* DifferenceKit in Frameworks */,
|
7A1D80E627F20FCB007BD64F /* DifferenceKit in Frameworks */,
|
||||||
7AE32D6E27F06D2D004EF6E0 /* SwiftDate in Frameworks */,
|
7AE32D6E27F06D2D004EF6E0 /* SwiftDate in Frameworks */,
|
||||||
);
|
);
|
||||||
@ -523,6 +531,22 @@
|
|||||||
path = Testing;
|
path = Testing;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
7A39D0782998FF1800A6F6FC /* Extensions */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
7A39D0792998FF3500A6F6FC /* RealmDecoding.swift */,
|
||||||
|
);
|
||||||
|
path = Extensions;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
7A39D07B2999049F00A6F6FC /* Sidebar */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
7A39D07C299904B700A6F6FC /* SidebarView.swift */,
|
||||||
|
);
|
||||||
|
path = Sidebar;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
7A4951B5288D3A6100C644B6 /* AutoCat2SUI */ = {
|
7A4951B5288D3A6100C644B6 /* AutoCat2SUI */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
@ -550,6 +574,7 @@
|
|||||||
7A4951C3288D3AF000C644B6 /* Screens */ = {
|
7A4951C3288D3AF000C644B6 /* Screens */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
7A39D07B2999049F00A6F6FC /* Sidebar */,
|
||||||
7AE9F20228CDFCAB00ABF6DF /* VehicleDetail */,
|
7AE9F20228CDFCAB00ABF6DF /* VehicleDetail */,
|
||||||
7A163BEF28BBE9DA0005A0A4 /* VehiclesList */,
|
7A163BEF28BBE9DA0005A0A4 /* VehiclesList */,
|
||||||
7AF1D0D628BB5768004E19F7 /* CheckNumber */,
|
7AF1D0D628BB5768004E19F7 /* CheckNumber */,
|
||||||
@ -582,6 +607,7 @@
|
|||||||
7A054FD728C4BB700002C386 /* PlateView */,
|
7A054FD728C4BB700002C386 /* PlateView */,
|
||||||
7A4951B8288D3A6100C644B6 /* RootView.swift */,
|
7A4951B8288D3A6100C644B6 /* RootView.swift */,
|
||||||
7A4951D0288D5C4300C644B6 /* ACProgressView.swift */,
|
7A4951D0288D5C4300C644B6 /* ACProgressView.swift */,
|
||||||
|
7A39D0762998F25600A6F6FC /* PlaceholderView.swift */,
|
||||||
);
|
);
|
||||||
path = Views;
|
path = Views;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -663,9 +689,9 @@
|
|||||||
7A49F4D827D4064500AEAAE0 /* AutoCatCore */ = {
|
7A49F4D827D4064500AEAAE0 /* AutoCatCore */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
7A39D0782998FF1800A6F6FC /* Extensions */,
|
||||||
7A36E55A27FB54610025AACB /* Testing */,
|
7A36E55A27FB54610025AACB /* Testing */,
|
||||||
7AE32D6F27F06D87004EF6E0 /* DataSource */,
|
7AE32D6F27F06D87004EF6E0 /* DataSource */,
|
||||||
7A49F51327D40C6100AEAAE0 /* AutoCat2.xcdatamodeld */,
|
|
||||||
7A49F50427D406CB00AEAAE0 /* Models */,
|
7A49F50427D406CB00AEAAE0 /* Models */,
|
||||||
7A49F4FF27D406C300AEAAE0 /* Services */,
|
7A49F4FF27D406C300AEAAE0 /* Services */,
|
||||||
7A49F4FC27D406BA00AEAAE0 /* ThirdParty */,
|
7A49F4FC27D406BA00AEAAE0 /* ThirdParty */,
|
||||||
@ -973,6 +999,8 @@
|
|||||||
packageProductDependencies = (
|
packageProductDependencies = (
|
||||||
7AE32D6D27F06D2D004EF6E0 /* SwiftDate */,
|
7AE32D6D27F06D2D004EF6E0 /* SwiftDate */,
|
||||||
7A1D80E527F20FCB007BD64F /* DifferenceKit */,
|
7A1D80E527F20FCB007BD64F /* DifferenceKit */,
|
||||||
|
7A91E8102986DE9C0008A982 /* Realm */,
|
||||||
|
7A91E8122986DE9C0008A982 /* RealmSwift */,
|
||||||
);
|
);
|
||||||
productName = AutoCatCore;
|
productName = AutoCatCore;
|
||||||
productReference = 7A49F4D727D4064500AEAAE0 /* AutoCatCore.framework */;
|
productReference = 7A49F4D727D4064500AEAAE0 /* AutoCatCore.framework */;
|
||||||
@ -1070,6 +1098,7 @@
|
|||||||
7AE32D6C27F06D2D004EF6E0 /* XCRemoteSwiftPackageReference "SwiftDate" */,
|
7AE32D6C27F06D2D004EF6E0 /* XCRemoteSwiftPackageReference "SwiftDate" */,
|
||||||
7A1D80DE27F1F275007BD64F /* XCRemoteSwiftPackageReference "DifferenceKit" */,
|
7A1D80DE27F1F275007BD64F /* XCRemoteSwiftPackageReference "DifferenceKit" */,
|
||||||
7A1D80E427F20FCB007BD64F /* XCRemoteSwiftPackageReference "DifferenceKit" */,
|
7A1D80E427F20FCB007BD64F /* XCRemoteSwiftPackageReference "DifferenceKit" */,
|
||||||
|
7A91E80F2986DE9C0008A982 /* XCRemoteSwiftPackageReference "realm-swift" */,
|
||||||
);
|
);
|
||||||
productRefGroup = 7A49F4A027D4061900AEAAE0 /* Products */;
|
productRefGroup = 7A49F4A027D4061900AEAAE0 /* Products */;
|
||||||
projectDirPath = "";
|
projectDirPath = "";
|
||||||
@ -1157,6 +1186,7 @@
|
|||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
7A4951D3288D5E2800C644B6 /* AuthVM.swift in Sources */,
|
7A4951D3288D5E2800C644B6 /* AuthVM.swift in Sources */,
|
||||||
|
7A39D07D299904B700A6F6FC /* SidebarView.swift in Sources */,
|
||||||
7A054FDA28C4C24B0002C386 /* CenterTextLayer.swift in Sources */,
|
7A054FDA28C4C24B0002C386 /* CenterTextLayer.swift in Sources */,
|
||||||
7A163BF128BBE9ED0005A0A4 /* VehiclesListView.swift in Sources */,
|
7A163BF128BBE9ED0005A0A4 /* VehiclesListView.swift in Sources */,
|
||||||
7A054FD928C4BE560002C386 /* PlateView.swift in Sources */,
|
7A054FD928C4BE560002C386 /* PlateView.swift in Sources */,
|
||||||
@ -1164,6 +1194,7 @@
|
|||||||
7A4951C7288D3BDD00C644B6 /* MainView.swift in Sources */,
|
7A4951C7288D3BDD00C644B6 /* MainView.swift in Sources */,
|
||||||
7AE9F20428CDFCC600ABF6DF /* VehicleDetailView.swift in Sources */,
|
7AE9F20428CDFCC600ABF6DF /* VehicleDetailView.swift in Sources */,
|
||||||
7AF1D0D828BB577E004E19F7 /* CheckNumber.swift in Sources */,
|
7AF1D0D828BB577E004E19F7 /* CheckNumber.swift in Sources */,
|
||||||
|
7A39D0772998F25600A6F6FC /* PlaceholderView.swift in Sources */,
|
||||||
7A4951B7288D3A6100C644B6 /* AutoCat2SUIApp.swift in Sources */,
|
7A4951B7288D3A6100C644B6 /* AutoCat2SUIApp.swift in Sources */,
|
||||||
7A9471BD28C52DD80054CB0A /* PlateViewItem.swift in Sources */,
|
7A9471BD28C52DD80054CB0A /* PlateViewItem.swift in Sources */,
|
||||||
7AF1D0DA28BB5BF5004E19F7 /* View.swift in Sources */,
|
7AF1D0DA28BB5BF5004E19F7 /* View.swift in Sources */,
|
||||||
@ -1253,9 +1284,9 @@
|
|||||||
7A49F50F27D406CB00AEAAE0 /* Response.swift in Sources */,
|
7A49F50F27D406CB00AEAAE0 /* Response.swift in Sources */,
|
||||||
929EDE8127F8A75E00E55F65 /* VPhoto.swift in Sources */,
|
929EDE8127F8A75E00E55F65 /* VPhoto.swift in Sources */,
|
||||||
7A49F4FB27D406B200AEAAE0 /* Api.swift in Sources */,
|
7A49F4FB27D406B200AEAAE0 /* Api.swift in Sources */,
|
||||||
7A49F51527D40C6100AEAAE0 /* AutoCat2.xcdatamodeld in Sources */,
|
|
||||||
929EDE7F27F89C3000E55F65 /* VEngine.swift in Sources */,
|
929EDE7F27F89C3000E55F65 /* VEngine.swift in Sources */,
|
||||||
929EDE8727F8E11E00E55F65 /* VOsago.swift in Sources */,
|
929EDE8727F8E11E00E55F65 /* VOsago.swift in Sources */,
|
||||||
|
7A39D07A2998FF3500A6F6FC /* RealmDecoding.swift in Sources */,
|
||||||
7A2B6CD427FCE93C00519F1E /* TestSettings.swift in Sources */,
|
7A2B6CD427FCE93C00519F1E /* TestSettings.swift in Sources */,
|
||||||
7A49F50E27D406CB00AEAAE0 /* User.swift in Sources */,
|
7A49F50E27D406CB00AEAAE0 /* User.swift in Sources */,
|
||||||
7A36E56127FB5A330025AACB /* ApiMethodMockProtocol.swift in Sources */,
|
7A36E56127FB5A330025AACB /* ApiMethodMockProtocol.swift in Sources */,
|
||||||
@ -1974,6 +2005,14 @@
|
|||||||
minimumVersion = 5.0.0;
|
minimumVersion = 5.0.0;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
7A91E80F2986DE9C0008A982 /* XCRemoteSwiftPackageReference "realm-swift" */ = {
|
||||||
|
isa = XCRemoteSwiftPackageReference;
|
||||||
|
repositoryURL = "https://github.com/realm/realm-swift.git";
|
||||||
|
requirement = {
|
||||||
|
branch = master;
|
||||||
|
kind = branch;
|
||||||
|
};
|
||||||
|
};
|
||||||
7AE32D6C27F06D2D004EF6E0 /* XCRemoteSwiftPackageReference "SwiftDate" */ = {
|
7AE32D6C27F06D2D004EF6E0 /* XCRemoteSwiftPackageReference "SwiftDate" */ = {
|
||||||
isa = XCRemoteSwiftPackageReference;
|
isa = XCRemoteSwiftPackageReference;
|
||||||
repositoryURL = "https://github.com/malcommac/SwiftDate";
|
repositoryURL = "https://github.com/malcommac/SwiftDate";
|
||||||
@ -2005,6 +2044,16 @@
|
|||||||
package = 7A48B26527D9442A004D1A4B /* XCRemoteSwiftPackageReference "PKHUD" */;
|
package = 7A48B26527D9442A004D1A4B /* XCRemoteSwiftPackageReference "PKHUD" */;
|
||||||
productName = PKHUD;
|
productName = PKHUD;
|
||||||
};
|
};
|
||||||
|
7A91E8102986DE9C0008A982 /* Realm */ = {
|
||||||
|
isa = XCSwiftPackageProductDependency;
|
||||||
|
package = 7A91E80F2986DE9C0008A982 /* XCRemoteSwiftPackageReference "realm-swift" */;
|
||||||
|
productName = Realm;
|
||||||
|
};
|
||||||
|
7A91E8122986DE9C0008A982 /* RealmSwift */ = {
|
||||||
|
isa = XCSwiftPackageProductDependency;
|
||||||
|
package = 7A91E80F2986DE9C0008A982 /* XCRemoteSwiftPackageReference "realm-swift" */;
|
||||||
|
productName = RealmSwift;
|
||||||
|
};
|
||||||
7A9FD4192857AF8D0057ECFA /* DifferenceKit */ = {
|
7A9FD4192857AF8D0057ECFA /* DifferenceKit */ = {
|
||||||
isa = XCSwiftPackageProductDependency;
|
isa = XCSwiftPackageProductDependency;
|
||||||
package = 7A1D80DE27F1F275007BD64F /* XCRemoteSwiftPackageReference "DifferenceKit" */;
|
package = 7A1D80DE27F1F275007BD64F /* XCRemoteSwiftPackageReference "DifferenceKit" */;
|
||||||
@ -2016,19 +2065,6 @@
|
|||||||
productName = SwiftDate;
|
productName = SwiftDate;
|
||||||
};
|
};
|
||||||
/* End XCSwiftPackageProductDependency section */
|
/* End XCSwiftPackageProductDependency section */
|
||||||
|
|
||||||
/* Begin XCVersionGroup section */
|
|
||||||
7A49F51327D40C6100AEAAE0 /* AutoCat2.xcdatamodeld */ = {
|
|
||||||
isa = XCVersionGroup;
|
|
||||||
children = (
|
|
||||||
7A49F51427D40C6100AEAAE0 /* Shared.xcdatamodel */,
|
|
||||||
);
|
|
||||||
currentVersion = 7A49F51427D40C6100AEAAE0 /* Shared.xcdatamodel */;
|
|
||||||
path = AutoCat2.xcdatamodeld;
|
|
||||||
sourceTree = "<group>";
|
|
||||||
versionGroupType = wrapper.xcdatamodel;
|
|
||||||
};
|
|
||||||
/* End XCVersionGroup section */
|
|
||||||
};
|
};
|
||||||
rootObject = 7A49F49727D4061900AEAAE0 /* Project object */;
|
rootObject = 7A49F49727D4061900AEAAE0 /* Project object */;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -18,6 +18,24 @@
|
|||||||
"version" : "5.4.0"
|
"version" : "5.4.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"identity" : "realm-core",
|
||||||
|
"kind" : "remoteSourceControl",
|
||||||
|
"location" : "https://github.com/realm/realm-core.git",
|
||||||
|
"state" : {
|
||||||
|
"revision" : "b77443ca7fa25407869ca537bf3ae912b1427bff",
|
||||||
|
"version" : "12.13.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"identity" : "realm-swift",
|
||||||
|
"kind" : "remoteSourceControl",
|
||||||
|
"location" : "https://github.com/realm/realm-swift.git",
|
||||||
|
"state" : {
|
||||||
|
"branch" : "master",
|
||||||
|
"revision" : "f5aaf456ea725ac2f352b0b3decc78a7094adbd8"
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"identity" : "swiftdate",
|
"identity" : "swiftdate",
|
||||||
"kind" : "remoteSourceControl",
|
"kind" : "remoteSourceControl",
|
||||||
|
|||||||
@ -12,17 +12,17 @@
|
|||||||
<key>AutoCat2.xcscheme_^#shared#^_</key>
|
<key>AutoCat2.xcscheme_^#shared#^_</key>
|
||||||
<dict>
|
<dict>
|
||||||
<key>orderHint</key>
|
<key>orderHint</key>
|
||||||
<integer>0</integer>
|
<integer>2</integer>
|
||||||
</dict>
|
</dict>
|
||||||
<key>AutoCat2Mac.xcscheme_^#shared#^_</key>
|
<key>AutoCat2Mac.xcscheme_^#shared#^_</key>
|
||||||
<dict>
|
<dict>
|
||||||
<key>orderHint</key>
|
<key>orderHint</key>
|
||||||
<integer>2</integer>
|
<integer>3</integer>
|
||||||
</dict>
|
</dict>
|
||||||
<key>AutoCat2SUI.xcscheme_^#shared#^_</key>
|
<key>AutoCat2SUI.xcscheme_^#shared#^_</key>
|
||||||
<dict>
|
<dict>
|
||||||
<key>orderHint</key>
|
<key>orderHint</key>
|
||||||
<integer>1</integer>
|
<integer>0</integer>
|
||||||
</dict>
|
</dict>
|
||||||
<key>AutoCat2UITests.testExample.xcscheme</key>
|
<key>AutoCat2UITests.testExample.xcscheme</key>
|
||||||
<dict>
|
<dict>
|
||||||
@ -41,14 +41,14 @@
|
|||||||
<key>isShown</key>
|
<key>isShown</key>
|
||||||
<false/>
|
<false/>
|
||||||
<key>orderHint</key>
|
<key>orderHint</key>
|
||||||
<integer>3</integer>
|
<integer>8</integer>
|
||||||
</dict>
|
</dict>
|
||||||
<key>DifferenceKit (Playground) 2.xcscheme</key>
|
<key>DifferenceKit (Playground) 2.xcscheme</key>
|
||||||
<dict>
|
<dict>
|
||||||
<key>isShown</key>
|
<key>isShown</key>
|
||||||
<false/>
|
<false/>
|
||||||
<key>orderHint</key>
|
<key>orderHint</key>
|
||||||
<integer>4</integer>
|
<integer>9</integer>
|
||||||
</dict>
|
</dict>
|
||||||
<key>DifferenceKit (Playground) 3.xcscheme</key>
|
<key>DifferenceKit (Playground) 3.xcscheme</key>
|
||||||
<dict>
|
<dict>
|
||||||
@ -76,21 +76,42 @@
|
|||||||
<key>isShown</key>
|
<key>isShown</key>
|
||||||
<false/>
|
<false/>
|
||||||
<key>orderHint</key>
|
<key>orderHint</key>
|
||||||
<integer>2</integer>
|
<integer>7</integer>
|
||||||
|
</dict>
|
||||||
|
<key>GettingStarted (Playground) 1.xcscheme</key>
|
||||||
|
<dict>
|
||||||
|
<key>isShown</key>
|
||||||
|
<false/>
|
||||||
|
<key>orderHint</key>
|
||||||
|
<integer>10</integer>
|
||||||
|
</dict>
|
||||||
|
<key>GettingStarted (Playground) 2.xcscheme</key>
|
||||||
|
<dict>
|
||||||
|
<key>isShown</key>
|
||||||
|
<false/>
|
||||||
|
<key>orderHint</key>
|
||||||
|
<integer>11</integer>
|
||||||
|
</dict>
|
||||||
|
<key>GettingStarted (Playground).xcscheme</key>
|
||||||
|
<dict>
|
||||||
|
<key>isShown</key>
|
||||||
|
<false/>
|
||||||
|
<key>orderHint</key>
|
||||||
|
<integer>3</integer>
|
||||||
</dict>
|
</dict>
|
||||||
<key>SwiftDate (Playground) 1.xcscheme</key>
|
<key>SwiftDate (Playground) 1.xcscheme</key>
|
||||||
<dict>
|
<dict>
|
||||||
<key>isShown</key>
|
<key>isShown</key>
|
||||||
<false/>
|
<false/>
|
||||||
<key>orderHint</key>
|
<key>orderHint</key>
|
||||||
<integer>6</integer>
|
<integer>5</integer>
|
||||||
</dict>
|
</dict>
|
||||||
<key>SwiftDate (Playground) 2.xcscheme</key>
|
<key>SwiftDate (Playground) 2.xcscheme</key>
|
||||||
<dict>
|
<dict>
|
||||||
<key>isShown</key>
|
<key>isShown</key>
|
||||||
<false/>
|
<false/>
|
||||||
<key>orderHint</key>
|
<key>orderHint</key>
|
||||||
<integer>7</integer>
|
<integer>6</integer>
|
||||||
</dict>
|
</dict>
|
||||||
<key>SwiftDate (Playground) 3.xcscheme</key>
|
<key>SwiftDate (Playground) 3.xcscheme</key>
|
||||||
<dict>
|
<dict>
|
||||||
@ -118,11 +139,16 @@
|
|||||||
<key>isShown</key>
|
<key>isShown</key>
|
||||||
<false/>
|
<false/>
|
||||||
<key>orderHint</key>
|
<key>orderHint</key>
|
||||||
<integer>5</integer>
|
<integer>4</integer>
|
||||||
</dict>
|
</dict>
|
||||||
</dict>
|
</dict>
|
||||||
<key>SuppressBuildableAutocreation</key>
|
<key>SuppressBuildableAutocreation</key>
|
||||||
<dict>
|
<dict>
|
||||||
|
<key>7A4951B3288D3A6100C644B6</key>
|
||||||
|
<dict>
|
||||||
|
<key>primary</key>
|
||||||
|
<true/>
|
||||||
|
</dict>
|
||||||
<key>7A49F4D627D4064500AEAAE0</key>
|
<key>7A49F4D627D4064500AEAAE0</key>
|
||||||
<dict>
|
<dict>
|
||||||
<key>primary</key>
|
<key>primary</key>
|
||||||
|
|||||||
@ -86,12 +86,8 @@ class VehicleCell: UITableViewCell {
|
|||||||
|
|
||||||
extension VehicleCell: ConfigurableCell {
|
extension VehicleCell: ConfigurableCell {
|
||||||
|
|
||||||
func configure(with vehicle: CDVehicle) {
|
func configure(with vehicle: Vehicle) {
|
||||||
guard let number = vehicle.number else {
|
plateView.number = PlateNumber(vehicle.number)
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
plateView.number = PlateNumber(number)
|
|
||||||
nameLabel.text = vehicle.brand?.name?.original ?? "<Unknown>"
|
nameLabel.text = vehicle.brand?.name?.original ?? "<Unknown>"
|
||||||
|
|
||||||
if vehicle.unrecognized {
|
if vehicle.unrecognized {
|
||||||
|
|||||||
@ -18,7 +18,7 @@ class HistoryController: UIViewController, UITableViewDelegate {
|
|||||||
return table
|
return table
|
||||||
}()
|
}()
|
||||||
|
|
||||||
private var dataSource: CoreDataSource<CDVehicle, VehicleCell>?
|
private var dataSource: CoreDataSource<Vehicle, VehicleCell>?
|
||||||
|
|
||||||
override func viewDidLoad() {
|
override func viewDidLoad() {
|
||||||
super.viewDidLoad()
|
super.viewDidLoad()
|
||||||
|
|||||||
@ -14,16 +14,12 @@ struct AutoCat2SUIApp: App {
|
|||||||
|
|
||||||
@NSApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
|
@NSApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
|
||||||
|
|
||||||
let storageService = StorageService.sharedNotWait
|
|
||||||
|
|
||||||
var body: some Scene {
|
var body: some Scene {
|
||||||
WindowGroup {
|
WindowGroup {
|
||||||
if Testing.isUITesting {
|
if Testing.isUITesting {
|
||||||
RootView(settings: getTestSettings())
|
RootView(settings: getTestSettings())
|
||||||
.environment(\.managedObjectContext, storageService.context)
|
|
||||||
} else {
|
} else {
|
||||||
RootView(settings: getSettings())
|
RootView(settings: getSettings())
|
||||||
.environment(\.managedObjectContext, storageService.context)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -29,7 +29,7 @@ struct CheckNumber: View {
|
|||||||
}
|
}
|
||||||
.disabled(showProgress)
|
.disabled(showProgress)
|
||||||
Button("Check") {
|
Button("Check") {
|
||||||
Task.init {
|
Task { @MainActor in
|
||||||
showProgress = true
|
showProgress = true
|
||||||
do {
|
do {
|
||||||
try await VehicleService.shared.check(plateNumber: plateNumber.uppercased(), force: false)
|
try await VehicleService.shared.check(plateNumber: plateNumber.uppercased(), force: false)
|
||||||
|
|||||||
@ -7,125 +7,33 @@
|
|||||||
|
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
import AutoCatCore
|
import AutoCatCore
|
||||||
|
import RealmSwift
|
||||||
struct SidebarSection: Identifiable {
|
|
||||||
|
|
||||||
let name: String
|
|
||||||
let filters: [Filter]
|
|
||||||
let id = UUID()
|
|
||||||
|
|
||||||
func contains(filter id: UUID) -> Bool {
|
|
||||||
filters.contains { $0.id == id }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct MainView: View {
|
struct MainView: View {
|
||||||
|
|
||||||
@FetchRequest(entity: CDVehicle.entity(), sortDescriptors: []) var vehicles: FetchedResults<CDVehicle>
|
|
||||||
|
|
||||||
@State private var selectedFilterId: UUID?
|
|
||||||
@State var selectedVehicle: CDVehicle?
|
|
||||||
@State private var checkSheetPresented = false
|
|
||||||
@State private var searchText = ""
|
@State private var searchText = ""
|
||||||
|
|
||||||
@State var columnVisibility = NavigationSplitViewVisibility.all
|
@State var columnVisibility = NavigationSplitViewVisibility.all
|
||||||
|
@State var selectedFilter: Filter?
|
||||||
private let sections: [SidebarSection] = [
|
@State var selectedVehicle: Vehicle?
|
||||||
SidebarSection(name: "History", filters: [
|
|
||||||
.allLocal,
|
|
||||||
.unrecognized,
|
|
||||||
.outdated
|
|
||||||
]),
|
|
||||||
SidebarSection(name: "Remote", filters: [
|
|
||||||
.allRemote
|
|
||||||
])
|
|
||||||
]
|
|
||||||
|
|
||||||
var selectedFilter: Filter? {
|
|
||||||
guard let filterId = selectedFilterId else {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return sections.first(where: { $0.contains(filter: filterId) })?
|
|
||||||
.filters.first(where: { $0.id == filterId })
|
|
||||||
}
|
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
NavigationSplitView(columnVisibility: $columnVisibility) {
|
NavigationSplitView(columnVisibility: $columnVisibility) {
|
||||||
List(selection: $selectedFilterId) {
|
SidebarView(selectedFilter: $selectedFilter)
|
||||||
ForEach(sections) { section in
|
|
||||||
Section(section.name) {
|
|
||||||
ForEach(section.filters) { filter in
|
|
||||||
Label(filter.name, systemImage: filter.iconName)
|
|
||||||
.badge(vehicles.filter(filter.match).count)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.navigationSplitViewColumnWidth(180)
|
|
||||||
.toolbar {
|
|
||||||
ToolbarItemGroup(placement: .primaryAction) {
|
|
||||||
Spacer()
|
|
||||||
Button {
|
|
||||||
checkSheetPresented = true
|
|
||||||
} label: {
|
|
||||||
Image(systemName: "plus")
|
|
||||||
}
|
|
||||||
.sheet(isPresented: $checkSheetPresented) {
|
|
||||||
CheckNumber()
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} content: {
|
} content: {
|
||||||
if let filter = selectedFilter {
|
if let filter = selectedFilter {
|
||||||
let filtered = vehicles.filter(filter.match)
|
VehiclesListView(filter: filter, selection: $selectedVehicle)
|
||||||
if filtered.isEmpty {
|
|
||||||
VStack {
|
|
||||||
Image(systemName: filter.iconName)
|
|
||||||
.resizable()
|
|
||||||
.aspectRatio(contentMode: .fit)
|
|
||||||
.frame(width: 64)
|
|
||||||
.foregroundColor(.secondary)
|
|
||||||
|
|
||||||
Text("Nothing here")
|
|
||||||
.font(.system(size: 18))
|
|
||||||
.foregroundColor(.secondary)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
VehiclesListView(vehicles: filtered, selection: $selectedVehicle)
|
|
||||||
.toolbar {
|
|
||||||
ToolbarItem {
|
|
||||||
Button(action: {}) {
|
|
||||||
Image(systemName: "line.3.horizontal.decrease.circle")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.navigationTitle(filter.name)
|
|
||||||
.navigationSubtitle("\(filtered.count) vehicles")
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
EmptyView()
|
EmptyView()
|
||||||
}
|
}
|
||||||
} detail: {
|
} detail: {
|
||||||
if let vehicle = selectedVehicle {
|
if let vehicle = selectedVehicle {
|
||||||
VehicleDetailView(vehicle: vehicle)
|
VehicleDetailView(vehicle: vehicle)
|
||||||
.toolbar {
|
|
||||||
ToolbarItem(placement: .automatic) {
|
|
||||||
Button(action: {}) {
|
|
||||||
Image(systemName: "square.and.arrow.up")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.navigationTitle(vehicle.brand?.name?.original ?? "")
|
|
||||||
.navigationSubtitle("\(vehicle.year)")
|
|
||||||
.searchable(text: $searchText, placement: .toolbar)
|
.searchable(text: $searchText, placement: .toolbar)
|
||||||
} else {
|
} else {
|
||||||
EmptyView()
|
EmptyView()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.navigationSplitViewStyle(.balanced)
|
.navigationSplitViewStyle(.balanced)
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
74
AutoCat2SUI/Screens/Sidebar/SidebarView.swift
Normal file
74
AutoCat2SUI/Screens/Sidebar/SidebarView.swift
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
//
|
||||||
|
// SidebarView.swift
|
||||||
|
// AutoCat2SUI
|
||||||
|
//
|
||||||
|
// Created by Selim Mustafaev on 12.02.2023.
|
||||||
|
//
|
||||||
|
|
||||||
|
import SwiftUI
|
||||||
|
import AutoCatCore
|
||||||
|
import RealmSwift
|
||||||
|
|
||||||
|
struct SidebarSection: Identifiable {
|
||||||
|
|
||||||
|
let name: String
|
||||||
|
let filters: [Filter]
|
||||||
|
let id = UUID()
|
||||||
|
|
||||||
|
func contains(filter id: UUID) -> Bool {
|
||||||
|
filters.contains { $0.id == id }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct SidebarView: View {
|
||||||
|
|
||||||
|
@ObservedResults(Vehicle.self) var vehicles
|
||||||
|
|
||||||
|
@Binding var selectedFilter: Filter?
|
||||||
|
@State private var checkSheetPresented = false
|
||||||
|
|
||||||
|
private let sections: [SidebarSection] = [
|
||||||
|
SidebarSection(name: "History", filters: [
|
||||||
|
.allLocal,
|
||||||
|
.unrecognized,
|
||||||
|
.outdated
|
||||||
|
]),
|
||||||
|
SidebarSection(name: "Remote", filters: [
|
||||||
|
.allRemote
|
||||||
|
])
|
||||||
|
]
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
List(selection: $selectedFilter) {
|
||||||
|
ForEach(sections) { section in
|
||||||
|
Section(section.name) {
|
||||||
|
ForEach(section.filters, id: \.self) { filter in
|
||||||
|
Label(filter.name, systemImage: filter.iconName)
|
||||||
|
.badge(vehicles.filter(filter.match).count)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.navigationSplitViewColumnWidth(180)
|
||||||
|
.toolbar {
|
||||||
|
ToolbarItemGroup(placement: .primaryAction) {
|
||||||
|
Spacer()
|
||||||
|
Button {
|
||||||
|
checkSheetPresented = true
|
||||||
|
} label: {
|
||||||
|
Image(systemName: "plus")
|
||||||
|
}
|
||||||
|
.sheet(isPresented: $checkSheetPresented) {
|
||||||
|
CheckNumber()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct SidebarView_Previews: PreviewProvider {
|
||||||
|
static var previews: some View {
|
||||||
|
SidebarView(selectedFilter: .constant(nil))
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -26,16 +26,16 @@ struct ReportTextItem: View {
|
|||||||
|
|
||||||
struct VehicleDetailView: View {
|
struct VehicleDetailView: View {
|
||||||
|
|
||||||
let vehicle: CDVehicle
|
let vehicle: Vehicle
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
Form {
|
Form {
|
||||||
Section(header: Text("General")) {
|
Section(header: Text("General")) {
|
||||||
ReportTextItem(name: "Year", value: String(vehicle.year))
|
ReportTextItem(name: "Year", value: String(vehicle.year ?? 0))
|
||||||
ReportTextItem(name: "Color", value: vehicle.color)
|
ReportTextItem(name: "Color", value: vehicle.color)
|
||||||
ReportTextItem(name: "Category", value: vehicle.category)
|
ReportTextItem(name: "Category", value: vehicle.category)
|
||||||
ReportTextItem(name: "Steering wheel position", value: vehicle.isRightWheel ? "Right": "Left")
|
ReportTextItem(name: "Steering wheel position", value: vehicle.isRightWheel == true ? "Right": "Left")
|
||||||
ReportTextItem(name: "Japanese", value: vehicle.isJapanese ? "Yes" : "No")
|
ReportTextItem(name: "Japanese", value: vehicle.isJapanese == true ? "Yes" : "No")
|
||||||
}
|
}
|
||||||
Section(header: Text("Identifiers")) {
|
Section(header: Text("Identifiers")) {
|
||||||
ReportTextItem(name: "Plate number", value: vehicle.number)
|
ReportTextItem(name: "Plate number", value: vehicle.number)
|
||||||
@ -52,6 +52,15 @@ struct VehicleDetailView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
.formStyle(.grouped)
|
.formStyle(.grouped)
|
||||||
|
.toolbar {
|
||||||
|
ToolbarItem(placement: .automatic) {
|
||||||
|
Button(action: {}) {
|
||||||
|
Image(systemName: "square.and.arrow.up")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.navigationTitle(vehicle.brand?.name?.original ?? "")
|
||||||
|
.navigationSubtitle("\(vehicle.year ?? 0)")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,7 +73,6 @@ struct VehicleDetailView_Previews: PreviewProvider {
|
|||||||
addedDate: Date().timeIntervalSince1970,
|
addedDate: Date().timeIntervalSince1970,
|
||||||
updatedDate: Date().timeIntervalSince1970)
|
updatedDate: Date().timeIntervalSince1970)
|
||||||
|
|
||||||
return VehicleDetailView(vehicle: CDVehicle(vehicle: test1,
|
return VehicleDetailView(vehicle: test1)
|
||||||
context: NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType)))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,27 +7,43 @@
|
|||||||
|
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
import AutoCatCore
|
import AutoCatCore
|
||||||
|
import RealmSwift
|
||||||
|
|
||||||
struct VehiclesListView: View {
|
struct VehiclesListView: View {
|
||||||
|
|
||||||
var vehicles: [CDVehicle]
|
var filter: Filter
|
||||||
@Binding var selection: CDVehicle?
|
@Binding var selection: Vehicle?
|
||||||
|
|
||||||
|
@ObservedResults(Vehicle.self) var vehicles
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
|
let filtered: [Vehicle] = vehicles.filter(filter.match)
|
||||||
|
if filtered.isEmpty {
|
||||||
|
PlaceholderView(imageName: filter.iconName)
|
||||||
|
} else {
|
||||||
List(selection: $selection) {
|
List(selection: $selection) {
|
||||||
ForEach(vehicles, id: \.self) { vehicle in
|
ForEach(filtered, id: \.self) { vehicle in
|
||||||
PlateViewItem(vehicle: vehicle)
|
PlateViewItem(vehicle: vehicle)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.toolbar {
|
||||||
|
ToolbarItem {
|
||||||
|
Button(action: {}) {
|
||||||
|
Image(systemName: "line.3.horizontal.decrease.circle")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.navigationTitle(filter.name)
|
||||||
|
.navigationSubtitle("\(filtered.count) vehicles")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct VehiclesListView_Previews: PreviewProvider {
|
struct VehiclesListView_Previews: PreviewProvider {
|
||||||
|
|
||||||
@State var selection: CDVehicle?
|
@State var selection: Vehicle?
|
||||||
|
|
||||||
static var previews: some View {
|
static var previews: some View {
|
||||||
VehiclesListView(vehicles: [
|
VehiclesListView(filter: .allLocal, selection: .constant(nil))
|
||||||
], selection: .constant(nil))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
39
AutoCat2SUI/Views/PlaceholderView.swift
Normal file
39
AutoCat2SUI/Views/PlaceholderView.swift
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
//
|
||||||
|
// PlaceholderView.swift
|
||||||
|
// AutoCat2SUI
|
||||||
|
//
|
||||||
|
// Created by Selim Mustafaev on 12.02.2023.
|
||||||
|
//
|
||||||
|
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct PlaceholderView: View {
|
||||||
|
|
||||||
|
let imageName: String
|
||||||
|
let text: String
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
VStack {
|
||||||
|
Image(systemName: imageName)
|
||||||
|
.resizable()
|
||||||
|
.aspectRatio(contentMode: .fit)
|
||||||
|
.frame(width: 64)
|
||||||
|
.foregroundColor(.secondary)
|
||||||
|
|
||||||
|
Text(text)
|
||||||
|
.font(.system(size: 18))
|
||||||
|
.foregroundColor(.secondary)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
init(imageName: String, text: String = "Nothing here") {
|
||||||
|
self.imageName = imageName
|
||||||
|
self.text = text
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct PlaceholderView_Previews: PreviewProvider {
|
||||||
|
static var previews: some View {
|
||||||
|
PlaceholderView(imageName: "eye", text: "Nothing here")
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -10,21 +10,21 @@ import AutoCatCore
|
|||||||
|
|
||||||
struct PlateViewItem: View {
|
struct PlateViewItem: View {
|
||||||
|
|
||||||
let vehicle: CDVehicle
|
let vehicle: Vehicle
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
VStack(alignment: .leading, spacing: 4) {
|
VStack(alignment: .leading, spacing: 4) {
|
||||||
Text(vehicle.brand?.name?.original ?? "")
|
Text(vehicle.brand?.name?.original ?? "")
|
||||||
|
|
||||||
HStack {
|
HStack {
|
||||||
PlateNumberView(number: PlateNumber(vehicle.number ?? ""),
|
PlateNumberView(number: PlateNumber(vehicle.number),
|
||||||
unrecognized: vehicle.unrecognized,
|
unrecognized: vehicle.unrecognized,
|
||||||
outdated: vehicle.outdated,
|
outdated: vehicle.outdated,
|
||||||
fontSize: 30)
|
fontSize: 30)
|
||||||
VStack {
|
VStack {
|
||||||
if let upDate = vehicle.updatedDate {
|
// if let upDate = vehicle.updatedDate {
|
||||||
|
//
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -41,7 +41,6 @@ struct PlateViewItem_Previews: PreviewProvider {
|
|||||||
addedDate: Date().timeIntervalSince1970,
|
addedDate: Date().timeIntervalSince1970,
|
||||||
updatedDate: Date().timeIntervalSince1970)
|
updatedDate: Date().timeIntervalSince1970)
|
||||||
|
|
||||||
return PlateViewItem(vehicle: CDVehicle(vehicle: test1,
|
return PlateViewItem(vehicle: test1)
|
||||||
context: NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType)))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,8 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
<plist version="1.0">
|
<plist version="1.0">
|
||||||
<dict>
|
<dict/>
|
||||||
<key>_XCCurrentVersionName</key>
|
|
||||||
<string>Shared.xcdatamodel</string>
|
|
||||||
</dict>
|
|
||||||
</plist>
|
</plist>
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||||
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="19574" systemVersion="20G80" minimumToolsVersion="Automatic" sourceLanguage="Swift" usedWithCloudKit="YES" userDefinedModelVersionIdentifier="">
|
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="21513" systemVersion="22D49" minimumToolsVersion="Automatic" sourceLanguage="Swift" usedWithCloudKit="YES" userDefinedModelVersionIdentifier="">
|
||||||
<entity name="DebugInfo" representedClassName=".CDDebugInfo" syncable="YES" codeGenerationType="class">
|
<entity name="DebugInfo" representedClassName=".CDDebugInfo" syncable="YES" codeGenerationType="class">
|
||||||
<relationship name="autocod" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="DebugInfoEntry" inverseName="autocodInfo" inverseEntity="DebugInfoEntry"/>
|
<relationship name="autocod" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="DebugInfoEntry" inverseName="autocodInfo" inverseEntity="DebugInfoEntry"/>
|
||||||
<relationship name="nomerogram" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="DebugInfoEntry" inverseName="nomerogramInfo" inverseEntity="DebugInfoEntry"/>
|
<relationship name="nomerogram" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="DebugInfoEntry" inverseName="nomerogramInfo" inverseEntity="DebugInfoEntry"/>
|
||||||
@ -131,19 +131,4 @@
|
|||||||
<attribute name="url" optional="YES" attributeType="String"/>
|
<attribute name="url" optional="YES" attributeType="String"/>
|
||||||
<relationship name="vehicle" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="Vehicle" inverseName="photos" inverseEntity="Vehicle"/>
|
<relationship name="vehicle" optional="YES" maxCount="1" deletionRule="Nullify" destinationEntity="Vehicle" inverseName="photos" inverseEntity="Vehicle"/>
|
||||||
</entity>
|
</entity>
|
||||||
<elements>
|
|
||||||
<element name="VBrand" positionX="118.7528686523438" positionY="-209.1094360351562" width="128" height="74"/>
|
|
||||||
<element name="Vehicle" positionX="-145.9427490234375" positionY="-363.4805297851562" width="128" height="404"/>
|
|
||||||
<element name="VModel" positionX="-9" positionY="-207" width="128" height="59"/>
|
|
||||||
<element name="VName" positionX="-54" positionY="9" width="128" height="89"/>
|
|
||||||
<element name="VEngine" positionX="-9" positionY="-207" width="128" height="119"/>
|
|
||||||
<element name="VPhoto" positionX="0" positionY="-198" width="128" height="104"/>
|
|
||||||
<element name="VOwnershipPeriod" positionX="9" positionY="-189" width="128" height="209"/>
|
|
||||||
<element name="VEvent" positionX="18" positionY="-180" width="128" height="149"/>
|
|
||||||
<element name="VOsago" positionX="27" positionY="-171" width="128" height="194"/>
|
|
||||||
<element name="VAd" positionX="36" positionY="-162" width="128" height="179"/>
|
|
||||||
<element name="VNote" positionX="45" positionY="-153" width="128" height="104"/>
|
|
||||||
<element name="DebugInfoEntry" positionX="-9" positionY="-207" width="128" height="149"/>
|
|
||||||
<element name="DebugInfo" positionX="0" positionY="-198" width="128" height="119"/>
|
|
||||||
</elements>
|
|
||||||
</model>
|
</model>
|
||||||
16
AutoCatCore/Extensions/RealmDecoding.swift
Normal file
16
AutoCatCore/Extensions/RealmDecoding.swift
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
//
|
||||||
|
// RealmDecoding.swift
|
||||||
|
// AutoCatCore
|
||||||
|
//
|
||||||
|
// Created by Selim Mustafaev on 12.02.2023.
|
||||||
|
//
|
||||||
|
|
||||||
|
import RealmSwift
|
||||||
|
|
||||||
|
extension KeyedDecodingContainer {
|
||||||
|
|
||||||
|
func decode<T: Decodable>(_ type: Persisted<List<T>>.Type, forKey key: Key) throws -> Persisted<List<T>> {
|
||||||
|
// Use decode if present, falling back to an empty list
|
||||||
|
try decodeIfPresent(type, forKey: key) ?? Persisted<List<T>>(wrappedValue: List<T>())
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -26,7 +26,7 @@ public enum DataSource: CaseIterable, Identifiable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public struct Filter: Hashable, Identifiable {
|
public final class Filter: Hashable, Identifiable {
|
||||||
|
|
||||||
public let id = UUID()
|
public let id = UUID()
|
||||||
public let name: String
|
public let name: String
|
||||||
@ -49,10 +49,20 @@ public struct Filter: Hashable, Identifiable {
|
|||||||
self.outdated = outdated
|
self.outdated = outdated
|
||||||
}
|
}
|
||||||
|
|
||||||
public func match(vehicle: CDVehicle) -> Bool {
|
public func match(vehicle: Vehicle) -> Bool {
|
||||||
return unrecognized == vehicle.unrecognized
|
return unrecognized == vehicle.unrecognized
|
||||||
&& outdated == vehicle.outdated
|
&& outdated == vehicle.outdated
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static func == (lhs: Filter, rhs: Filter) -> Bool {
|
||||||
|
lhs.dataSource == rhs.dataSource
|
||||||
|
&& lhs.unrecognized == rhs.unrecognized
|
||||||
|
&& lhs.outdated == rhs.outdated
|
||||||
|
}
|
||||||
|
|
||||||
|
public func hash(into hasher: inout Hasher) {
|
||||||
|
hasher.combine(id)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Presets
|
// MARK: - Presets
|
||||||
|
|||||||
@ -1,109 +1,46 @@
|
|||||||
import Foundation
|
import RealmSwift
|
||||||
import CoreData
|
|
||||||
import DifferenceKit
|
import DifferenceKit
|
||||||
|
|
||||||
public struct Vehicle: Decodable {
|
public final class Vehicle: Object, Decodable {
|
||||||
|
|
||||||
public var number: String
|
@Persisted(primaryKey: true) public var number: String
|
||||||
public var currentNumber: String?
|
@Persisted public var currentNumber: String?
|
||||||
public var brand: VBrand?
|
@Persisted public var brand: VBrand?
|
||||||
public var model: VModel?
|
@Persisted public var model: VModel?
|
||||||
public var addedDate: TimeInterval
|
@Persisted public var addedDate: TimeInterval
|
||||||
public var updatedDate: TimeInterval
|
@Persisted public var updatedDate: TimeInterval
|
||||||
public var color: String?
|
@Persisted public var color: String?
|
||||||
public var year: Int64?
|
@Persisted public var year: Int64?
|
||||||
public var category: String?
|
@Persisted public var category: String?
|
||||||
public var vin1: String?
|
@Persisted public var vin1: String?
|
||||||
public var vin2: String?
|
@Persisted public var vin2: String?
|
||||||
public var sts: String?
|
@Persisted public var sts: String?
|
||||||
public var pts: String?
|
@Persisted public var pts: String?
|
||||||
public var isRightWheel: Bool?
|
@Persisted public var isRightWheel: Bool?
|
||||||
public var isJapanese: Bool?
|
@Persisted public var isJapanese: Bool?
|
||||||
public var addedBy: String?
|
@Persisted public var addedBy: String?
|
||||||
public var engine: VEngine?
|
@Persisted public var engine: VEngine?
|
||||||
public var photos: [VPhoto]?
|
@Persisted public var photos: List<VPhoto>
|
||||||
public var ownershipPeriods: [VOwnershipPeriod]?
|
@Persisted public var ownershipPeriods: List<VOwnershipPeriod>
|
||||||
public var events: [VEvent]?
|
@Persisted public var events: List<VEvent>
|
||||||
public var osagoContracts: [VOsago]?
|
@Persisted public var osagoContracts: List<VOsago>
|
||||||
public var ads: [VAd]?
|
@Persisted public var ads: List<VAd>
|
||||||
public var notes: [VNote]?
|
@Persisted public var notes: List<VNote>
|
||||||
public var debugInfo: DebugInfo?
|
@Persisted public var debugInfo: DebugInfo?
|
||||||
|
|
||||||
public init(number: String, brandName: String, addedDate: TimeInterval, updatedDate: TimeInterval) {
|
public convenience init(number: String, brandName: String, addedDate: TimeInterval, updatedDate: TimeInterval) {
|
||||||
|
self.init()
|
||||||
self.number = number
|
self.number = number
|
||||||
self.currentNumber = number
|
self.currentNumber = number
|
||||||
self.addedDate = addedDate
|
self.addedDate = addedDate
|
||||||
self.updatedDate = updatedDate
|
self.updatedDate = updatedDate
|
||||||
|
|
||||||
self.brand = VBrand(name: VName(original: brandName))
|
let name = VName()
|
||||||
}
|
name.original = brandName
|
||||||
}
|
|
||||||
|
|
||||||
extension CDVehicle: Dated {
|
let brand = VBrand()
|
||||||
|
brand.name = name
|
||||||
public var updatedAt: Date {
|
self.brand = brand
|
||||||
Date(timeIntervalSince1970: updatedDate)
|
|
||||||
}
|
|
||||||
|
|
||||||
public var addedAt: Date {
|
|
||||||
Date(timeIntervalSince1970: addedDate)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension CDVehicle: Differentiable {
|
|
||||||
|
|
||||||
public var differenceIdentifier: String { number! }
|
|
||||||
|
|
||||||
public func isContentEqual(to source: CDVehicle) -> Bool {
|
|
||||||
return number == source.number &&
|
|
||||||
addedDate == source.addedDate &&
|
|
||||||
updatedDate == source.updatedDate
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension CDVehicle {
|
|
||||||
|
|
||||||
public convenience init(vehicle: Vehicle, context: NSManagedObjectContext) {
|
|
||||||
|
|
||||||
self.init(context: context)
|
|
||||||
self.number = vehicle.number
|
|
||||||
self.currentNumber = vehicle.currentNumber
|
|
||||||
self.addedDate = vehicle.addedDate/1000
|
|
||||||
self.updatedDate = vehicle.updatedDate/1000
|
|
||||||
self.color = vehicle.color
|
|
||||||
self.brand = CDVBrand(vbrand: vehicle.brand, context: context)
|
|
||||||
self.model = CDVModel(model: vehicle.model, context: context)
|
|
||||||
self.year = vehicle.year ?? 0
|
|
||||||
self.category = category
|
|
||||||
self.vin1 = vehicle.vin1
|
|
||||||
self.vin2 = vehicle.vin2
|
|
||||||
self.sts = vehicle.sts
|
|
||||||
self.pts = vehicle.pts
|
|
||||||
self.isRightWheel = vehicle.isRightWheel ?? false
|
|
||||||
self.isJapanese = vehicle.isJapanese ?? false
|
|
||||||
self.addedBy = vehicle.addedBy
|
|
||||||
self.synchronized = true
|
|
||||||
self.engine = CDVEngine(model: vehicle.engine, context: context)
|
|
||||||
|
|
||||||
let photos = vehicle.photos?.map { CDVPhoto(model: $0, context: context) } ?? []
|
|
||||||
self.photos = NSSet(array: photos)
|
|
||||||
|
|
||||||
let ownershipPeriods = vehicle.ownershipPeriods?.map { CDVOwnershipPeriod(model: $0, context: context) } ?? []
|
|
||||||
self.ownershipPeriods = NSSet(array: ownershipPeriods)
|
|
||||||
|
|
||||||
let events = vehicle.events?.map { CDVEvent(model: $0, context: context) } ?? []
|
|
||||||
self.events = NSSet(array: events)
|
|
||||||
|
|
||||||
let osagoContracts = vehicle.osagoContracts?.map { CDVOsago(model: $0, context: context) } ?? []
|
|
||||||
self.osagoContracts = NSSet(array: osagoContracts)
|
|
||||||
|
|
||||||
let ads = vehicle.ads?.map { CDVAd(model: $0, context: context) } ?? []
|
|
||||||
self.ads = NSSet(array: ads)
|
|
||||||
|
|
||||||
let notes = vehicle.notes?.map { CDVNote(model: $0, context: context) } ?? []
|
|
||||||
self.notes = NSSet(array: notes)
|
|
||||||
|
|
||||||
self.debugInfo = CDDebugInfo(model: vehicle.debugInfo, context: context)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public var unrecognized: Bool {
|
public var unrecognized: Bool {
|
||||||
@ -117,5 +54,32 @@ extension CDVehicle {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extension Vehicle: Dated {
|
||||||
|
|
||||||
|
public var updatedAt: Date {
|
||||||
|
Date(timeIntervalSince1970: updatedDate)
|
||||||
|
}
|
||||||
|
|
||||||
|
public var addedAt: Date {
|
||||||
|
Date(timeIntervalSince1970: addedDate)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension Vehicle: Differentiable {
|
||||||
|
|
||||||
|
public var differenceIdentifier: String { number }
|
||||||
|
|
||||||
|
public func isContentEqual(to source: Vehicle) -> Bool {
|
||||||
|
return number == source.number &&
|
||||||
|
addedDate == source.addedDate &&
|
||||||
|
updatedDate == source.updatedDate
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension Vehicle: Identifiable {
|
||||||
|
|
||||||
|
public var id: String { number }
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,31 +1,10 @@
|
|||||||
//
|
import RealmSwift
|
||||||
// DebugInfo.swift
|
|
||||||
// AutoCatCore
|
|
||||||
//
|
|
||||||
// Created by Selim Mustafaev on 03.04.2022.
|
|
||||||
//
|
|
||||||
|
|
||||||
import Foundation
|
public final class DebugInfo: Object, Decodable {
|
||||||
import CoreData
|
|
||||||
|
|
||||||
public struct DebugInfo: Decodable {
|
@Persisted var autocod: DebugInfoEntry?
|
||||||
|
@Persisted var vin01vin: DebugInfoEntry?
|
||||||
let autocod: DebugInfoEntry?
|
@Persisted var vin01base: DebugInfoEntry?
|
||||||
let vin01vin: DebugInfoEntry?
|
@Persisted var vin01history: DebugInfoEntry?
|
||||||
let vin01base: DebugInfoEntry?
|
@Persisted var nomerogram: DebugInfoEntry?
|
||||||
let vin01history: DebugInfoEntry?
|
|
||||||
let nomerogram: DebugInfoEntry?
|
|
||||||
}
|
|
||||||
|
|
||||||
extension CDDebugInfo {
|
|
||||||
|
|
||||||
convenience init(model: DebugInfo?, context: NSManagedObjectContext) {
|
|
||||||
self.init(context: context)
|
|
||||||
|
|
||||||
self.autocod = CDDebugInfoEntry(model: model?.autocod, context: context)
|
|
||||||
self.vin01vin = CDDebugInfoEntry(model: model?.vin01vin, context: context)
|
|
||||||
self.vin01base = CDDebugInfoEntry(model: model?.vin01base, context: context)
|
|
||||||
self.vin01history = CDDebugInfoEntry(model: model?.vin01history, context: context)
|
|
||||||
self.nomerogram = CDDebugInfoEntry(model: model?.nomerogram, context: context)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,38 +1,15 @@
|
|||||||
//
|
import RealmSwift
|
||||||
// DebugInfoEntry.swift
|
|
||||||
// AutoCatCore
|
|
||||||
//
|
|
||||||
// Created by Selim Mustafaev on 03.04.2022.
|
|
||||||
//
|
|
||||||
|
|
||||||
import Foundation
|
public enum DebugInfoStatus: Int64, Decodable, PersistableEnum {
|
||||||
import CoreData
|
|
||||||
|
|
||||||
public enum DebugInfoStatus: Int64 {
|
|
||||||
case success = 0
|
case success = 0
|
||||||
case error = 1
|
case error = 1
|
||||||
case warning = 2
|
case warning = 2
|
||||||
}
|
}
|
||||||
|
|
||||||
public struct DebugInfoEntry: Decodable {
|
public final class DebugInfoEntry: Object, Decodable {
|
||||||
|
|
||||||
let fields: Int64
|
@Persisted var fields: Int64
|
||||||
let error: String?
|
@Persisted var error: String?
|
||||||
let status: Int64
|
@Persisted var status: DebugInfoStatus?
|
||||||
}
|
|
||||||
|
|
||||||
extension CDDebugInfoEntry {
|
|
||||||
|
|
||||||
convenience init(model: DebugInfoEntry?, context: NSManagedObjectContext) {
|
|
||||||
self.init(context: context)
|
|
||||||
|
|
||||||
self.fields = model?.fields ?? 0
|
|
||||||
self.error = model?.error
|
|
||||||
self.status = model?.status ?? 0
|
|
||||||
}
|
|
||||||
|
|
||||||
public var statusEnum: DebugInfoStatus {
|
|
||||||
get { DebugInfoStatus(rawValue: self.status)! }
|
|
||||||
set { self.status = newValue.rawValue }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,39 +1,15 @@
|
|||||||
//
|
import RealmSwift
|
||||||
// VAd.swift
|
|
||||||
// AutoCatCore
|
|
||||||
//
|
|
||||||
// Created by Selim Mustafaev on 02.04.2022.
|
|
||||||
//
|
|
||||||
|
|
||||||
import Foundation
|
public final class VAd: Object, Decodable {
|
||||||
import CoreData
|
|
||||||
|
|
||||||
public struct VAd: Decodable {
|
@Persisted var id: Int64
|
||||||
|
@Persisted var url: String?
|
||||||
let id: Int64
|
@Persisted var price: String?
|
||||||
let url: String?
|
@Persisted var date: Double
|
||||||
let price: String?
|
@Persisted var mileage: String?
|
||||||
let date: Double
|
@Persisted var region: String?
|
||||||
let mileage: String?
|
@Persisted var city: String?
|
||||||
let region: String?
|
@Persisted var adDescription: String?
|
||||||
let city: String?
|
@Persisted var photos: List<String>
|
||||||
let adDescription: String?
|
|
||||||
let photos: [String]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extension CDVAd {
|
|
||||||
|
|
||||||
convenience init(model: VAd?, context: NSManagedObjectContext) {
|
|
||||||
self.init(context: context)
|
|
||||||
|
|
||||||
self.id = model?.id ?? 0
|
|
||||||
self.url = model?.url
|
|
||||||
self.price = model?.price
|
|
||||||
self.date = model?.date ?? 0
|
|
||||||
self.mileage = model?.mileage
|
|
||||||
self.region = model?.region
|
|
||||||
self.city = model?.city
|
|
||||||
self.adDescription = model?.adDescription
|
|
||||||
self.photos = model?.photos
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@ -1,19 +1,7 @@
|
|||||||
import Foundation
|
import RealmSwift
|
||||||
import CoreData
|
|
||||||
|
|
||||||
public struct VBrand: Decodable {
|
public final class VBrand: Object, Decodable {
|
||||||
|
|
||||||
public var logo: String?
|
|
||||||
public var name: VName?
|
|
||||||
}
|
|
||||||
|
|
||||||
extension CDVBrand {
|
|
||||||
|
|
||||||
convenience init(vbrand: VBrand?, context: NSManagedObjectContext) {
|
|
||||||
|
|
||||||
self.init(context: context)
|
|
||||||
self.logo = vbrand?.logo
|
|
||||||
self.name = CDVName(vname: vbrand?.name, context: context)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@Persisted public var logo: String?
|
||||||
|
@Persisted public var name: VName?
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,31 +1,10 @@
|
|||||||
//
|
import RealmSwift
|
||||||
// VEngine.swift
|
|
||||||
// AutoCatCore
|
|
||||||
//
|
|
||||||
// Created by Selim Mustafaev on 02.04.2022.
|
|
||||||
//
|
|
||||||
|
|
||||||
import Foundation
|
public final class VEngine: Object, Decodable {
|
||||||
import CoreData
|
|
||||||
|
|
||||||
public struct VEngine: Decodable {
|
@Persisted public var number: String?
|
||||||
|
@Persisted public var volume: Int64?
|
||||||
let number: String?
|
@Persisted public var powerHp: Float?
|
||||||
let volume: Int64?
|
@Persisted public var powerKw: Float?
|
||||||
let powerHp: Float?
|
@Persisted public var fuelType: String?
|
||||||
let powerKw: Float?
|
|
||||||
let fuelType: String?
|
|
||||||
}
|
|
||||||
|
|
||||||
extension CDVEngine {
|
|
||||||
|
|
||||||
convenience init(model: VEngine?, context: NSManagedObjectContext) {
|
|
||||||
self.init(context: context)
|
|
||||||
|
|
||||||
self.number = model?.number
|
|
||||||
self.volume = model?.volume ?? 0
|
|
||||||
self.powerHp = model?.powerHp ?? 0
|
|
||||||
self.powerKw = model?.powerKw ?? 0
|
|
||||||
self.fuelType = model?.fuelType
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,35 +1,10 @@
|
|||||||
//
|
import RealmSwift
|
||||||
// VEvent.swift
|
|
||||||
// AutoCatCore
|
|
||||||
//
|
|
||||||
// Created by Selim Mustafaev on 02.04.2022.
|
|
||||||
//
|
|
||||||
|
|
||||||
import Foundation
|
public final class VEvent: Object, Decodable {
|
||||||
import CoreData
|
|
||||||
|
|
||||||
public struct VEvent: Decodable {
|
@Persisted var id: String
|
||||||
|
@Persisted var date: Double
|
||||||
let id: String
|
@Persisted var latitude: Double
|
||||||
let date: Double
|
@Persisted var longitude: Double
|
||||||
let latitude: Double
|
@Persisted var address: String?
|
||||||
let longitude: Double
|
|
||||||
let speed: Double
|
|
||||||
let direction: Double
|
|
||||||
let address: String?
|
|
||||||
}
|
|
||||||
|
|
||||||
extension CDVEvent {
|
|
||||||
|
|
||||||
convenience init(model: VEvent?, context: NSManagedObjectContext) {
|
|
||||||
self.init(context: context)
|
|
||||||
|
|
||||||
self.id = model?.id
|
|
||||||
self.date = model?.date ?? 0
|
|
||||||
self.latitude = model?.latitude ?? 0
|
|
||||||
self.longitude = model?.longitude ?? 0
|
|
||||||
self.speed = model?.speed ?? 0
|
|
||||||
self.direction = model?.direction ?? 0
|
|
||||||
self.address = model?.address
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,22 +1,6 @@
|
|||||||
//
|
import RealmSwift
|
||||||
// VModel.swift
|
|
||||||
// AutoCatCore
|
|
||||||
//
|
|
||||||
// Created by Selim Mustafaev on 29.03.2022.
|
|
||||||
//
|
|
||||||
|
|
||||||
import Foundation
|
public final class VModel: Object, Decodable {
|
||||||
import CoreData
|
|
||||||
|
|
||||||
public struct VModel: Decodable {
|
@Persisted var name: VName?
|
||||||
|
|
||||||
let name: VName?
|
|
||||||
}
|
|
||||||
|
|
||||||
extension CDVModel {
|
|
||||||
|
|
||||||
convenience init(model: VModel?, context: NSManagedObjectContext) {
|
|
||||||
self.init(context: context)
|
|
||||||
self.name = CDVName(vname: model?.name, context: context)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,19 +1,7 @@
|
|||||||
import Foundation
|
import RealmSwift
|
||||||
import CoreData
|
|
||||||
|
|
||||||
public struct VName: Decodable {
|
public final class VName: Object, Decodable {
|
||||||
|
|
||||||
public var normalized: String?
|
|
||||||
public var original: String?
|
|
||||||
}
|
|
||||||
|
|
||||||
extension CDVName {
|
|
||||||
|
|
||||||
convenience init(vname: VName?, context: NSManagedObjectContext) {
|
|
||||||
|
|
||||||
self.init(context: context)
|
|
||||||
self.normalized = vname?.normalized
|
|
||||||
self.original = vname?.original
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@Persisted public var normalized: String?
|
||||||
|
@Persisted public var original: String?
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,29 +1,9 @@
|
|||||||
//
|
import RealmSwift
|
||||||
// VNote.swift
|
|
||||||
// AutoCatCore
|
|
||||||
//
|
|
||||||
// Created by Selim Mustafaev on 02.04.2022.
|
|
||||||
//
|
|
||||||
|
|
||||||
import Foundation
|
public final class VNote: Object, Decodable {
|
||||||
import CoreData
|
|
||||||
|
|
||||||
public struct VNote: Decodable {
|
@Persisted var id: String?
|
||||||
|
@Persisted var user: String?
|
||||||
let id: String?
|
@Persisted var date: Double
|
||||||
let user: String?
|
@Persisted var text: String?
|
||||||
let date: Double
|
|
||||||
let text: String?
|
|
||||||
}
|
|
||||||
|
|
||||||
extension CDVNote {
|
|
||||||
|
|
||||||
convenience init(model: VNote?, context: NSManagedObjectContext) {
|
|
||||||
self.init(context: context)
|
|
||||||
|
|
||||||
self.id = model?.id
|
|
||||||
self.user = model?.user
|
|
||||||
self.date = model?.date ?? 0
|
|
||||||
self.text = model?.text
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,41 +1,15 @@
|
|||||||
//
|
import RealmSwift
|
||||||
// VOsago.swift
|
|
||||||
// AutoCatCore
|
|
||||||
//
|
|
||||||
// Created by Selim Mustafaev on 02.04.2022.
|
|
||||||
//
|
|
||||||
|
|
||||||
import Foundation
|
public final class VOsago: Object, Decodable {
|
||||||
import CoreData
|
|
||||||
|
|
||||||
public struct VOsago: Decodable {
|
@Persisted var date: Double
|
||||||
|
@Persisted var number: String?
|
||||||
let date: Double
|
@Persisted var vin: String?
|
||||||
let number: String?
|
@Persisted var plateNumber: String?
|
||||||
let vin: String?
|
@Persisted var name: String?
|
||||||
let plateNumber: String?
|
@Persisted var status: String?
|
||||||
let name: String?
|
@Persisted var restrictions: String?
|
||||||
let status: String?
|
@Persisted var insurant: String?
|
||||||
let restrictions: String?
|
@Persisted var owner: String?
|
||||||
let insurant: String?
|
@Persisted var usageRegion: String?
|
||||||
let owner: String?
|
|
||||||
let usageRegion: String?
|
|
||||||
}
|
|
||||||
|
|
||||||
extension CDVOsago {
|
|
||||||
|
|
||||||
convenience init(model: VOsago?, context: NSManagedObjectContext) {
|
|
||||||
self.init(context: context)
|
|
||||||
|
|
||||||
self.date = model?.date ?? 0
|
|
||||||
self.number = model?.number
|
|
||||||
self.vin = model?.vin
|
|
||||||
self.plateNumber = model?.plateNumber
|
|
||||||
self.name = model?.name
|
|
||||||
self.status = model?.status
|
|
||||||
self.restrictions = model?.restrictions
|
|
||||||
self.insurant = model?.insurant
|
|
||||||
self.owner = model?.owner
|
|
||||||
self.usageRegion = model?.usageRegion
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,43 +1,16 @@
|
|||||||
//
|
import RealmSwift
|
||||||
// VOwnershipPeriod.swift
|
|
||||||
// AutoCatCore
|
|
||||||
//
|
|
||||||
// Created by Selim Mustafaev on 02.04.2022.
|
|
||||||
//
|
|
||||||
|
|
||||||
import Foundation
|
public final class VOwnershipPeriod: Object, Decodable {
|
||||||
import CoreData
|
|
||||||
|
|
||||||
public struct VOwnershipPeriod: Decodable {
|
@Persisted var lastOperation: String?
|
||||||
|
@Persisted var ownerType: String?
|
||||||
let lastOperation: String?
|
@Persisted var from: Int64?
|
||||||
let ownerType: String?
|
@Persisted var to: Int64?
|
||||||
let from: Int64?
|
@Persisted var region: String?
|
||||||
let to: Int64?
|
@Persisted var registrationRegion: String?
|
||||||
let region: String?
|
@Persisted var locality: String?
|
||||||
let registrationRegion: String?
|
@Persisted var code: String?
|
||||||
let locality: String?
|
@Persisted var street: String?
|
||||||
let code: String?
|
@Persisted var building: String?
|
||||||
let street: String?
|
@Persisted var inn: String?
|
||||||
let building: String?
|
|
||||||
let inn: String?
|
|
||||||
}
|
|
||||||
|
|
||||||
extension CDVOwnershipPeriod {
|
|
||||||
|
|
||||||
convenience init(model: VOwnershipPeriod?, context: NSManagedObjectContext) {
|
|
||||||
self.init(context: context)
|
|
||||||
|
|
||||||
self.lastOperation = model?.lastOperation
|
|
||||||
self.ownerType = model?.ownerType
|
|
||||||
self.from = model?.from ?? 0
|
|
||||||
self.to = model?.to ?? 0
|
|
||||||
self.region = model?.region
|
|
||||||
self.registrationRegion = model?.registrationRegion
|
|
||||||
self.locality = model?.locality
|
|
||||||
self.code = model?.locality
|
|
||||||
self.street = model?.street
|
|
||||||
self.building = model?.building
|
|
||||||
self.inn = model?.inn
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,29 +1,9 @@
|
|||||||
//
|
import RealmSwift
|
||||||
// VPhoto.swift
|
|
||||||
// AutoCatCore
|
|
||||||
//
|
|
||||||
// Created by Selim Mustafaev on 02.04.2022.
|
|
||||||
//
|
|
||||||
|
|
||||||
import Foundation
|
public final class VPhoto: Object, Decodable {
|
||||||
import CoreData
|
|
||||||
|
|
||||||
public struct VPhoto: Decodable {
|
@Persisted var brand: String?
|
||||||
|
@Persisted var model: String?
|
||||||
let brand: String?
|
@Persisted var date: Double
|
||||||
let model: String?
|
@Persisted var url: String?
|
||||||
let date: Double
|
|
||||||
let url: String?
|
|
||||||
}
|
|
||||||
|
|
||||||
extension CDVPhoto {
|
|
||||||
|
|
||||||
convenience init(model: VPhoto?, context: NSManagedObjectContext) {
|
|
||||||
self.init(context: context)
|
|
||||||
|
|
||||||
self.brand = model?.brand
|
|
||||||
self.model = model?.model
|
|
||||||
self.date = model?.date ?? 0
|
|
||||||
self.url = model?.url
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,91 +1,57 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
import CoreData
|
import RealmSwift
|
||||||
|
|
||||||
protocol StorageServiceProtocol {
|
protocol StorageServiceProtocol {
|
||||||
|
|
||||||
var context: NSManagedObjectContext { get }
|
func store(vehicle: Vehicle) throws
|
||||||
func store(vehicle: Vehicle) throws -> CDVehicle
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class StorageService: StorageServiceProtocol {
|
public class StorageService: StorageServiceProtocol {
|
||||||
|
|
||||||
|
public enum StorageError: String, LocalizedError {
|
||||||
|
|
||||||
|
case openDatabaseError = "Ошибка открытия БД"
|
||||||
|
|
||||||
|
public var errorDescription: String? {
|
||||||
|
rawValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static var instance: StorageService?
|
private static var instance: StorageService?
|
||||||
|
|
||||||
private let container: NSPersistentCloudKitContainer
|
private let realm: Realm
|
||||||
|
|
||||||
public static var shared: StorageService {
|
public static var shared: StorageService {
|
||||||
get async throws {
|
get throws {
|
||||||
if let instance = StorageService.instance {
|
if let instance = StorageService.instance {
|
||||||
return instance
|
return instance
|
||||||
} else {
|
} else {
|
||||||
let service = StorageService(inMemory: Testing.isUITesting)
|
if let service = StorageService(inMemory: Testing.isUITesting) {
|
||||||
try await service.loadPersistentStores()
|
|
||||||
StorageService.instance = service
|
StorageService.instance = service
|
||||||
return service
|
return service
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static var sharedNotWait: StorageService {
|
|
||||||
if let instance = StorageService.instance {
|
|
||||||
return instance
|
|
||||||
} else {
|
} else {
|
||||||
let service = StorageService(inMemory: Testing.isUITesting)
|
throw StorageError.openDatabaseError
|
||||||
Task {
|
}
|
||||||
try? await service.loadPersistentStores()
|
|
||||||
}
|
}
|
||||||
StorageService.instance = service
|
|
||||||
return service
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
init(inMemory: Bool = false) {
|
init?(inMemory: Bool = false) {
|
||||||
|
let config = Realm.Configuration(inMemoryIdentifier: inMemory ? "memory" : nil)
|
||||||
|
|
||||||
let bundle = Bundle(for: Self.self)
|
guard let realm = try? Realm(configuration: config) else {
|
||||||
let url = bundle.url(forResource: "AutoCat2", withExtension: "momd")
|
return nil
|
||||||
let mom = NSManagedObjectModel(contentsOf: url!)
|
|
||||||
|
|
||||||
container = NSPersistentCloudKitContainer(name: "AutoCat2", managedObjectModel: mom!)
|
|
||||||
if inMemory {
|
|
||||||
container.persistentStoreDescriptions.first!.url = URL(fileURLWithPath: "/dev/null")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private func loadPersistentStores() async throws {
|
self.realm = realm
|
||||||
try await withCheckedThrowingContinuation { (continuation: CheckedContinuation<Void, Error>) in
|
|
||||||
container.loadPersistentStores(completionHandler: { (storeDescription, error) in
|
|
||||||
if let error = error as NSError? {
|
|
||||||
continuation.resume(throwing: error)
|
|
||||||
} else {
|
|
||||||
continuation.resume(returning: ())
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private func save() throws {
|
|
||||||
guard context.hasChanges else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
do {
|
|
||||||
try context.save()
|
|
||||||
} catch {
|
|
||||||
context.rollback()
|
|
||||||
throw error
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - StorageServiceProtocol
|
// MARK: - StorageServiceProtocol
|
||||||
|
|
||||||
public var context: NSManagedObjectContext {
|
public func store(vehicle: Vehicle) throws {
|
||||||
container.viewContext
|
|
||||||
|
try realm.write {
|
||||||
|
realm.add(vehicle, update: .all)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func store(vehicle: Vehicle) throws -> CDVehicle {
|
|
||||||
|
|
||||||
let cdVehicle = CDVehicle(vehicle: vehicle, context: context)
|
|
||||||
try save()
|
|
||||||
return cdVehicle
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,7 +2,7 @@ import Foundation
|
|||||||
|
|
||||||
protocol VehicleServiceProtocol {
|
protocol VehicleServiceProtocol {
|
||||||
|
|
||||||
func check(plateNumber: String, force: Bool) async throws -> CDVehicle
|
func check(plateNumber: String, force: Bool) async throws -> Vehicle
|
||||||
}
|
}
|
||||||
|
|
||||||
public class VehicleService: VehicleServiceProtocol {
|
public class VehicleService: VehicleServiceProtocol {
|
||||||
@ -11,8 +11,8 @@ public class VehicleService: VehicleServiceProtocol {
|
|||||||
private let storage: StorageServiceProtocol
|
private let storage: StorageServiceProtocol
|
||||||
|
|
||||||
public static var shared: VehicleService {
|
public static var shared: VehicleService {
|
||||||
get async throws {
|
get throws {
|
||||||
let storageService = try await StorageService.shared
|
let storageService = try StorageService.shared
|
||||||
return VehicleService(api: Api.shared, storage: storageService)
|
return VehicleService(api: Api.shared, storage: storageService)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -25,11 +25,13 @@ public class VehicleService: VehicleServiceProtocol {
|
|||||||
|
|
||||||
// MARK: - VehicleServiceProtocol
|
// MARK: - VehicleServiceProtocol
|
||||||
|
|
||||||
|
@MainActor
|
||||||
@discardableResult
|
@discardableResult
|
||||||
public func check(plateNumber: String, force: Bool) async throws -> CDVehicle {
|
public func check(plateNumber: String, force: Bool) async throws -> Vehicle {
|
||||||
|
|
||||||
let vehicle = try await api.check(plateNumber: plateNumber, force: force)
|
let vehicle = try await api.check(plateNumber: plateNumber, force: force)
|
||||||
return try storage.store(vehicle: vehicle)
|
try storage.store(vehicle: vehicle)
|
||||||
|
return vehicle
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user