SwiftUI version of google oauth signin controller
This commit is contained in:
parent
7831b7e615
commit
41578579ef
@ -136,7 +136,6 @@
|
|||||||
7A9519842D80B72B00E69883 /* RecordsCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A9519832D80B72B00E69883 /* RecordsCoordinator.swift */; };
|
7A9519842D80B72B00E69883 /* RecordsCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A9519832D80B72B00E69883 /* RecordsCoordinator.swift */; };
|
||||||
7A961C6C2C4C3C8600CE2211 /* TextRowView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A961C6B2C4C3C8600CE2211 /* TextRowView.swift */; };
|
7A961C6C2C4C3C8600CE2211 /* TextRowView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A961C6B2C4C3C8600CE2211 /* TextRowView.swift */; };
|
||||||
7A961C6E2C4C3C9E00CE2211 /* LinkRowView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A961C6D2C4C3C9E00CE2211 /* LinkRowView.swift */; };
|
7A961C6E2C4C3C9E00CE2211 /* LinkRowView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A961C6D2C4C3C9E00CE2211 /* LinkRowView.swift */; };
|
||||||
7A96AE2D246B2B7400297C33 /* GoogleSignInController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A96AE2C246B2B7400297C33 /* GoogleSignInController.swift */; };
|
|
||||||
7A96AE2F246B2BCD00297C33 /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7A96AE2E246B2BCD00297C33 /* WebKit.framework */; };
|
7A96AE2F246B2BCD00297C33 /* WebKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7A96AE2E246B2BCD00297C33 /* WebKit.framework */; };
|
||||||
7AA514E02D0B75B3001CAC50 /* StorageService+Events.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AA514DF2D0B75B3001CAC50 /* StorageService+Events.swift */; };
|
7AA514E02D0B75B3001CAC50 /* StorageService+Events.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AA514DF2D0B75B3001CAC50 /* StorageService+Events.swift */; };
|
||||||
7AA515D02D9ABCC800EB3418 /* RecordPlayerService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AA515CF2D9ABCC800EB3418 /* RecordPlayerService.swift */; };
|
7AA515D02D9ABCC800EB3418 /* RecordPlayerService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AA515CF2D9ABCC800EB3418 /* RecordPlayerService.swift */; };
|
||||||
@ -194,8 +193,12 @@
|
|||||||
7ADF6C97250F41B000F237B2 /* PNKeyboard.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7ADF6C96250F41B000F237B2 /* PNKeyboard.swift */; };
|
7ADF6C97250F41B000F237B2 /* PNKeyboard.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7ADF6C96250F41B000F237B2 /* PNKeyboard.swift */; };
|
||||||
7ADF6C99250F872C00F237B2 /* RoadNumbers.otf in Resources */ = {isa = PBXBuildFile; fileRef = 7ADF6C98250F872C00F237B2 /* RoadNumbers.otf */; };
|
7ADF6C99250F872C00F237B2 /* RoadNumbers.otf in Resources */ = {isa = PBXBuildFile; fileRef = 7ADF6C98250F872C00F237B2 /* RoadNumbers.otf */; };
|
||||||
7ADF6CA12512244400F237B2 /* MapExt.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7ADF6CA02512244400F237B2 /* MapExt.swift */; };
|
7ADF6CA12512244400F237B2 /* MapExt.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7ADF6CA02512244400F237B2 /* MapExt.swift */; };
|
||||||
|
7ADFC9572DAD0288001A43E3 /* GoogleAuthScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7ADFC9562DAD0288001A43E3 /* GoogleAuthScreen.swift */; };
|
||||||
|
7ADFC9592DAD1C3D001A43E3 /* GoogleAuthViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7ADFC9582DAD1C3D001A43E3 /* GoogleAuthViewModel.swift */; };
|
||||||
|
7ADFC95B2DAD1F45001A43E3 /* WebView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7ADFC95A2DAD1F45001A43E3 /* WebView.swift */; };
|
||||||
7AE24C5F251F1B4E00758E39 /* Buttons.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AE24C5E251F1B4E00758E39 /* Buttons.swift */; };
|
7AE24C5F251F1B4E00758E39 /* Buttons.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AE24C5E251F1B4E00758E39 /* Buttons.swift */; };
|
||||||
7AE26A3324EEF9EC00625033 /* UIViewControllerExt.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AE26A3224EEF9EC00625033 /* UIViewControllerExt.swift */; };
|
7AE26A3324EEF9EC00625033 /* UIViewControllerExt.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AE26A3224EEF9EC00625033 /* UIViewControllerExt.swift */; };
|
||||||
|
7AEAA2A12DAD9C00009954F0 /* TokenResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AEAA2A02DAD9C00009954F0 /* TokenResponse.swift */; };
|
||||||
7AF231932DA1C28100AE5EB3 /* AuthScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AF231922DA1C28100AE5EB3 /* AuthScreen.swift */; };
|
7AF231932DA1C28100AE5EB3 /* AuthScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AF231922DA1C28100AE5EB3 /* AuthScreen.swift */; };
|
||||||
7AF231952DA1C29300AE5EB3 /* AuthViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AF231942DA1C29300AE5EB3 /* AuthViewModel.swift */; };
|
7AF231952DA1C29300AE5EB3 /* AuthViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AF231942DA1C29300AE5EB3 /* AuthViewModel.swift */; };
|
||||||
7AF231972DA1C30000AE5EB3 /* AuthCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AF231962DA1C30000AE5EB3 /* AuthCoordinator.swift */; };
|
7AF231972DA1C30000AE5EB3 /* AuthCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AF231962DA1C30000AE5EB3 /* AuthCoordinator.swift */; };
|
||||||
@ -422,7 +425,6 @@
|
|||||||
7A9519832D80B72B00E69883 /* RecordsCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecordsCoordinator.swift; sourceTree = "<group>"; };
|
7A9519832D80B72B00E69883 /* RecordsCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecordsCoordinator.swift; sourceTree = "<group>"; };
|
||||||
7A961C6B2C4C3C8600CE2211 /* TextRowView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextRowView.swift; sourceTree = "<group>"; };
|
7A961C6B2C4C3C8600CE2211 /* TextRowView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextRowView.swift; sourceTree = "<group>"; };
|
||||||
7A961C6D2C4C3C9E00CE2211 /* LinkRowView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LinkRowView.swift; sourceTree = "<group>"; };
|
7A961C6D2C4C3C9E00CE2211 /* LinkRowView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LinkRowView.swift; sourceTree = "<group>"; };
|
||||||
7A96AE2C246B2B7400297C33 /* GoogleSignInController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GoogleSignInController.swift; sourceTree = "<group>"; };
|
|
||||||
7A96AE2E246B2BCD00297C33 /* WebKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebKit.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk/System/Library/Frameworks/WebKit.framework; sourceTree = DEVELOPER_DIR; };
|
7A96AE2E246B2BCD00297C33 /* WebKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WebKit.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk/System/Library/Frameworks/WebKit.framework; sourceTree = DEVELOPER_DIR; };
|
||||||
7A96AE30246B2FE400297C33 /* Constants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Constants.swift; sourceTree = "<group>"; };
|
7A96AE30246B2FE400297C33 /* Constants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Constants.swift; sourceTree = "<group>"; };
|
||||||
7A96AE32246C095700297C33 /* Base64FS.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Base64FS.swift; sourceTree = "<group>"; };
|
7A96AE32246C095700297C33 /* Base64FS.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Base64FS.swift; sourceTree = "<group>"; };
|
||||||
@ -478,9 +480,13 @@
|
|||||||
7ADF6C96250F41B000F237B2 /* PNKeyboard.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PNKeyboard.swift; sourceTree = "<group>"; };
|
7ADF6C96250F41B000F237B2 /* PNKeyboard.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PNKeyboard.swift; sourceTree = "<group>"; };
|
||||||
7ADF6C98250F872C00F237B2 /* RoadNumbers.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = RoadNumbers.otf; sourceTree = "<group>"; };
|
7ADF6C98250F872C00F237B2 /* RoadNumbers.otf */ = {isa = PBXFileReference; lastKnownFileType = file; path = RoadNumbers.otf; sourceTree = "<group>"; };
|
||||||
7ADF6CA02512244400F237B2 /* MapExt.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapExt.swift; sourceTree = "<group>"; };
|
7ADF6CA02512244400F237B2 /* MapExt.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MapExt.swift; sourceTree = "<group>"; };
|
||||||
|
7ADFC9562DAD0288001A43E3 /* GoogleAuthScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GoogleAuthScreen.swift; sourceTree = "<group>"; };
|
||||||
|
7ADFC9582DAD1C3D001A43E3 /* GoogleAuthViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GoogleAuthViewModel.swift; sourceTree = "<group>"; };
|
||||||
|
7ADFC95A2DAD1F45001A43E3 /* WebView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WebView.swift; sourceTree = "<group>"; };
|
||||||
7AE24C5E251F1B4E00758E39 /* Buttons.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Buttons.swift; sourceTree = "<group>"; };
|
7AE24C5E251F1B4E00758E39 /* Buttons.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Buttons.swift; sourceTree = "<group>"; };
|
||||||
7AE26A3224EEF9EC00625033 /* UIViewControllerExt.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIViewControllerExt.swift; sourceTree = "<group>"; };
|
7AE26A3224EEF9EC00625033 /* UIViewControllerExt.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UIViewControllerExt.swift; sourceTree = "<group>"; };
|
||||||
7AE8424D26109F78002F6B31 /* Exportable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Exportable.swift; sourceTree = "<group>"; };
|
7AE8424D26109F78002F6B31 /* Exportable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Exportable.swift; sourceTree = "<group>"; };
|
||||||
|
7AEAA2A02DAD9C00009954F0 /* TokenResponse.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TokenResponse.swift; sourceTree = "<group>"; };
|
||||||
7AF231922DA1C28100AE5EB3 /* AuthScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthScreen.swift; sourceTree = "<group>"; };
|
7AF231922DA1C28100AE5EB3 /* AuthScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthScreen.swift; sourceTree = "<group>"; };
|
||||||
7AF231942DA1C29300AE5EB3 /* AuthViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthViewModel.swift; sourceTree = "<group>"; };
|
7AF231942DA1C29300AE5EB3 /* AuthViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthViewModel.swift; sourceTree = "<group>"; };
|
||||||
7AF231962DA1C30000AE5EB3 /* AuthCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthCoordinator.swift; sourceTree = "<group>"; };
|
7AF231962DA1C30000AE5EB3 /* AuthCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthCoordinator.swift; sourceTree = "<group>"; };
|
||||||
@ -655,7 +661,6 @@
|
|||||||
7A11471423FDEAF800B424AF /* Controllers */ = {
|
7A11471423FDEAF800B424AF /* Controllers */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
7A96AE2C246B2B7400297C33 /* GoogleSignInController.swift */,
|
|
||||||
7A11471523FDEB2A00B424AF /* MainSplitController.swift */,
|
7A11471523FDEB2A00B424AF /* MainSplitController.swift */,
|
||||||
7AC3554B29696A1C00889457 /* MainTabController.swift */,
|
7AC3554B29696A1C00889457 /* MainTabController.swift */,
|
||||||
7AC3554D29696C4500889457 /* DummyNewController.swift */,
|
7AC3554D29696C4500889457 /* DummyNewController.swift */,
|
||||||
@ -692,7 +697,6 @@
|
|||||||
7A333813249A532400D878F1 /* Filter.swift */,
|
7A333813249A532400D878F1 /* Filter.swift */,
|
||||||
6841A913FABBB0AB20DEF4FC /* PagedResponse.swift */,
|
6841A913FABBB0AB20DEF4FC /* PagedResponse.swift */,
|
||||||
7A6DD90D24337930009DE740 /* PlateNumber.swift */,
|
7A6DD90D24337930009DE740 /* PlateNumber.swift */,
|
||||||
7A11474823FF2B2D00B424AF /* Response.swift */,
|
|
||||||
7A11474623FF2AA500B424AF /* User.swift */,
|
7A11474623FF2AA500B424AF /* User.swift */,
|
||||||
7AB562B9249C9E9B00473D53 /* VehicleRegion.swift */,
|
7AB562B9249C9E9B00473D53 /* VehicleRegion.swift */,
|
||||||
7AB4E4372D3D0C5C0006D052 /* VehiclesArchive.swift */,
|
7AB4E4372D3D0C5C0006D052 /* VehiclesArchive.swift */,
|
||||||
@ -725,6 +729,7 @@
|
|||||||
7A1441632C297E9800E79018 /* Screens */ = {
|
7A1441632C297E9800E79018 /* Screens */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
7ADFC9552DAD026C001A43E3 /* GoogleAuthScreen */,
|
||||||
7A386A3E2DABDBFF0051676A /* MapScreen */,
|
7A386A3E2DABDBFF0051676A /* MapScreen */,
|
||||||
7AF231912DA1C26C00AE5EB3 /* AuthScreen */,
|
7AF231912DA1C26C00AE5EB3 /* AuthScreen */,
|
||||||
7A95197E2D80B69800E69883 /* RecordsScreen */,
|
7A95197E2D80B69800E69883 /* RecordsScreen */,
|
||||||
@ -1060,6 +1065,8 @@
|
|||||||
7AB587402C42FFE200FA7B66 /* ApiServiceProtocol.swift */,
|
7AB587402C42FFE200FA7B66 /* ApiServiceProtocol.swift */,
|
||||||
7A11474323FF06CA00B424AF /* ApiService.swift */,
|
7A11474323FF06CA00B424AF /* ApiService.swift */,
|
||||||
7A599C352C18AC7F00D47C18 /* ApiError.swift */,
|
7A599C352C18AC7F00D47C18 /* ApiError.swift */,
|
||||||
|
7A11474823FF2B2D00B424AF /* Response.swift */,
|
||||||
|
7AEAA2A02DAD9C00009954F0 /* TokenResponse.swift */,
|
||||||
);
|
);
|
||||||
path = ApiService;
|
path = ApiService;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -1127,6 +1134,16 @@
|
|||||||
path = Extensions;
|
path = Extensions;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
7ADFC9552DAD026C001A43E3 /* GoogleAuthScreen */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
7ADFC9562DAD0288001A43E3 /* GoogleAuthScreen.swift */,
|
||||||
|
7ADFC9582DAD1C3D001A43E3 /* GoogleAuthViewModel.swift */,
|
||||||
|
7ADFC95A2DAD1F45001A43E3 /* WebView.swift */,
|
||||||
|
);
|
||||||
|
path = GoogleAuthScreen;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
7AF231912DA1C26C00AE5EB3 /* AuthScreen */ = {
|
7AF231912DA1C26C00AE5EB3 /* AuthScreen */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
@ -1446,6 +1463,7 @@
|
|||||||
7AFBE8C02C3024E5003C491D /* ACHud.swift in Sources */,
|
7AFBE8C02C3024E5003C491D /* ACHud.swift in Sources */,
|
||||||
7A9519842D80B72B00E69883 /* RecordsCoordinator.swift in Sources */,
|
7A9519842D80B72B00E69883 /* RecordsCoordinator.swift in Sources */,
|
||||||
7AAAFADA2C4D1AFE0050410D /* Zoomable.swift in Sources */,
|
7AAAFADA2C4D1AFE0050410D /* Zoomable.swift in Sources */,
|
||||||
|
7ADFC9572DAD0288001A43E3 /* GoogleAuthScreen.swift in Sources */,
|
||||||
7AC8B2762D6A01C700190706 /* UISearchTextField+Dumb.swift in Sources */,
|
7AC8B2762D6A01C700190706 /* UISearchTextField+Dumb.swift in Sources */,
|
||||||
7A6DD90C24335A6D009DE740 /* FlagLayer.swift in Sources */,
|
7A6DD90C24335A6D009DE740 /* FlagLayer.swift in Sources */,
|
||||||
7A2E11292CCE395300E5CA17 /* OptionalDatePicker.swift in Sources */,
|
7A2E11292CCE395300E5CA17 /* OptionalDatePicker.swift in Sources */,
|
||||||
@ -1483,6 +1501,7 @@
|
|||||||
7A7158072C44085600852088 /* OsagoScreen.swift in Sources */,
|
7A7158072C44085600852088 /* OsagoScreen.swift in Sources */,
|
||||||
7ABD1B492D044A4700B43213 /* GalleryViewModel.swift in Sources */,
|
7ABD1B492D044A4700B43213 /* GalleryViewModel.swift in Sources */,
|
||||||
7A386A442DABDC360051676A /* MapViewModel.swift in Sources */,
|
7A386A442DABDC360051676A /* MapViewModel.swift in Sources */,
|
||||||
|
7ADFC9592DAD1C3D001A43E3 /* GoogleAuthViewModel.swift in Sources */,
|
||||||
7AAAFAD32C4D0FD00050410D /* ACImageSliderView.swift in Sources */,
|
7AAAFAD32C4D0FD00050410D /* ACImageSliderView.swift in Sources */,
|
||||||
7A912F372D381B7400002938 /* LicensePlateView.swift in Sources */,
|
7A912F372D381B7400002938 /* LicensePlateView.swift in Sources */,
|
||||||
7A3F07AB24360DC800E59687 /* Dated.swift in Sources */,
|
7A3F07AB24360DC800E59687 /* Dated.swift in Sources */,
|
||||||
@ -1494,7 +1513,6 @@
|
|||||||
7A7DADAC2D99738300F52F6C /* AudioRecordView.swift in Sources */,
|
7A7DADAC2D99738300F52F6C /* AudioRecordView.swift in Sources */,
|
||||||
7A1090EC24A4E3E100B4F0B2 /* CellProgressView.swift in Sources */,
|
7A1090EC24A4E3E100B4F0B2 /* CellProgressView.swift in Sources */,
|
||||||
7AB9FE2A2D08CF35005DE374 /* EventsScreenMode.swift in Sources */,
|
7AB9FE2A2D08CF35005DE374 /* EventsScreenMode.swift in Sources */,
|
||||||
7A96AE2D246B2B7400297C33 /* GoogleSignInController.swift in Sources */,
|
|
||||||
7A10227B2C557EE900B84627 /* LocationPickerCoordinator.swift in Sources */,
|
7A10227B2C557EE900B84627 /* LocationPickerCoordinator.swift in Sources */,
|
||||||
7AB490292D6B1217002F39C6 /* ACKeyboardView.swift in Sources */,
|
7AB490292D6B1217002F39C6 /* ACKeyboardView.swift in Sources */,
|
||||||
7A11471623FDEB2A00B424AF /* MainSplitController.swift in Sources */,
|
7A11471623FDEB2A00B424AF /* MainSplitController.swift in Sources */,
|
||||||
@ -1505,6 +1523,7 @@
|
|||||||
7AF231932DA1C28100AE5EB3 /* AuthScreen.swift in Sources */,
|
7AF231932DA1C28100AE5EB3 /* AuthScreen.swift in Sources */,
|
||||||
7A1E78F82CE900440004B740 /* ReportViewModel.swift in Sources */,
|
7A1E78F82CE900440004B740 /* ReportViewModel.swift in Sources */,
|
||||||
7A10226E2C551EE000B84627 /* LocationEditViewModel.swift in Sources */,
|
7A10226E2C551EE000B84627 /* LocationEditViewModel.swift in Sources */,
|
||||||
|
7ADFC95B2DAD1F45001A43E3 /* WebView.swift in Sources */,
|
||||||
7AB4902B2D6B1446002F39C6 /* ACKeyboardButton.swift in Sources */,
|
7AB4902B2D6B1446002F39C6 /* ACKeyboardButton.swift in Sources */,
|
||||||
7AFBE8CE2C308B53003C491D /* ACMessageView.swift in Sources */,
|
7AFBE8CE2C308B53003C491D /* ACMessageView.swift in Sources */,
|
||||||
7A14416C2C297F2100E79018 /* NotesCoordinator.swift in Sources */,
|
7A14416C2C297F2100E79018 /* NotesCoordinator.swift in Sources */,
|
||||||
@ -1582,6 +1601,7 @@
|
|||||||
7A6B65B32CFB0DB500AABA6B /* NullifyDate.swift in Sources */,
|
7A6B65B32CFB0DB500AABA6B /* NullifyDate.swift in Sources */,
|
||||||
7A7097C22C9EC139007CFDCA /* ServiceContainer.swift in Sources */,
|
7A7097C22C9EC139007CFDCA /* ServiceContainer.swift in Sources */,
|
||||||
7A7AA2C42DA2A3CB00276D83 /* LocationError.swift in Sources */,
|
7A7AA2C42DA2A3CB00276D83 /* LocationError.swift in Sources */,
|
||||||
|
7AEAA2A12DAD9C00009954F0 /* TokenResponse.swift in Sources */,
|
||||||
7A54BFD32D43B95E00176D6D /* DbUpdatePolicy.swift in Sources */,
|
7A54BFD32D43B95E00176D6D /* DbUpdatePolicy.swift in Sources */,
|
||||||
7A5D84BE2C1AE44700C2209B /* VehiclePhoto.swift in Sources */,
|
7A5D84BE2C1AE44700C2209B /* VehiclePhoto.swift in Sources */,
|
||||||
7A64A2262C1A32C800284124 /* AudioRecordDto.swift in Sources */,
|
7A64A2262C1A32C800284124 /* AudioRecordDto.swift in Sources */,
|
||||||
|
|||||||
@ -3,60 +3,9 @@
|
|||||||
<device id="retina4_7" orientation="portrait" appearance="dark"/>
|
<device id="retina4_7" orientation="portrait" appearance="dark"/>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="23721"/>
|
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="23721"/>
|
||||||
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
|
||||||
<capability name="System colors in document resources" minToolsVersion="11.0"/>
|
|
||||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<scenes>
|
<scenes>
|
||||||
<!--Google Sign In Controller-->
|
|
||||||
<scene sceneID="ztj-pr-ty7">
|
|
||||||
<objects>
|
|
||||||
<viewController storyboardIdentifier="GoogleSignInController" id="Ptg-6q-3w6" customClass="GoogleSignInController" customModule="AutoCat" customModuleProvider="target" sceneMemberID="viewController">
|
|
||||||
<view key="view" contentMode="scaleToFill" id="NtL-RA-Nxs">
|
|
||||||
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
|
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
|
||||||
<subviews>
|
|
||||||
<wkWebView contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="0QS-UT-hbi">
|
|
||||||
<rect key="frame" x="0.0" y="64" width="375" height="603"/>
|
|
||||||
<color key="backgroundColor" red="0.36078431370000003" green="0.38823529410000002" blue="0.4039215686" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
|
||||||
<wkWebViewConfiguration key="configuration">
|
|
||||||
<audiovisualMediaTypes key="mediaTypesRequiringUserActionForPlayback" none="YES"/>
|
|
||||||
<wkPreferences key="preferences"/>
|
|
||||||
</wkWebViewConfiguration>
|
|
||||||
</wkWebView>
|
|
||||||
<navigationBar contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="AMg-mc-MMG">
|
|
||||||
<rect key="frame" x="0.0" y="20" width="375" height="44"/>
|
|
||||||
<items>
|
|
||||||
<navigationItem id="fZb-kM-9an">
|
|
||||||
<barButtonItem key="rightBarButtonItem" title="Close" id="ZHH-OZ-vHc">
|
|
||||||
<connections>
|
|
||||||
<action selector="close:" destination="Ptg-6q-3w6" id="VVY-eV-Yeg"/>
|
|
||||||
</connections>
|
|
||||||
</barButtonItem>
|
|
||||||
</navigationItem>
|
|
||||||
</items>
|
|
||||||
</navigationBar>
|
|
||||||
</subviews>
|
|
||||||
<viewLayoutGuide key="safeArea" id="4cf-6q-b5U"/>
|
|
||||||
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
|
|
||||||
<constraints>
|
|
||||||
<constraint firstItem="0QS-UT-hbi" firstAttribute="top" secondItem="AMg-mc-MMG" secondAttribute="bottom" id="1l8-UT-leW"/>
|
|
||||||
<constraint firstItem="AMg-mc-MMG" firstAttribute="top" secondItem="4cf-6q-b5U" secondAttribute="top" id="50U-IM-aiw"/>
|
|
||||||
<constraint firstItem="AMg-mc-MMG" firstAttribute="leading" secondItem="4cf-6q-b5U" secondAttribute="leading" id="9Si-sE-9y6"/>
|
|
||||||
<constraint firstItem="AMg-mc-MMG" firstAttribute="trailing" secondItem="4cf-6q-b5U" secondAttribute="trailing" id="DuZ-iN-C4K"/>
|
|
||||||
<constraint firstItem="0QS-UT-hbi" firstAttribute="leading" secondItem="4cf-6q-b5U" secondAttribute="leading" id="RKF-L4-hnY"/>
|
|
||||||
<constraint firstItem="0QS-UT-hbi" firstAttribute="trailing" secondItem="4cf-6q-b5U" secondAttribute="trailing" id="gBv-r4-tWa"/>
|
|
||||||
<constraint firstItem="0QS-UT-hbi" firstAttribute="bottom" secondItem="4cf-6q-b5U" secondAttribute="bottom" id="sYj-Jg-IMn"/>
|
|
||||||
</constraints>
|
|
||||||
</view>
|
|
||||||
<connections>
|
|
||||||
<outlet property="webView" destination="0QS-UT-hbi" id="vZb-CE-W3J"/>
|
|
||||||
</connections>
|
|
||||||
</viewController>
|
|
||||||
<placeholder placeholderIdentifier="IBFirstResponder" id="WxN-oK-U9s" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
|
|
||||||
</objects>
|
|
||||||
<point key="canvasLocation" x="1823" y="143"/>
|
|
||||||
</scene>
|
|
||||||
<!--Main Tab Controller-->
|
<!--Main Tab Controller-->
|
||||||
<scene sceneID="YhQ-kn-py3">
|
<scene sceneID="YhQ-kn-py3">
|
||||||
<objects>
|
<objects>
|
||||||
@ -84,9 +33,4 @@
|
|||||||
<point key="canvasLocation" x="199" y="143"/>
|
<point key="canvasLocation" x="199" y="143"/>
|
||||||
</scene>
|
</scene>
|
||||||
</scenes>
|
</scenes>
|
||||||
<resources>
|
|
||||||
<systemColor name="systemBackgroundColor">
|
|
||||||
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
|
|
||||||
</systemColor>
|
|
||||||
</resources>
|
|
||||||
</document>
|
</document>
|
||||||
|
|||||||
@ -1,108 +0,0 @@
|
|||||||
import UIKit
|
|
||||||
import WebKit
|
|
||||||
import CommonCrypto
|
|
||||||
import PKHUD
|
|
||||||
import AutoCatCore
|
|
||||||
|
|
||||||
struct TokenResponse: Codable {
|
|
||||||
var id_token: String
|
|
||||||
var refresh_token: String?
|
|
||||||
var access_token: String
|
|
||||||
var expires_in: Int
|
|
||||||
var token_type: String
|
|
||||||
var scope: String
|
|
||||||
}
|
|
||||||
|
|
||||||
class GoogleSignInController: UIViewController, WKNavigationDelegate {
|
|
||||||
@IBOutlet weak var webView: WKWebView!
|
|
||||||
|
|
||||||
private var codeVerifier: String = ""
|
|
||||||
public var completion: (() -> Void)?
|
|
||||||
|
|
||||||
let apiService: ApiServiceProtocol = ServiceContainer.shared.resolve(ApiServiceProtocol.self)
|
|
||||||
|
|
||||||
override func viewDidLoad() {
|
|
||||||
super.viewDidLoad()
|
|
||||||
self.webView.navigationDelegate = self
|
|
||||||
|
|
||||||
#if targetEnvironment(macCatalyst)
|
|
||||||
self.webView.customUserAgent = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_4) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.1 Safari/605.1.15"
|
|
||||||
#else
|
|
||||||
self.webView.customUserAgent = "Mozilla/5.0 (iPhone; CPU iPhone OS 13_4_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.1 Mobile/15E148 Safari/604.1"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
self.codeVerifier = UUID().uuidString
|
|
||||||
let codeChallenge = self.sha256(string: self.codeVerifier) ?? ""
|
|
||||||
|
|
||||||
let authUrlString = Constants.googleAuthURL
|
|
||||||
+ "?response_type=code"
|
|
||||||
+ "&code_challenge_method=S256"
|
|
||||||
+ "&scope=email%20profile"
|
|
||||||
+ "&redirect_uri=" + Constants.googleRedirectURL
|
|
||||||
+ "&client_id=" + Constants.fbClientId
|
|
||||||
+ "&code_challenge=" + codeChallenge
|
|
||||||
|
|
||||||
if let url = URL(string: authUrlString) {
|
|
||||||
let request = URLRequest(url: url)
|
|
||||||
self.webView.load(request)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction) async -> WKNavigationActionPolicy {
|
|
||||||
if let url = navigationAction.request.url {
|
|
||||||
if let components = URLComponents(url: url, resolvingAgainstBaseURL: false) {
|
|
||||||
if let queryItems = components.queryItems {
|
|
||||||
if let code = queryItems.first(where: { $0.name == "code" })?.value {
|
|
||||||
|
|
||||||
Task { @MainActor in
|
|
||||||
do {
|
|
||||||
let token = try await self.getToken(code: code)
|
|
||||||
await apiService.fbVerifyAssertion(provider: "google.com", idToken: token.id_token, accessToken: token.access_token)
|
|
||||||
self.dismiss(animated: true, completion: self.completion)
|
|
||||||
} catch {
|
|
||||||
HUD.flash(.labeledError(title: nil, subtitle: error.localizedDescription))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return .cancel
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return .allow
|
|
||||||
}
|
|
||||||
|
|
||||||
@IBAction func close(_ sender: UIBarButtonItem) {
|
|
||||||
self.dismiss(animated: true, completion: nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
func sha256(string: String) -> String? {
|
|
||||||
guard let data = string.data(using: .utf8) else { return nil }
|
|
||||||
|
|
||||||
var hash = [UInt8](repeating: 0, count: Int(CC_SHA256_DIGEST_LENGTH))
|
|
||||||
data.withUnsafeBytes {
|
|
||||||
_ = CC_SHA256($0.baseAddress, CC_LONG(data.count), &hash)
|
|
||||||
}
|
|
||||||
|
|
||||||
return String(data: Data(Base64FS.encode(data: hash)), encoding: .utf8)?.trimmingCharacters(in: CharacterSet(charactersIn: "="))
|
|
||||||
}
|
|
||||||
|
|
||||||
func getToken(code: String) async throws -> TokenResponse {
|
|
||||||
let tokenUrlString = Constants.googleTokenURL
|
|
||||||
+ "?grant_type=authorization_code"
|
|
||||||
+ "&code=" + code
|
|
||||||
+ "&redirect_uri=" + Constants.googleRedirectURL
|
|
||||||
+ "&client_id=" + Constants.fbClientId
|
|
||||||
+ "&code_verifier=" + self.codeVerifier
|
|
||||||
|
|
||||||
if let url = URL(string: tokenUrlString) {
|
|
||||||
var request = URLRequest(url: url)
|
|
||||||
request.httpMethod = "POST"
|
|
||||||
let (data, _) = try await URLSession.shared.data(for: request)
|
|
||||||
return try JSONDecoder().decode(TokenResponse.self, from: data)
|
|
||||||
} else {
|
|
||||||
throw NSError(domain: "", code: 0, userInfo: [NSLocalizedDescriptionKey: "Bad URL"])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
36
AutoCat/Screens/GoogleAuthScreen/GoogleAuthScreen.swift
Normal file
36
AutoCat/Screens/GoogleAuthScreen/GoogleAuthScreen.swift
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
//
|
||||||
|
// GoogleAuthScreen.swift
|
||||||
|
// AutoCat
|
||||||
|
//
|
||||||
|
// Created by Selim Mustafaev on 14.04.2025.
|
||||||
|
// Copyright © 2025 Selim Mustafaev. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import SwiftUI
|
||||||
|
import AutoCatCore
|
||||||
|
|
||||||
|
struct GoogleAuthScreen: View {
|
||||||
|
|
||||||
|
@State var viewModel = makeViewModel()
|
||||||
|
|
||||||
|
@Environment(\.dismiss) var dismiss
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
WebView(url: viewModel.url, userAgent: Constants.userAgent)
|
||||||
|
.decidePolicy { navAction in
|
||||||
|
let policy = await viewModel.decidePolicy(for: navAction)
|
||||||
|
if policy == .cancel {
|
||||||
|
dismiss()
|
||||||
|
}
|
||||||
|
return policy
|
||||||
|
}
|
||||||
|
.hud($viewModel.hud)
|
||||||
|
}
|
||||||
|
|
||||||
|
static func makeViewModel() -> GoogleAuthViewModel {
|
||||||
|
let resolver = ServiceContainer.shared
|
||||||
|
return GoogleAuthViewModel(
|
||||||
|
apiService: resolver.resolve(ApiServiceProtocol.self)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
97
AutoCat/Screens/GoogleAuthScreen/GoogleAuthViewModel.swift
Normal file
97
AutoCat/Screens/GoogleAuthScreen/GoogleAuthViewModel.swift
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
//
|
||||||
|
// GoogleAuthViewModel.swift
|
||||||
|
// AutoCat
|
||||||
|
//
|
||||||
|
// Created by Selim Mustafaev on 14.04.2025.
|
||||||
|
// Copyright © 2025 Selim Mustafaev. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import AutoCatCore
|
||||||
|
import SwiftUI
|
||||||
|
import CommonCrypto
|
||||||
|
import WebKit
|
||||||
|
|
||||||
|
@MainActor
|
||||||
|
@Observable
|
||||||
|
final class GoogleAuthViewModel: ACHudContainer {
|
||||||
|
|
||||||
|
let apiService: ApiServiceProtocol
|
||||||
|
|
||||||
|
var hud: ACHud?
|
||||||
|
let codeVerifier = UUID().uuidString
|
||||||
|
|
||||||
|
var url = URL(fileURLWithPath: "")
|
||||||
|
|
||||||
|
init(
|
||||||
|
apiService: ApiServiceProtocol
|
||||||
|
) {
|
||||||
|
self.apiService = apiService
|
||||||
|
|
||||||
|
do {
|
||||||
|
url = try makeAuthURL()
|
||||||
|
} catch {
|
||||||
|
hud = .error(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func makeAuthURL() throws -> URL {
|
||||||
|
guard let codeChallenge = sha256(string: codeVerifier) else {
|
||||||
|
throw GenericError.somethingWentWrong
|
||||||
|
}
|
||||||
|
|
||||||
|
let authUrlString = Constants.googleAuthURL
|
||||||
|
+ "?response_type=code"
|
||||||
|
+ "&code_challenge_method=S256"
|
||||||
|
+ "&scope=email%20profile"
|
||||||
|
+ "&redirect_uri=" + Constants.googleRedirectURL
|
||||||
|
+ "&client_id=" + Constants.fbClientId
|
||||||
|
+ "&code_challenge=" + codeChallenge
|
||||||
|
|
||||||
|
if let url = URL(string: authUrlString) {
|
||||||
|
return url
|
||||||
|
} else {
|
||||||
|
throw GenericError.somethingWentWrong
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func sha256(string: String) -> String? {
|
||||||
|
guard let data = string.data(using: .utf8) else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var hash = [UInt8](repeating: 0, count: Int(CC_SHA256_DIGEST_LENGTH))
|
||||||
|
data.withUnsafeBytes {
|
||||||
|
_ = CC_SHA256($0.baseAddress, CC_LONG(data.count), &hash)
|
||||||
|
}
|
||||||
|
|
||||||
|
let hashData = Data(Base64FS.encode(data: hash))
|
||||||
|
return String(data: hashData, encoding: .utf8)?
|
||||||
|
.trimmingCharacters(in: CharacterSet(charactersIn: "="))
|
||||||
|
}
|
||||||
|
|
||||||
|
func decidePolicy(for navigationAction: WKNavigationAction) async -> WKNavigationActionPolicy {
|
||||||
|
guard let url = navigationAction.request.url,
|
||||||
|
let components = URLComponents(url: url, resolvingAgainstBaseURL: false),
|
||||||
|
let queryItems = components.queryItems,
|
||||||
|
let code = queryItems.first(where: { $0.name == "code" })?.value
|
||||||
|
else {
|
||||||
|
return .allow
|
||||||
|
}
|
||||||
|
|
||||||
|
await wrapWithToast { [weak self] in
|
||||||
|
guard let self else { return }
|
||||||
|
|
||||||
|
let token = try await apiService.getToken(
|
||||||
|
code: code,
|
||||||
|
codeVerifier: codeVerifier
|
||||||
|
)
|
||||||
|
await apiService.fbVerifyAssertion(
|
||||||
|
provider: "google.com",
|
||||||
|
idToken: token.id_token,
|
||||||
|
accessToken: token.access_token
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return .cancel
|
||||||
|
}
|
||||||
|
}
|
||||||
61
AutoCat/Screens/GoogleAuthScreen/WebView.swift
Normal file
61
AutoCat/Screens/GoogleAuthScreen/WebView.swift
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
//
|
||||||
|
// WebView.swift
|
||||||
|
// AutoCat
|
||||||
|
//
|
||||||
|
// Created by Selim Mustafaev on 14.04.2025.
|
||||||
|
// Copyright © 2025 Selim Mustafaev. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import WebKit
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct WebView: UIViewRepresentable {
|
||||||
|
|
||||||
|
class Coordinator: NSObject, WKNavigationDelegate {
|
||||||
|
|
||||||
|
var decidePolicyClosure: ((WKNavigationAction) async -> WKNavigationActionPolicy)?
|
||||||
|
|
||||||
|
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction) async -> WKNavigationActionPolicy {
|
||||||
|
if let decidePolicyClosure {
|
||||||
|
return await decidePolicyClosure(navigationAction)
|
||||||
|
} else {
|
||||||
|
return .allow
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let url: URL
|
||||||
|
let userAgent: String?
|
||||||
|
|
||||||
|
@State private var delegate = Coordinator()
|
||||||
|
|
||||||
|
func makeUIView(context: Context) -> WKWebView {
|
||||||
|
|
||||||
|
let webView = WKWebView()
|
||||||
|
webView.navigationDelegate = context.coordinator
|
||||||
|
return webView
|
||||||
|
}
|
||||||
|
|
||||||
|
func updateUIView(_ webView: WKWebView, context: Context) {
|
||||||
|
|
||||||
|
webView.customUserAgent = userAgent
|
||||||
|
webView.navigationDelegate = context.coordinator
|
||||||
|
|
||||||
|
let request = URLRequest(url: url)
|
||||||
|
webView.load(request)
|
||||||
|
}
|
||||||
|
|
||||||
|
func makeCoordinator() -> Coordinator {
|
||||||
|
|
||||||
|
delegate
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension WebView {
|
||||||
|
|
||||||
|
func decidePolicy(closure: @escaping (WKNavigationAction) async -> WKNavigationActionPolicy) -> Self {
|
||||||
|
|
||||||
|
delegate.decidePolicyClosure = closure
|
||||||
|
return self
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -13,6 +13,7 @@ struct SettingsScreen: View {
|
|||||||
|
|
||||||
@State var viewModel: SettingsViewModel
|
@State var viewModel: SettingsViewModel
|
||||||
@State var googleSheetOpened = false
|
@State var googleSheetOpened = false
|
||||||
|
@State var googleLoginSheetOpened = false
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
Form {
|
Form {
|
||||||
@ -29,7 +30,7 @@ struct SettingsScreen: View {
|
|||||||
if viewModel.googleAuthorized {
|
if viewModel.googleAuthorized {
|
||||||
googleSheetOpened = true
|
googleSheetOpened = true
|
||||||
} else {
|
} else {
|
||||||
viewModel.googleSignIn()
|
googleLoginSheetOpened = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,6 +84,9 @@ struct SettingsScreen: View {
|
|||||||
Text("You are currently signed in with email \(email). It will help to gather more data about vehicles.")
|
Text("You are currently signed in with email \(email). It will help to gather more data about vehicles.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.sheet(isPresented: $googleLoginSheetOpened) {
|
||||||
|
GoogleAuthScreen()
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -82,10 +82,6 @@ class SettingsViewModel {
|
|||||||
coordinator?.openAuthScreen()
|
coordinator?.openAuthScreen()
|
||||||
}
|
}
|
||||||
|
|
||||||
func googleSignIn() {
|
|
||||||
coordinator?.openGoogleOauthPage()
|
|
||||||
}
|
|
||||||
|
|
||||||
func googleSignout() {
|
func googleSignout() {
|
||||||
settingService.user.firebaseIdToken = nil
|
settingService.user.firebaseIdToken = nil
|
||||||
settingService.user.firebaseRefreshToken = nil
|
settingService.user.firebaseRefreshToken = nil
|
||||||
|
|||||||
@ -14,6 +14,7 @@ public enum ApiError: LocalizedError, Equatable {
|
|||||||
case emptyResponse
|
case emptyResponse
|
||||||
case unauthorized
|
case unauthorized
|
||||||
case threadSafety
|
case threadSafety
|
||||||
|
case badUrl
|
||||||
case message(String)
|
case message(String)
|
||||||
case httpError(Int)
|
case httpError(Int)
|
||||||
|
|
||||||
@ -25,6 +26,7 @@ public enum ApiError: LocalizedError, Equatable {
|
|||||||
case .threadSafety: "Thread safety error"
|
case .threadSafety: "Thread safety error"
|
||||||
case .message(let message): message
|
case .message(let message): message
|
||||||
case .httpError(let status): "General http error (status \(status))"
|
case .httpError(let status): "General http error (status \(status))"
|
||||||
|
case .badUrl: "Bad url"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -193,6 +193,25 @@ public actor ApiService: ApiServiceProtocol {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public func getToken(code: String, codeVerifier: String) async throws -> TokenResponse {
|
||||||
|
|
||||||
|
let tokenUrlString = Constants.googleTokenURL
|
||||||
|
+ "?grant_type=authorization_code"
|
||||||
|
+ "&code=" + code
|
||||||
|
+ "&redirect_uri=" + Constants.googleRedirectURL
|
||||||
|
+ "&client_id=" + Constants.fbClientId
|
||||||
|
+ "&code_verifier=" + codeVerifier
|
||||||
|
|
||||||
|
if let url = URL(string: tokenUrlString) {
|
||||||
|
var request = URLRequest(url: url)
|
||||||
|
request.httpMethod = "POST"
|
||||||
|
let (data, _) = try await URLSession.shared.data(for: request)
|
||||||
|
return try JSONDecoder().decode(TokenResponse.self, from: data)
|
||||||
|
} else {
|
||||||
|
throw ApiError.badUrl
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// MARK: - AutoCat public API
|
// MARK: - AutoCat public API
|
||||||
|
|
||||||
public func login(email: String, password: String) async throws -> User {
|
public func login(email: String, password: String) async throws -> User {
|
||||||
|
|||||||
@ -34,5 +34,6 @@ public protocol ApiServiceProtocol: Sendable {
|
|||||||
|
|
||||||
func getVehicles(with filter: Filter, pageToken: String?, pageSize: Int) async throws -> PagedResponse<VehicleDto>
|
func getVehicles(with filter: Filter, pageToken: String?, pageSize: Int) async throws -> PagedResponse<VehicleDto>
|
||||||
func fbVerifyAssertion(provider: String, idToken: String, accessToken: String?) async
|
func fbVerifyAssertion(provider: String, idToken: String, accessToken: String?) async
|
||||||
|
func getToken(code: String, codeVerifier: String) async throws -> TokenResponse
|
||||||
func getReport(for number: String) async throws -> VehicleDto
|
func getReport(for number: String) async throws -> VehicleDto
|
||||||
}
|
}
|
||||||
|
|||||||
17
AutoCatCore/Services/ApiService/TokenResponse.swift
Normal file
17
AutoCatCore/Services/ApiService/TokenResponse.swift
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
//
|
||||||
|
// TokenResponse.swift
|
||||||
|
// AutoCatCore
|
||||||
|
//
|
||||||
|
// Created by Selim Mustafaev on 14.04.2025.
|
||||||
|
// Copyright © 2025 Selim Mustafaev. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
public struct TokenResponse: Codable, Sendable {
|
||||||
|
|
||||||
|
public var id_token: String
|
||||||
|
public var refresh_token: String?
|
||||||
|
public var access_token: String
|
||||||
|
public var expires_in: Int
|
||||||
|
public var token_type: String
|
||||||
|
public var scope: String
|
||||||
|
}
|
||||||
@ -52,4 +52,6 @@ public enum Constants {
|
|||||||
public static let reportLinkBaseURL = "https://auto.aliencat.pro/report.html"
|
public static let reportLinkBaseURL = "https://auto.aliencat.pro/report.html"
|
||||||
|
|
||||||
public static let audioRecordsFolder = "recordings"
|
public static let audioRecordsFolder = "recordings"
|
||||||
|
|
||||||
|
public static let userAgent = "Mozilla/5.0 (iPhone; CPU iPhone OS 18_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.4 Mobile/15E148 Safari/604.1"
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user