diff --git a/AutoCat2.xcodeproj/project.pbxproj b/AutoCat2.xcodeproj/project.pbxproj index ae79b7a..b026622 100644 --- a/AutoCat2.xcodeproj/project.pbxproj +++ b/AutoCat2.xcodeproj/project.pbxproj @@ -45,6 +45,17 @@ 7A36E56127FB5A330025AACB /* ApiMethodMockProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A558AAF27FA3CCF001A18EE /* ApiMethodMockProtocol.swift */; }; 7A36E56327FB5BEB0025AACB /* TestError.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A36E56227FB5BEB0025AACB /* TestError.swift */; }; 7A48B26727D9442A004D1A4B /* PKHUD in Frameworks */ = {isa = PBXBuildFile; productRef = 7A48B26627D9442A004D1A4B /* PKHUD */; }; + 7A4951B7288D3A6100C644B6 /* AutoCat2SUIApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A4951B6288D3A6100C644B6 /* AutoCat2SUIApp.swift */; }; + 7A4951B9288D3A6100C644B6 /* RootView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A4951B8288D3A6100C644B6 /* RootView.swift */; }; + 7A4951BB288D3A6300C644B6 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 7A4951BA288D3A6300C644B6 /* Assets.xcassets */; }; + 7A4951BF288D3A6300C644B6 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 7A4951BE288D3A6300C644B6 /* Preview Assets.xcassets */; }; + 7A4951C5288D3BCF00C644B6 /* AuthView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A4951C4288D3BCF00C644B6 /* AuthView.swift */; }; + 7A4951C7288D3BDD00C644B6 /* MainView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A4951C6288D3BDD00C644B6 /* MainView.swift */; }; + 7A4951C8288D3BFA00C644B6 /* AutoCatCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7A49F4D727D4064500AEAAE0 /* AutoCatCore.framework */; }; + 7A4951C9288D3BFA00C644B6 /* AutoCatCore.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 7A49F4D727D4064500AEAAE0 /* AutoCatCore.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 7A4951D1288D5C4300C644B6 /* ACProgressView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A4951D0288D5C4300C644B6 /* ACProgressView.swift */; }; + 7A4951D3288D5E2800C644B6 /* AuthVM.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A4951D2288D5E2800C644B6 /* AuthVM.swift */; }; + 7A4951D5288D5ED000C644B6 /* Alert.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A4951D4288D5ED000C644B6 /* Alert.swift */; }; 7A49F4A327D4061900AEAAE0 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A49F4A227D4061900AEAAE0 /* AppDelegate.swift */; }; 7A49F4A527D4061900AEAAE0 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A49F4A427D4061900AEAAE0 /* SceneDelegate.swift */; }; 7A49F4A727D4061900AEAAE0 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A49F4A627D4061900AEAAE0 /* ViewController.swift */; }; @@ -113,6 +124,13 @@ remoteGlobalIDString = 7A49F4D627D4064500AEAAE0; remoteInfo = AutoCatCore; }; + 7A4951CA288D3BFA00C644B6 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 7A49F49727D4061900AEAAE0 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 7A49F4D627D4064500AEAAE0; + remoteInfo = AutoCatCore; + }; 7A49F4B627D4061B00AEAAE0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 7A49F49727D4061900AEAAE0 /* Project object */; @@ -162,6 +180,17 @@ name = "Embed Frameworks"; runOnlyForDeploymentPostprocessing = 0; }; + 7A4951CC288D3BFA00C644B6 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + 7A4951C9288D3BFA00C644B6 /* AutoCatCore.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; 7A49F4F127D4064500AEAAE0 /* Embed Frameworks */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; @@ -203,6 +232,17 @@ 7A2B6CD527FCEC8600519F1E /* XCUIApplication.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = XCUIApplication.swift; sourceTree = ""; }; 7A36E55B27FB55570025AACB /* Testing.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Testing.swift; sourceTree = ""; }; 7A36E56227FB5BEB0025AACB /* TestError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TestError.swift; sourceTree = ""; }; + 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 = ""; }; + 7A4951B8288D3A6100C644B6 /* RootView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RootView.swift; sourceTree = ""; }; + 7A4951BA288D3A6300C644B6 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 7A4951BC288D3A6300C644B6 /* AutoCat2SUI.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = AutoCat2SUI.entitlements; sourceTree = ""; }; + 7A4951BE288D3A6300C644B6 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; + 7A4951C4288D3BCF00C644B6 /* AuthView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthView.swift; sourceTree = ""; }; + 7A4951C6288D3BDD00C644B6 /* MainView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainView.swift; sourceTree = ""; }; + 7A4951D0288D5C4300C644B6 /* ACProgressView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ACProgressView.swift; sourceTree = ""; }; + 7A4951D2288D5E2800C644B6 /* AuthVM.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthVM.swift; sourceTree = ""; }; + 7A4951D4288D5ED000C644B6 /* Alert.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Alert.swift; sourceTree = ""; }; 7A49F49F27D4061900AEAAE0 /* AutoCat2.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = AutoCat2.app; sourceTree = BUILT_PRODUCTS_DIR; }; 7A49F4A227D4061900AEAAE0 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 7A49F4A427D4061900AEAAE0 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; @@ -272,6 +312,14 @@ /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ + 7A4951B1288D3A6100C644B6 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 7A4951C8288D3BFA00C644B6 /* AutoCatCore.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 7A49F49C27D4061900AEAAE0 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -431,6 +479,71 @@ path = Testing; sourceTree = ""; }; + 7A4951B5288D3A6100C644B6 /* AutoCat2SUI */ = { + isa = PBXGroup; + children = ( + 7A4951B6288D3A6100C644B6 /* AutoCat2SUIApp.swift */, + 7A4951D6288D5EE700C644B6 /* Extensions */, + 7A4951CF288D5C2100C644B6 /* Views */, + 7A4951C3288D3AF000C644B6 /* Screens */, + 7A4951BA288D3A6300C644B6 /* Assets.xcassets */, + 7A4951BC288D3A6300C644B6 /* AutoCat2SUI.entitlements */, + 7A4951BD288D3A6300C644B6 /* Preview Content */, + ); + path = AutoCat2SUI; + sourceTree = ""; + }; + 7A4951BD288D3A6300C644B6 /* Preview Content */ = { + isa = PBXGroup; + children = ( + 7A4951BE288D3A6300C644B6 /* Preview Assets.xcassets */, + ); + path = "Preview Content"; + sourceTree = ""; + }; + 7A4951C3288D3AF000C644B6 /* Screens */ = { + isa = PBXGroup; + children = ( + 7A4951CE288D5C1300C644B6 /* Main */, + 7A4951CD288D5C0800C644B6 /* Auth */, + ); + path = Screens; + sourceTree = ""; + }; + 7A4951CD288D5C0800C644B6 /* Auth */ = { + isa = PBXGroup; + children = ( + 7A4951C4288D3BCF00C644B6 /* AuthView.swift */, + 7A4951D2288D5E2800C644B6 /* AuthVM.swift */, + ); + path = Auth; + sourceTree = ""; + }; + 7A4951CE288D5C1300C644B6 /* Main */ = { + isa = PBXGroup; + children = ( + 7A4951C6288D3BDD00C644B6 /* MainView.swift */, + ); + path = Main; + sourceTree = ""; + }; + 7A4951CF288D5C2100C644B6 /* Views */ = { + isa = PBXGroup; + children = ( + 7A4951B8288D3A6100C644B6 /* RootView.swift */, + 7A4951D0288D5C4300C644B6 /* ACProgressView.swift */, + ); + path = Views; + sourceTree = ""; + }; + 7A4951D6288D5EE700C644B6 /* Extensions */ = { + isa = PBXGroup; + children = ( + 7A4951D4288D5ED000C644B6 /* Alert.swift */, + ); + path = Extensions; + sourceTree = ""; + }; 7A49F49627D4061900AEAAE0 = { isa = PBXGroup; children = ( @@ -440,6 +553,7 @@ 7A49F4D827D4064500AEAAE0 /* AutoCatCore */, 7A49F4E627D4064500AEAAE0 /* AutoCatCoreTests */, 7A9FD4052857AF590057ECFA /* AutoCat2Mac */, + 7A4951B5288D3A6100C644B6 /* AutoCat2SUI */, 7A49F4A027D4061900AEAAE0 /* Products */, 7A9FD4132857AF860057ECFA /* Frameworks */, ); @@ -454,6 +568,7 @@ 7A49F4D727D4064500AEAAE0 /* AutoCatCore.framework */, 7A49F4E027D4064500AEAAE0 /* AutoCatCoreTests.xctest */, 7A9FD4042857AF590057ECFA /* AutoCat2Mac.app */, + 7A4951B4288D3A6100C644B6 /* AutoCat2SUI.app */, ); name = Products; sourceTree = ""; @@ -695,6 +810,25 @@ /* End PBXHeadersBuildPhase section */ /* Begin PBXNativeTarget section */ + 7A4951B3288D3A6100C644B6 /* AutoCat2SUI */ = { + isa = PBXNativeTarget; + buildConfigurationList = 7A4951C0288D3A6300C644B6 /* Build configuration list for PBXNativeTarget "AutoCat2SUI" */; + buildPhases = ( + 7A4951B0288D3A6100C644B6 /* Sources */, + 7A4951B1288D3A6100C644B6 /* Frameworks */, + 7A4951B2288D3A6100C644B6 /* Resources */, + 7A4951CC288D3BFA00C644B6 /* Embed Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 7A4951CB288D3BFA00C644B6 /* PBXTargetDependency */, + ); + name = AutoCat2SUI; + productName = AutoCat2SUI; + productReference = 7A4951B4288D3A6100C644B6 /* AutoCat2SUI.app */; + productType = "com.apple.product-type.application"; + }; 7A49F49E27D4061900AEAAE0 /* AutoCat2 */ = { isa = PBXNativeTarget; buildConfigurationList = 7A49F4C927D4061B00AEAAE0 /* Build configuration list for PBXNativeTarget "AutoCat2" */; @@ -825,9 +959,12 @@ isa = PBXProject; attributes = { BuildIndependentTargetsInParallel = 1; - LastSwiftUpdateCheck = 1340; + LastSwiftUpdateCheck = 1400; LastUpgradeCheck = 1400; TargetAttributes = { + 7A4951B3288D3A6100C644B6 = { + CreatedOnToolsVersion = 14.0; + }; 7A49F49E27D4061900AEAAE0 = { CreatedOnToolsVersion = 13.2.1; }; @@ -877,11 +1014,21 @@ 7A49F4D627D4064500AEAAE0 /* AutoCatCore */, 7A49F4DF27D4064500AEAAE0 /* AutoCatCoreTests */, 7A9FD4032857AF590057ECFA /* AutoCat2Mac */, + 7A4951B3288D3A6100C644B6 /* AutoCat2SUI */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ + 7A4951B2288D3A6100C644B6 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 7A4951BF288D3A6300C644B6 /* Preview Assets.xcassets in Resources */, + 7A4951BB288D3A6300C644B6 /* Assets.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 7A49F49D27D4061900AEAAE0 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -936,6 +1083,20 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ + 7A4951B0288D3A6100C644B6 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 7A4951D3288D5E2800C644B6 /* AuthVM.swift in Sources */, + 7A4951B9288D3A6100C644B6 /* RootView.swift in Sources */, + 7A4951C7288D3BDD00C644B6 /* MainView.swift in Sources */, + 7A4951B7288D3A6100C644B6 /* AutoCat2SUIApp.swift in Sources */, + 7A4951D1288D5C4300C644B6 /* ACProgressView.swift in Sources */, + 7A4951C5288D3BCF00C644B6 /* AuthView.swift in Sources */, + 7A4951D5288D5ED000C644B6 /* Alert.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 7A49F49B27D4061900AEAAE0 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -1061,6 +1222,11 @@ target = 7A49F4D627D4064500AEAAE0 /* AutoCatCore */; targetProxy = 7A0391D8285933EF000EE522 /* PBXContainerItemProxy */; }; + 7A4951CB288D3BFA00C644B6 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 7A49F4D627D4064500AEAAE0 /* AutoCatCore */; + targetProxy = 7A4951CA288D3BFA00C644B6 /* PBXContainerItemProxy */; + }; 7A49F4B727D4061B00AEAAE0 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 7A49F49E27D4061900AEAAE0 /* AutoCat2 */; @@ -1116,6 +1282,84 @@ /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ + 7A4951C1288D3A6300C644B6 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CODE_SIGN_ENTITLEMENTS = AutoCat2SUI/AutoCat2SUI.entitlements; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_ASSET_PATHS = "\"AutoCat2SUI/Preview Content\""; + DEVELOPMENT_TEAM = 46DTTB8X4S; + ENABLE_HARDENED_RUNTIME = YES; + ENABLE_PREVIEWS = YES; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_KEY_CFBundleDisplayName = AutoCat2; + INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.productivity"; + "INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphoneos*]" = YES; + "INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphonesimulator*]" = YES; + "INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents[sdk=iphoneos*]" = YES; + "INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents[sdk=iphonesimulator*]" = YES; + "INFOPLIST_KEY_UILaunchScreen_Generation[sdk=iphoneos*]" = YES; + "INFOPLIST_KEY_UILaunchScreen_Generation[sdk=iphonesimulator*]" = YES; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + IPHONEOS_DEPLOYMENT_TARGET = 16.0; + LD_RUNPATH_SEARCH_PATHS = "@executable_path/Frameworks"; + "LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks"; + MACOSX_DEPLOYMENT_TARGET = 12.4; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = pro.aliencat.AutoCat2SUI; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = auto; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx"; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 7A4951C2288D3A6300C644B6 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CODE_SIGN_ENTITLEMENTS = AutoCat2SUI/AutoCat2SUI.entitlements; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_ASSET_PATHS = "\"AutoCat2SUI/Preview Content\""; + DEVELOPMENT_TEAM = 46DTTB8X4S; + ENABLE_HARDENED_RUNTIME = YES; + ENABLE_PREVIEWS = YES; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_KEY_CFBundleDisplayName = AutoCat2; + INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.productivity"; + "INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphoneos*]" = YES; + "INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphonesimulator*]" = YES; + "INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents[sdk=iphoneos*]" = YES; + "INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents[sdk=iphonesimulator*]" = YES; + "INFOPLIST_KEY_UILaunchScreen_Generation[sdk=iphoneos*]" = YES; + "INFOPLIST_KEY_UILaunchScreen_Generation[sdk=iphonesimulator*]" = YES; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + IPHONEOS_DEPLOYMENT_TARGET = 16.0; + LD_RUNPATH_SEARCH_PATHS = "@executable_path/Frameworks"; + "LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks"; + MACOSX_DEPLOYMENT_TARGET = 12.4; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = pro.aliencat.AutoCat2SUI; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = auto; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx"; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; 7A49F4C727D4061B00AEAAE0 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -1489,6 +1733,7 @@ DEVELOPMENT_TEAM = 46DTTB8X4S; ENABLE_HARDENED_RUNTIME = YES; GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_KEY_CFBundleDisplayName = AutoCat2; INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities"; INFOPLIST_KEY_NSHumanReadableCopyright = ""; INFOPLIST_KEY_NSMainStoryboardFile = Main; @@ -1522,6 +1767,7 @@ DEVELOPMENT_TEAM = 46DTTB8X4S; ENABLE_HARDENED_RUNTIME = YES; GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_KEY_CFBundleDisplayName = AutoCat2; INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities"; INFOPLIST_KEY_NSHumanReadableCopyright = ""; INFOPLIST_KEY_NSMainStoryboardFile = Main; @@ -1543,6 +1789,15 @@ /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ + 7A4951C0288D3A6300C644B6 /* Build configuration list for PBXNativeTarget "AutoCat2SUI" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 7A4951C1288D3A6300C644B6 /* Debug */, + 7A4951C2288D3A6300C644B6 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; 7A49F49A27D4061900AEAAE0 /* Build configuration list for PBXProject "AutoCat2" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/AutoCat2.xcodeproj/xcuserdata/selim.xcuserdatad/xcschemes/xcschememanagement.plist b/AutoCat2.xcodeproj/xcuserdata/selim.xcuserdatad/xcschemes/xcschememanagement.plist index 2dd8bc0..aecfc2a 100644 --- a/AutoCat2.xcodeproj/xcuserdata/selim.xcuserdatad/xcschemes/xcschememanagement.plist +++ b/AutoCat2.xcodeproj/xcuserdata/selim.xcuserdatad/xcschemes/xcschememanagement.plist @@ -19,6 +19,11 @@ orderHint 1 + AutoCat2SUI.xcscheme_^#shared#^_ + + orderHint + 2 + AutoCat2UITests.testExample.xcscheme isShown diff --git a/AutoCat2Mac/Base.lproj/Main.storyboard b/AutoCat2Mac/Base.lproj/Main.storyboard index 686d5a3..e308e66 100644 --- a/AutoCat2Mac/Base.lproj/Main.storyboard +++ b/AutoCat2Mac/Base.lproj/Main.storyboard @@ -1,8 +1,8 @@ - + - + @@ -852,13 +852,13 @@ Gw - + - + - + diff --git a/AutoCat2SUI/Assets.xcassets/AccentColor.colorset/Contents.json b/AutoCat2SUI/Assets.xcassets/AccentColor.colorset/Contents.json new file mode 100644 index 0000000..eb87897 --- /dev/null +++ b/AutoCat2SUI/Assets.xcassets/AccentColor.colorset/Contents.json @@ -0,0 +1,11 @@ +{ + "colors" : [ + { + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AutoCat2SUI/Assets.xcassets/AppIcon.appiconset/Contents.json b/AutoCat2SUI/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..532cd72 --- /dev/null +++ b/AutoCat2SUI/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,63 @@ +{ + "images" : [ + { + "idiom" : "universal", + "platform" : "ios", + "size" : "1024x1024" + }, + { + "idiom" : "mac", + "scale" : "1x", + "size" : "16x16" + }, + { + "idiom" : "mac", + "scale" : "2x", + "size" : "16x16" + }, + { + "idiom" : "mac", + "scale" : "1x", + "size" : "32x32" + }, + { + "idiom" : "mac", + "scale" : "2x", + "size" : "32x32" + }, + { + "idiom" : "mac", + "scale" : "1x", + "size" : "128x128" + }, + { + "idiom" : "mac", + "scale" : "2x", + "size" : "128x128" + }, + { + "idiom" : "mac", + "scale" : "1x", + "size" : "256x256" + }, + { + "idiom" : "mac", + "scale" : "2x", + "size" : "256x256" + }, + { + "idiom" : "mac", + "scale" : "1x", + "size" : "512x512" + }, + { + "idiom" : "mac", + "scale" : "2x", + "size" : "512x512" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AutoCat2SUI/Assets.xcassets/Contents.json b/AutoCat2SUI/Assets.xcassets/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/AutoCat2SUI/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AutoCat2SUI/AutoCat2SUI.entitlements b/AutoCat2SUI/AutoCat2SUI.entitlements new file mode 100644 index 0000000..f2ef3ae --- /dev/null +++ b/AutoCat2SUI/AutoCat2SUI.entitlements @@ -0,0 +1,10 @@ + + + + + com.apple.security.app-sandbox + + com.apple.security.files.user-selected.read-only + + + diff --git a/AutoCat2SUI/AutoCat2SUIApp.swift b/AutoCat2SUI/AutoCat2SUIApp.swift new file mode 100644 index 0000000..155972b --- /dev/null +++ b/AutoCat2SUI/AutoCat2SUIApp.swift @@ -0,0 +1,43 @@ +// +// AutoCat2SUIApp.swift +// AutoCat2SUI +// +// Created by Selim Mustafaev on 24.07.2022. +// + +import SwiftUI +import AutoCatCore + +@main +struct AutoCat2SUIApp: App { + + let storageService = StorageService.sharedNotWait + + var body: some Scene { + WindowGroup { + if Testing.isUITesting { + RootView(settings: getTestSettings()) + .environment(\.managedObjectContext, storageService.context) + } else { + RootView(settings: getSettings()) + .environment(\.managedObjectContext, storageService.context) + } + } + } + + func getTestSettings() -> TestSettings { + guard let settings = Settings.shared as? TestSettings else { + fatalError("Error getting settings") + } + + return settings + } + + func getSettings() -> Settings { + guard let settings = Settings.shared as? Settings else { + fatalError("Error getting settings") + } + + return settings + } +} diff --git a/AutoCat2SUI/Extensions/Alert.swift b/AutoCat2SUI/Extensions/Alert.swift new file mode 100644 index 0000000..7736d5e --- /dev/null +++ b/AutoCat2SUI/Extensions/Alert.swift @@ -0,0 +1,34 @@ +// +// Alert.swift +// AutoCat2SUI +// +// Created by Selim Mustafaev on 24.07.2022. +// + +import SwiftUI + +enum AlertMessage: Identifiable { + case info(title: String, body: String) + case error(error: Error) + + var id: Int { + switch self { + case .info(let title, let body): + return title.hashValue + body.hashValue + case .error(let error): + return error.localizedDescription.hashValue + } + } +} + +extension Alert { + init(_ message: AlertMessage) { + switch message { + case .info(let title, let body): + self.init(title: Text(title), message: Text(body)) + case .error(let error): + //let msg = (error as NSError).displayMessage + self.init(title: Text(""), message: Text(error.localizedDescription)) + } + } +} diff --git a/AutoCat2SUI/Preview Content/Preview Assets.xcassets/Contents.json b/AutoCat2SUI/Preview Content/Preview Assets.xcassets/Contents.json new file mode 100644 index 0000000..73c0059 --- /dev/null +++ b/AutoCat2SUI/Preview Content/Preview Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AutoCat2SUI/Screens/Auth/AuthVM.swift b/AutoCat2SUI/Screens/Auth/AuthVM.swift new file mode 100644 index 0000000..b4c8a28 --- /dev/null +++ b/AutoCat2SUI/Screens/Auth/AuthVM.swift @@ -0,0 +1,25 @@ +// +// AuthVM.swift +// AutoCat2SUI +// +// Created by Selim Mustafaev on 24.07.2022. +// + +import AutoCatCore + +public class AuthVM: ObservableObject { + + private let api: ApiProtocol + private var settings: any SettingsProtocol + + init(api: ApiProtocol = Api.shared, settings: any SettingsProtocol = Settings.shared) { + + self.api = api + self.settings = settings + } + + @MainActor + public func login(user: String, password: String) async throws { + settings.user = try await api.login(email: user, password: password) + } +} diff --git a/AutoCat2SUI/Screens/Auth/AuthView.swift b/AutoCat2SUI/Screens/Auth/AuthView.swift new file mode 100644 index 0000000..831266b --- /dev/null +++ b/AutoCat2SUI/Screens/Auth/AuthView.swift @@ -0,0 +1,72 @@ +// +// AuthView.swift +// AutoCat2SUI +// +// Created by Selim Mustafaev on 24.07.2022. +// + +import SwiftUI + +struct AuthView: View { + + enum Field { + case email + case password + } + + @ObservedObject var viewModel = AuthVM() + + @State private var login: String = "" + @State private var password: String = "" + @State private var showProgress: Bool = false + @State private var alert: AlertMessage? = nil + @FocusState private var focus: Field? + + var body: some View { + ZStack { + VStack(alignment: .center, spacing: 16) { + Spacer() + #if os(iOS) + TextField("Login", text: $login) + .focused($focus, equals: .email) + .textContentType(.emailAddress) + .keyboardType(.emailAddress) + #else + TextField("Login", text: $login) + .focused($focus, equals: .email) + #endif + SecureField("Password", text: $password) + .focused($focus, equals: .password) + Button("Login") { + Task.init { + do { + self.focus = nil + self.showProgress = true + try await self.viewModel.login(user: self.login, password: self.password) + self.showProgress = false + } catch { + self.showProgress = false + self.alert = .error(error: error) + } + } + } + .alert(item: $alert, content: Alert.init) + Spacer() + } + .buttonStyle(.bordered) + .controlSize(.large) + .textFieldStyle(.roundedBorder) + .padding(20) + + if self.showProgress { + ACProgressView() + } + } + } +} + +struct AuthView_Previews: PreviewProvider { + static var previews: some View { + AuthView() + } +} diff --git a/AutoCat2SUI/Screens/Main/MainView.swift b/AutoCat2SUI/Screens/Main/MainView.swift new file mode 100644 index 0000000..1e72e0f --- /dev/null +++ b/AutoCat2SUI/Screens/Main/MainView.swift @@ -0,0 +1,59 @@ +// +// MainView.swift +// AutoCat2SUI +// +// Created by Selim Mustafaev on 24.07.2022. +// + +import SwiftUI +import AutoCatCore + +struct MainView: View { + + @FetchRequest(entity: CDVehicle.entity(), sortDescriptors: []) var vehicles: FetchedResults + + @State private var selectedFilter: Filter? + + private var historyFilters: [Filter] = [ + .allLocal, + .unrecognized, + .outdated + ] + + private var remoteFilters: [Filter] = [ + .allRemote + ] + + var body: some View { + NavigationSplitView { + List(selection: $selectedFilter) { + Section("History") { + ForEach(historyFilters) { filter in + NavigationLink(value: filter) { + Label(filter.name, image: filter.iconName) + } + } + } + + Section("Remote") { + ForEach(remoteFilters) { filter in + NavigationLink(value: filter) { + Label(filter.name, image: filter.iconName) + } + } + } + } + } content: { + Text("Content") + } detail: { + Text("Detail") + } + + } +} + +struct MainView_Previews: PreviewProvider { + static var previews: some View { + MainView() + } +} diff --git a/AutoCat2SUI/Views/ACProgressView.swift b/AutoCat2SUI/Views/ACProgressView.swift new file mode 100644 index 0000000..55582e9 --- /dev/null +++ b/AutoCat2SUI/Views/ACProgressView.swift @@ -0,0 +1,76 @@ +// +// ACProgressView.swift +// AutoCat2SUI +// +// Created by Selim Mustafaev on 24.07.2022. +// + +import SwiftUI + +struct ACProgressView: View { + + @State var isDeterminate: Bool = false + @State var progress: CGFloat = 0 + @State var text: String? = nil + @State var isAnimating: Bool = false + + var body: some View { + ZStack(alignment: .center) { + Color.black.opacity(0.4) + VStack { + VStack(spacing: 24) { + if self.isDeterminate { + ZStack { + Circle() + .stroke(Color.secondary.opacity(0.2), style: StrokeStyle(lineWidth: 4)) + .frame(width: 100, height: 100) + Circle() + .trim(from: 0, to: self.progress) + .stroke(Color.blue, style: StrokeStyle(lineWidth: 4)) + .rotationEffect(.degrees(-90)) + .frame(width: 100, height: 100) + Text("\(Int(self.progress*100)) %") + } + } else { + let gradient = AngularGradient( + gradient: Gradient(colors: [Color.blue, Color.blue.opacity(0.01)]), + center: .center, + startAngle: .degrees(360), + endAngle: .degrees(0)) + Circle() + .stroke(gradient, style: StrokeStyle(lineWidth: 4)) + .rotationEffect(Angle(degrees: self.isAnimating ? 360 : 0)) + .onAppear { + withAnimation(.linear(duration: 1).repeatForever(autoreverses: false)) { + self.isAnimating = true + } + } + .onDisappear(perform: { + self.isAnimating = false + }) + .frame(width: 100, height: 100) + } + + if let msg = self.text { + Text(msg) + } + } + .padding(28) + } + //.frame(width: 160, height: 160) + .background(.regularMaterial) + .cornerRadius(20) + } + .edgesIgnoringSafeArea(.all) + } +} + +struct ACProgressView_Previews: PreviewProvider { + static var previews: some View { + Group { + ACProgressView() + ACProgressView(isDeterminate: true, progress: 0.3, text: "Loading...") + .preferredColorScheme(.dark) + } + } +} diff --git a/AutoCat2SUI/Views/RootView.swift b/AutoCat2SUI/Views/RootView.swift new file mode 100644 index 0000000..41018c1 --- /dev/null +++ b/AutoCat2SUI/Views/RootView.swift @@ -0,0 +1,32 @@ +// +// ContentView.swift +// AutoCat2SUI +// +// Created by Selim Mustafaev on 24.07.2022. +// + +import SwiftUI +import AutoCatCore + +struct RootView: View where T: SettingsProtocol { + + @ObservedObject var settings: T + + init(settings: T) { + self.settings = settings + } + + var body: some View { + if settings.user.token.isEmpty { + AuthView() + } else { + MainView() + } + } +} + +struct RootView_Previews: PreviewProvider { + static var previews: some View { + RootView(settings: Settings()) + } +} diff --git a/AutoCatCore/Models/Filter.swift b/AutoCatCore/Models/Filter.swift index bab5de5..72a1945 100644 --- a/AutoCatCore/Models/Filter.swift +++ b/AutoCatCore/Models/Filter.swift @@ -7,17 +7,82 @@ import Foundation -public enum DataSource { +public enum DataSource: CaseIterable, Identifiable { case local case remote -} - -public class Filter { - var dataSource: DataSource = .remote + public var id: String { + return name + } - public init(dataSource: DataSource) { - self.dataSource = dataSource + public var name: String { + switch self { + case .local: + return "Local" + case .remote: + return "Remote" + } + } +} + +public struct Filter: Hashable, Identifiable { + + public let id = UUID().uuidString + public let name: String + public let iconName: String + + public let dataSource: DataSource + public let unrecognized: Bool + public let outdated: Bool + + public init(name: String, + iconName: String, + dataSource: DataSource, + unrecognized: Bool, + outdated: Bool) { + + self.name = name + self.iconName = iconName + self.dataSource = dataSource + self.unrecognized = unrecognized + self.outdated = outdated + } +} + +// MARK: - Presets + +extension Filter { + + public static var allLocal: Filter { + Filter(name: "All", + iconName: "car.2", + dataSource: .local, + unrecognized: false, + outdated: false) + } + + public static var allRemote: Filter { + Filter(name: "All", + iconName: "car.2", + dataSource: .remote, + unrecognized: false, + outdated: false) + } + + public static var unrecognized: Filter { + Filter(name: "Unrecognized", + iconName: "eye.slash", + dataSource: .local, + unrecognized: true, + outdated: false) + } + + public static var outdated: Filter { + Filter(name: "Outdated", + iconName: "clock.badge.exclamationmark", + dataSource: .local, + unrecognized: false, + outdated: true) } } diff --git a/AutoCatCore/Models/Settings.swift b/AutoCatCore/Models/Settings.swift index 471c1f7..0a76c40 100644 --- a/AutoCatCore/Models/Settings.swift +++ b/AutoCatCore/Models/Settings.swift @@ -1,20 +1,17 @@ import Foundation -public protocol SettingsProtocol { +public protocol SettingsProtocol: ObservableObject { var user: User { get set } - var recognizeAlternativeOrder: Bool { get set } - var recognizeShortenedNumbers: Bool { get set } - var defaultRegion: String { get set } - var recordBeep: Bool { get set } var showDebugInfo: Bool { get set } } -public class Settings: ObservableObject, SettingsProtocol { +public class Settings: SettingsProtocol { private let defaults: UserDefaults - public static var shared: SettingsProtocol = Testing.isUITesting ? TestSettings() : Settings() + public static var shared: any SettingsProtocol = Testing.isUITesting ? TestSettings() : Settings() + @Published public var user: User { didSet { if let json = try? JSONEncoder().encode(self.user) { @@ -23,34 +20,6 @@ public class Settings: ObservableObject, SettingsProtocol { } } } - - public var recognizeAlternativeOrder: Bool = false { - didSet { - self.defaults.set(self.recognizeAlternativeOrder, forKey: "recognizeAlternativeOrder") - self.defaults.synchronize() - } - } - - public var recognizeShortenedNumbers: Bool = false { - didSet { - self.defaults.set(self.recognizeShortenedNumbers, forKey: "recognizeShortenedNumbers") - self.defaults.synchronize() - } - } - - public var defaultRegion: String = "" { - didSet { - self.defaults.set(self.defaultRegion, forKey: "defaultRegion") - self.defaults.synchronize() - } - } - - public var recordBeep: Bool = false { - didSet { - self.defaults.set(self.recordBeep, forKey: "recordBeep") - self.defaults.synchronize() - } - } public var showDebugInfo: Bool = false { didSet { @@ -63,17 +32,9 @@ public class Settings: ObservableObject, SettingsProtocol { self.defaults = defaults self.defaults.register(defaults: [ - "recognizeAlternativeOrder": false, - "recognizeShortenedNumbers": false, - "defaultRegion": "161", - "recordBeep": false, "showDebugInfo": false ]) - self.recognizeAlternativeOrder = self.defaults.bool(forKey: "recognizeAlternativeOrder") - self.recognizeShortenedNumbers = self.defaults.bool(forKey: "recognizeShortenedNumbers") - self.defaultRegion = self.defaults.string(forKey: "defaultRegion") ?? "161" - self.recordBeep = self.defaults.bool(forKey: "recordBeep") self.showDebugInfo = self.defaults.bool(forKey: "showDebugInfo") if let data = self.defaults.data(forKey: "user") { diff --git a/AutoCatCore/Services/StorageService.swift b/AutoCatCore/Services/StorageService.swift index 8dae7df..7b0f029 100644 --- a/AutoCatCore/Services/StorageService.swift +++ b/AutoCatCore/Services/StorageService.swift @@ -26,6 +26,19 @@ public class StorageService: StorageServiceProtocol { } } + public static var sharedNotWait: StorageService { + if let instance = StorageService.instance { + return instance + } else { + let service = StorageService(inMemory: Testing.isUITesting) + Task { + try? await service.loadPersistentStores() + } + StorageService.instance = service + return service + } + } + init(inMemory: Bool = false) { let bundle = Bundle(for: Self.self) diff --git a/AutoCatCore/Testing/TestSettings.swift b/AutoCatCore/Testing/TestSettings.swift index 637f7e4..861bb07 100644 --- a/AutoCatCore/Testing/TestSettings.swift +++ b/AutoCatCore/Testing/TestSettings.swift @@ -10,9 +10,9 @@ import Foundation public class TestSettings: SettingsProtocol { public var user: User = User() - public var recognizeAlternativeOrder: Bool = false - public var recognizeShortenedNumbers: Bool = false - public var defaultRegion: String = "" - public var recordBeep: Bool = false public var showDebugInfo: Bool = false + + public init() { + + } } diff --git a/AutoCatCore/Utils/Api.swift b/AutoCatCore/Utils/Api.swift index 794905a..05896e1 100644 --- a/AutoCatCore/Utils/Api.swift +++ b/AutoCatCore/Utils/Api.swift @@ -10,11 +10,11 @@ public protocol ApiProtocol { public class Api: ApiProtocol { private let session: URLSession - private let settings: SettingsProtocol + private let settings: any SettingsProtocol public static let shared = Api() - public init(session: URLSession? = nil, settings: SettingsProtocol = Settings.shared) { + public init(session: URLSession? = nil, settings: any SettingsProtocol = Settings.shared) { self.settings = settings