diff --git a/AIGrammar.xcodeproj/project.pbxproj "b/\t\t.xcodeproj/project.pbxproj" similarity index 50% rename from AIGrammar.xcodeproj/project.pbxproj rename to "\t\t.xcodeproj/project.pbxproj" index 3e62eeb..86af8ad 100644 --- a/AIGrammar.xcodeproj/project.pbxproj +++ "b/\t\t.xcodeproj/project.pbxproj" @@ -16,6 +16,31 @@ 5500A3A62BB3C7EC0065A1D3 /* AIGrammarTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5500A3A52BB3C7EC0065A1D3 /* AIGrammarTests.swift */; }; 5500A3B02BB3C7EC0065A1D3 /* AIGrammarUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5500A3AF2BB3C7EC0065A1D3 /* AIGrammarUITests.swift */; }; 5500A3B22BB3C7EC0065A1D3 /* AIGrammarUITestsLaunchTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5500A3B12BB3C7EC0065A1D3 /* AIGrammarUITestsLaunchTests.swift */; }; + 5500A3C02BB40A3B0065A1D3 /* AllTabView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5500A3BF2BB40A3B0065A1D3 /* AllTabView.swift */; }; + 5500A3C22BB40AB10065A1D3 /* GrammarCheckView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5500A3C12BB40AB10065A1D3 /* GrammarCheckView.swift */; }; + 5500A3C42BB40AC40065A1D3 /* WordsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5500A3C32BB40AC40065A1D3 /* WordsView.swift */; }; + 5500A3C62BB40AD30065A1D3 /* TranslateView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5500A3C52BB40AD30065A1D3 /* TranslateView.swift */; }; + 5500A3C82BB40ADE0065A1D3 /* SettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5500A3C72BB40ADE0065A1D3 /* SettingsView.swift */; }; + 5509CEEE2BB526F80056C5C2 /* ColorToString.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5509CEED2BB526F70056C5C2 /* ColorToString.swift */; }; + 5509CEF12BB54DD10056C5C2 /* Config.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5509CEF02BB54DD10056C5C2 /* Config.swift */; }; + 550B85A22C2BC624008834E5 /* InitAPP.swift in Sources */ = {isa = PBXBuildFile; fileRef = 550B85A12C2BC623008834E5 /* InitAPP.swift */; }; + 559E6D7C2C34EAE700C971B9 /* IapManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 559E6D7B2C34EAE700C971B9 /* IapManager.swift */; }; + 559E6D7E2C35355200C971B9 /* LogManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 559E6D7D2C35355200C971B9 /* LogManager.swift */; }; + 55A954A22BBBFD0C00BF181E /* GrammarData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 55A954A12BBBFD0C00BF181E /* GrammarData.swift */; }; + 55BB12792BBD4C9900D2BEA4 /* RichText.swift in Sources */ = {isa = PBXBuildFile; fileRef = 55BB12782BBD4C9900D2BEA4 /* RichText.swift */; }; + 55BB127B2BBD653100D2BEA4 /* ShareSheet.swift in Sources */ = {isa = PBXBuildFile; fileRef = 55BB127A2BBD653100D2BEA4 /* ShareSheet.swift */; }; + 55BB127D2BBD6D0600D2BEA4 /* CameraView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 55BB127C2BBD6D0600D2BEA4 /* CameraView.swift */; }; + 55BC47492C3A383A00120A7D /* LoadingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 55BC47482C3A383A00120A7D /* LoadingView.swift */; }; + 55BC474F2C3A4E5E00120A7D /* ToastUI in Frameworks */ = {isa = PBXBuildFile; productRef = 55BC474E2C3A4E5E00120A7D /* ToastUI */; }; + 55BC47512C3D431300120A7D /* IAPView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 55BC47502C3D431300120A7D /* IAPView.swift */; }; + 55D632FA2C0F125D00443894 /* NetworkManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 55D632F92C0F125D00443894 /* NetworkManager.swift */; }; + 55DAC6552BBA959500BDD4C8 /* ResultView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 55DAC6542BBA959500BDD4C8 /* ResultView.swift */; }; + 55DAC6572BBA984B00BDD4C8 /* InputView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 55DAC6562BBA984B00BDD4C8 /* InputView.swift */; }; + 55EF5C3C2C2250900060CE47 /* IAPTestView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 55EF5C3B2C2250900060CE47 /* IAPTestView.swift */; }; + 55EF5C3E2C2263460060CE47 /* StoreKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 55EF5C3D2C2263460060CE47 /* StoreKit.framework */; }; + 67F268687FCD2E4F2F4462C0 /* Pods_AIGrammar.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 12CA1A1A0FE978794C445DBF /* Pods_AIGrammar.framework */; }; + 74F2A468AB0CDAB987996958 /* Pods_AIGrammarTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D848C5F909AA8F5965ADC982 /* Pods_AIGrammarTests.framework */; }; + 9C67AFB08807D99E5D33962E /* Pods_AIGrammar_AIGrammarUITests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 17A4761E5C3381A5C601C830 /* Pods_AIGrammar_AIGrammarUITests.framework */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -36,6 +61,10 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ + 12CA1A1A0FE978794C445DBF /* Pods_AIGrammar.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_AIGrammar.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 151748838A6B3B48F136656A /* Pods-AIGrammarTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AIGrammarTests.release.xcconfig"; path = "Target Support Files/Pods-AIGrammarTests/Pods-AIGrammarTests.release.xcconfig"; sourceTree = ""; }; + 17A4761E5C3381A5C601C830 /* Pods_AIGrammar_AIGrammarUITests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_AIGrammar_AIGrammarUITests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 26700CBCCF4198DB4A727889 /* Pods-AIGrammar.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AIGrammar.release.xcconfig"; path = "Target Support Files/Pods-AIGrammar/Pods-AIGrammar.release.xcconfig"; sourceTree = ""; }; 5500A38C2BB3C7E80065A1D3 /* AIGrammar.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = AIGrammar.app; sourceTree = BUILT_PRODUCTS_DIR; }; 5500A38F2BB3C7E80065A1D3 /* AIGrammarApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AIGrammarApp.swift; sourceTree = ""; }; 5500A3912BB3C7E80065A1D3 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; @@ -48,6 +77,33 @@ 5500A3AB2BB3C7EC0065A1D3 /* AIGrammarUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = AIGrammarUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 5500A3AF2BB3C7EC0065A1D3 /* AIGrammarUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AIGrammarUITests.swift; sourceTree = ""; }; 5500A3B12BB3C7EC0065A1D3 /* AIGrammarUITestsLaunchTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AIGrammarUITestsLaunchTests.swift; sourceTree = ""; }; + 5500A3BF2BB40A3B0065A1D3 /* AllTabView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AllTabView.swift; sourceTree = ""; }; + 5500A3C12BB40AB10065A1D3 /* GrammarCheckView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GrammarCheckView.swift; sourceTree = ""; }; + 5500A3C32BB40AC40065A1D3 /* WordsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WordsView.swift; sourceTree = ""; }; + 5500A3C52BB40AD30065A1D3 /* TranslateView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TranslateView.swift; sourceTree = ""; }; + 5500A3C72BB40ADE0065A1D3 /* SettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsView.swift; sourceTree = ""; }; + 5509CEED2BB526F70056C5C2 /* ColorToString.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ColorToString.swift; sourceTree = ""; }; + 5509CEF02BB54DD10056C5C2 /* Config.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Config.swift; sourceTree = ""; }; + 550B85A12C2BC623008834E5 /* InitAPP.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InitAPP.swift; sourceTree = ""; }; + 559E6D7B2C34EAE700C971B9 /* IapManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IapManager.swift; sourceTree = ""; }; + 559E6D7D2C35355200C971B9 /* LogManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LogManager.swift; sourceTree = ""; }; + 55A954A12BBBFD0C00BF181E /* GrammarData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GrammarData.swift; sourceTree = ""; }; + 55BB12782BBD4C9900D2BEA4 /* RichText.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RichText.swift; sourceTree = ""; }; + 55BB127A2BBD653100D2BEA4 /* ShareSheet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShareSheet.swift; sourceTree = ""; }; + 55BB127C2BBD6D0600D2BEA4 /* CameraView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CameraView.swift; sourceTree = ""; }; + 55BC47482C3A383A00120A7D /* LoadingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoadingView.swift; sourceTree = ""; }; + 55BC47502C3D431300120A7D /* IAPView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IAPView.swift; sourceTree = ""; }; + 55C73D7E2C157C2200041C66 /* AIGrammar.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = AIGrammar.entitlements; sourceTree = ""; }; + 55D632F92C0F125D00443894 /* NetworkManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkManager.swift; sourceTree = ""; }; + 55DAC6542BBA959500BDD4C8 /* ResultView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ResultView.swift; sourceTree = ""; }; + 55DAC6562BBA984B00BDD4C8 /* InputView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InputView.swift; sourceTree = ""; }; + 55EF5C3B2C2250900060CE47 /* IAPTestView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IAPTestView.swift; sourceTree = ""; }; + 55EF5C3D2C2263460060CE47 /* StoreKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = StoreKit.framework; path = System/Library/Frameworks/StoreKit.framework; sourceTree = SDKROOT; }; + 5C33D84343808119C7E904A2 /* Pods-AIGrammarTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AIGrammarTests.debug.xcconfig"; path = "Target Support Files/Pods-AIGrammarTests/Pods-AIGrammarTests.debug.xcconfig"; sourceTree = ""; }; + 7C535B875DDD6400217E60EC /* Pods-AIGrammar-AIGrammarUITests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AIGrammar-AIGrammarUITests.debug.xcconfig"; path = "Target Support Files/Pods-AIGrammar-AIGrammarUITests/Pods-AIGrammar-AIGrammarUITests.debug.xcconfig"; sourceTree = ""; }; + 8AF5D0FA64AC9954B5F50C58 /* Pods-AIGrammar.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AIGrammar.debug.xcconfig"; path = "Target Support Files/Pods-AIGrammar/Pods-AIGrammar.debug.xcconfig"; sourceTree = ""; }; + C6DB81180B641DF0F1C587D7 /* Pods-AIGrammar-AIGrammarUITests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AIGrammar-AIGrammarUITests.release.xcconfig"; path = "Target Support Files/Pods-AIGrammar-AIGrammarUITests/Pods-AIGrammar-AIGrammarUITests.release.xcconfig"; sourceTree = ""; }; + D848C5F909AA8F5965ADC982 /* Pods_AIGrammarTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_AIGrammarTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -55,6 +111,9 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 55BC474F2C3A4E5E00120A7D /* ToastUI in Frameworks */, + 67F268687FCD2E4F2F4462C0 /* Pods_AIGrammar.framework in Frameworks */, + 55EF5C3E2C2263460060CE47 /* StoreKit.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -62,6 +121,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 74F2A468AB0CDAB987996958 /* Pods_AIGrammarTests.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -69,12 +129,24 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 9C67AFB08807D99E5D33962E /* Pods_AIGrammar_AIGrammarUITests.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 40FEAE98949AC44A40547B20 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 55EF5C3D2C2263460060CE47 /* StoreKit.framework */, + 12CA1A1A0FE978794C445DBF /* Pods_AIGrammar.framework */, + 17A4761E5C3381A5C601C830 /* Pods_AIGrammar_AIGrammarUITests.framework */, + D848C5F909AA8F5965ADC982 /* Pods_AIGrammarTests.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; 5500A3832BB3C7E80065A1D3 = { isa = PBXGroup; children = ( @@ -82,6 +154,8 @@ 5500A3A42BB3C7EC0065A1D3 /* AIGrammarTests */, 5500A3AE2BB3C7EC0065A1D3 /* AIGrammarUITests */, 5500A38D2BB3C7E80065A1D3 /* Products */, + B164443BE53434F82C385E52 /* Pods */, + 40FEAE98949AC44A40547B20 /* Frameworks */, ); sourceTree = ""; }; @@ -98,6 +172,13 @@ 5500A38E2BB3C7E80065A1D3 /* AIGrammar */ = { isa = PBXGroup; children = ( + 55BC47472C3A380C00120A7D /* CommView */, + 55C73D7E2C157C2200041C66 /* AIGrammar.entitlements */, + 55DAC6532BBA956100BDD4C8 /* GrammarSubView */, + 5509CEEF2BB54DAB0056C5C2 /* ViewModel */, + 5509CEEC2BB5267F0056C5C2 /* lib */, + 5500A3BF2BB40A3B0065A1D3 /* AllTabView.swift */, + 5500A3BE2BB40A1F0065A1D3 /* View */, 5500A38F2BB3C7E80065A1D3 /* AIGrammarApp.swift */, 5500A3912BB3C7E80065A1D3 /* ContentView.swift */, 5500A3932BB3C7EB0065A1D3 /* Assets.xcassets */, @@ -133,6 +214,73 @@ path = AIGrammarUITests; sourceTree = ""; }; + 5500A3BE2BB40A1F0065A1D3 /* View */ = { + isa = PBXGroup; + children = ( + 5500A3C12BB40AB10065A1D3 /* GrammarCheckView.swift */, + 5500A3C32BB40AC40065A1D3 /* WordsView.swift */, + 5500A3C52BB40AD30065A1D3 /* TranslateView.swift */, + 5500A3C72BB40ADE0065A1D3 /* SettingsView.swift */, + 55BC47502C3D431300120A7D /* IAPView.swift */, + ); + path = View; + sourceTree = ""; + }; + 5509CEEC2BB5267F0056C5C2 /* lib */ = { + isa = PBXGroup; + children = ( + 550B85A12C2BC623008834E5 /* InitAPP.swift */, + 5509CEED2BB526F70056C5C2 /* ColorToString.swift */, + 55D632F92C0F125D00443894 /* NetworkManager.swift */, + 559E6D7B2C34EAE700C971B9 /* IapManager.swift */, + 559E6D7D2C35355200C971B9 /* LogManager.swift */, + ); + path = lib; + sourceTree = ""; + }; + 5509CEEF2BB54DAB0056C5C2 /* ViewModel */ = { + isa = PBXGroup; + children = ( + 5509CEF02BB54DD10056C5C2 /* Config.swift */, + 55A954A12BBBFD0C00BF181E /* GrammarData.swift */, + ); + path = ViewModel; + sourceTree = ""; + }; + 55BC47472C3A380C00120A7D /* CommView */ = { + isa = PBXGroup; + children = ( + 55BC47482C3A383A00120A7D /* LoadingView.swift */, + ); + path = CommView; + sourceTree = ""; + }; + 55DAC6532BBA956100BDD4C8 /* GrammarSubView */ = { + isa = PBXGroup; + children = ( + 55DAC6542BBA959500BDD4C8 /* ResultView.swift */, + 55DAC6562BBA984B00BDD4C8 /* InputView.swift */, + 55BB12782BBD4C9900D2BEA4 /* RichText.swift */, + 55BB127A2BBD653100D2BEA4 /* ShareSheet.swift */, + 55BB127C2BBD6D0600D2BEA4 /* CameraView.swift */, + 55EF5C3B2C2250900060CE47 /* IAPTestView.swift */, + ); + path = GrammarSubView; + sourceTree = ""; + }; + B164443BE53434F82C385E52 /* Pods */ = { + isa = PBXGroup; + children = ( + 8AF5D0FA64AC9954B5F50C58 /* Pods-AIGrammar.debug.xcconfig */, + 26700CBCCF4198DB4A727889 /* Pods-AIGrammar.release.xcconfig */, + 7C535B875DDD6400217E60EC /* Pods-AIGrammar-AIGrammarUITests.debug.xcconfig */, + C6DB81180B641DF0F1C587D7 /* Pods-AIGrammar-AIGrammarUITests.release.xcconfig */, + 5C33D84343808119C7E904A2 /* Pods-AIGrammarTests.debug.xcconfig */, + 151748838A6B3B48F136656A /* Pods-AIGrammarTests.release.xcconfig */, + ); + path = Pods; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -140,15 +288,20 @@ isa = PBXNativeTarget; buildConfigurationList = 5500A3B52BB3C7EC0065A1D3 /* Build configuration list for PBXNativeTarget "AIGrammar" */; buildPhases = ( + 8B14D9249A058EC52D6F04F3 /* [CP] Check Pods Manifest.lock */, 5500A3882BB3C7E80065A1D3 /* Sources */, 5500A3892BB3C7E80065A1D3 /* Frameworks */, 5500A38A2BB3C7E80065A1D3 /* Resources */, + FF9E2F6B912125F8F338EE9E /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); dependencies = ( ); name = AIGrammar; + packageProductDependencies = ( + 55BC474E2C3A4E5E00120A7D /* ToastUI */, + ); productName = AIGrammar; productReference = 5500A38C2BB3C7E80065A1D3 /* AIGrammar.app */; productType = "com.apple.product-type.application"; @@ -157,6 +310,7 @@ isa = PBXNativeTarget; buildConfigurationList = 5500A3B82BB3C7EC0065A1D3 /* Build configuration list for PBXNativeTarget "AIGrammarTests" */; buildPhases = ( + 498A407B1B5D54884032EBE0 /* [CP] Check Pods Manifest.lock */, 5500A39D2BB3C7EC0065A1D3 /* Sources */, 5500A39E2BB3C7EC0065A1D3 /* Frameworks */, 5500A39F2BB3C7EC0065A1D3 /* Resources */, @@ -175,9 +329,11 @@ isa = PBXNativeTarget; buildConfigurationList = 5500A3BB2BB3C7EC0065A1D3 /* Build configuration list for PBXNativeTarget "AIGrammarUITests" */; buildPhases = ( + 122A24ED4A80683F7AD2CBF5 /* [CP] Check Pods Manifest.lock */, 5500A3A72BB3C7EC0065A1D3 /* Sources */, 5500A3A82BB3C7EC0065A1D3 /* Frameworks */, 5500A3A92BB3C7EC0065A1D3 /* Resources */, + 71E9C7A697AC9238D1513188 /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); @@ -221,6 +377,9 @@ Base, ); mainGroup = 5500A3832BB3C7E80065A1D3; + packageReferences = ( + 55BC474D2C3A4E5E00120A7D /* XCRemoteSwiftPackageReference "ToastUI" */, + ); productRefGroup = 5500A38D2BB3C7E80065A1D3 /* Products */; projectDirPath = ""; projectRoot = ""; @@ -258,15 +417,138 @@ }; /* End PBXResourcesBuildPhase section */ +/* Begin PBXShellScriptBuildPhase section */ + 122A24ED4A80683F7AD2CBF5 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-AIGrammar-AIGrammarUITests-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + 498A407B1B5D54884032EBE0 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-AIGrammarTests-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + 71E9C7A697AC9238D1513188 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-AIGrammar-AIGrammarUITests/Pods-AIGrammar-AIGrammarUITests-frameworks-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-AIGrammar-AIGrammarUITests/Pods-AIGrammar-AIGrammarUITests-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-AIGrammar-AIGrammarUITests/Pods-AIGrammar-AIGrammarUITests-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + 8B14D9249A058EC52D6F04F3 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-AIGrammar-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + FF9E2F6B912125F8F338EE9E /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-AIGrammar/Pods-AIGrammar-frameworks-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-AIGrammar/Pods-AIGrammar-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-AIGrammar/Pods-AIGrammar-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + /* Begin PBXSourcesBuildPhase section */ 5500A3882BB3C7E80065A1D3 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( 5500A3992BB3C7EB0065A1D3 /* Persistence.swift in Sources */, + 55DAC6572BBA984B00BDD4C8 /* InputView.swift in Sources */, + 55A954A22BBBFD0C00BF181E /* GrammarData.swift in Sources */, + 55BB12792BBD4C9900D2BEA4 /* RichText.swift in Sources */, + 5500A3C22BB40AB10065A1D3 /* GrammarCheckView.swift in Sources */, + 55BC47512C3D431300120A7D /* IAPView.swift in Sources */, + 550B85A22C2BC624008834E5 /* InitAPP.swift in Sources */, + 5500A3C42BB40AC40065A1D3 /* WordsView.swift in Sources */, + 5509CEF12BB54DD10056C5C2 /* Config.swift in Sources */, + 55BB127B2BBD653100D2BEA4 /* ShareSheet.swift in Sources */, + 5500A3C82BB40ADE0065A1D3 /* SettingsView.swift in Sources */, + 55DAC6552BBA959500BDD4C8 /* ResultView.swift in Sources */, + 5500A3C02BB40A3B0065A1D3 /* AllTabView.swift in Sources */, + 559E6D7E2C35355200C971B9 /* LogManager.swift in Sources */, + 55D632FA2C0F125D00443894 /* NetworkManager.swift in Sources */, 5500A3922BB3C7E80065A1D3 /* ContentView.swift in Sources */, + 55BB127D2BBD6D0600D2BEA4 /* CameraView.swift in Sources */, + 559E6D7C2C34EAE700C971B9 /* IapManager.swift in Sources */, + 55EF5C3C2C2250900060CE47 /* IAPTestView.swift in Sources */, 5500A3902BB3C7E80065A1D3 /* AIGrammarApp.swift in Sources */, 5500A39C2BB3C7EB0065A1D3 /* AIGrammar.xcdatamodeld in Sources */, + 5500A3C62BB40AD30065A1D3 /* TranslateView.swift in Sources */, + 5509CEEE2BB526F80056C5C2 /* ColorToString.swift in Sources */, + 55BC47492C3A383A00120A7D /* LoadingView.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -329,7 +611,7 @@ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; @@ -340,7 +622,7 @@ DEBUG_INFORMATION_FORMAT = dwarf; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; - ENABLE_USER_SCRIPT_SANDBOXING = YES; + ENABLE_USER_SCRIPT_SANDBOXING = NO; GCC_C_LANGUAGE_STANDARD = gnu17; GCC_DYNAMIC_NO_PIC = NO; GCC_NO_COMMON_BLOCKS = YES; @@ -392,7 +674,7 @@ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; @@ -403,7 +685,7 @@ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_USER_SCRIPT_SANDBOXING = YES; + ENABLE_USER_SCRIPT_SANDBOXING = NO; GCC_C_LANGUAGE_STANDARD = gnu17; GCC_NO_COMMON_BLOCKS = YES; GCC_WARN_64_TO_32_BIT_CONVERSION = YES; @@ -424,26 +706,30 @@ }; 5500A3B62BB3C7EC0065A1D3 /* Debug */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 8AF5D0FA64AC9954B5F50C58 /* Pods-AIGrammar.debug.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_ENTITLEMENTS = AIGrammar/AIGrammar.entitlements; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_ASSET_PATHS = "\"AIGrammar/Preview Content\""; DEVELOPMENT_TEAM = G8UMWM9TLL; ENABLE_PREVIEWS = YES; GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_KEY_NSCameraUsageDescription = "用户拍照获取文本"; INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; INFOPLIST_KEY_UILaunchScreen_Generation = YES; - INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; - INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations = UIInterfaceOrientationPortrait; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown"; + IPHONEOS_DEPLOYMENT_TARGET = 16.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = com.ostest.Grammar.AIGrammar; + PRODUCT_BUNDLE_IDENTIFIER = com.easyprompts.aigrammar; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_VERSION = 5.0; @@ -453,26 +739,30 @@ }; 5500A3B72BB3C7EC0065A1D3 /* Release */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 26700CBCCF4198DB4A727889 /* Pods-AIGrammar.release.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_ENTITLEMENTS = AIGrammar/AIGrammar.entitlements; CODE_SIGN_STYLE = Automatic; CURRENT_PROJECT_VERSION = 1; DEVELOPMENT_ASSET_PATHS = "\"AIGrammar/Preview Content\""; DEVELOPMENT_TEAM = G8UMWM9TLL; ENABLE_PREVIEWS = YES; GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_KEY_NSCameraUsageDescription = "用户拍照获取文本"; INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; INFOPLIST_KEY_UILaunchScreen_Generation = YES; - INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; - INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations = UIInterfaceOrientationPortrait; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown"; + IPHONEOS_DEPLOYMENT_TARGET = 16.0; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); MARKETING_VERSION = 1.0; - PRODUCT_BUNDLE_IDENTIFIER = com.ostest.Grammar.AIGrammar; + PRODUCT_BUNDLE_IDENTIFIER = com.easyprompts.aigrammar; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_EMIT_LOC_STRINGS = YES; SWIFT_VERSION = 5.0; @@ -482,6 +772,7 @@ }; 5500A3B92BB3C7EC0065A1D3 /* Debug */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 5C33D84343808119C7E904A2 /* Pods-AIGrammarTests.debug.xcconfig */; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; BUNDLE_LOADER = "$(TEST_HOST)"; @@ -502,6 +793,7 @@ }; 5500A3BA2BB3C7EC0065A1D3 /* Release */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 151748838A6B3B48F136656A /* Pods-AIGrammarTests.release.xcconfig */; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; BUNDLE_LOADER = "$(TEST_HOST)"; @@ -522,6 +814,7 @@ }; 5500A3BC2BB3C7EC0065A1D3 /* Debug */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 7C535B875DDD6400217E60EC /* Pods-AIGrammar-AIGrammarUITests.debug.xcconfig */; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; CODE_SIGN_STYLE = Automatic; @@ -540,6 +833,7 @@ }; 5500A3BD2BB3C7EC0065A1D3 /* Release */ = { isa = XCBuildConfiguration; + baseConfigurationReference = C6DB81180B641DF0F1C587D7 /* Pods-AIGrammar-AIGrammarUITests.release.xcconfig */; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; CODE_SIGN_STYLE = Automatic; @@ -597,6 +891,25 @@ }; /* End XCConfigurationList section */ +/* Begin XCRemoteSwiftPackageReference section */ + 55BC474D2C3A4E5E00120A7D /* XCRemoteSwiftPackageReference "ToastUI" */ = { + isa = XCRemoteSwiftPackageReference; + repositoryURL = "https://github.com/quanshousio/ToastUI.git"; + requirement = { + kind = upToNextMajorVersion; + minimumVersion = 3.0.1; + }; + }; +/* End XCRemoteSwiftPackageReference section */ + +/* Begin XCSwiftPackageProductDependency section */ + 55BC474E2C3A4E5E00120A7D /* ToastUI */ = { + isa = XCSwiftPackageProductDependency; + package = 55BC474D2C3A4E5E00120A7D /* XCRemoteSwiftPackageReference "ToastUI" */; + productName = ToastUI; + }; +/* End XCSwiftPackageProductDependency section */ + /* Begin XCVersionGroup section */ 5500A39A2BB3C7EB0065A1D3 /* AIGrammar.xcdatamodeld */ = { isa = XCVersionGroup; diff --git a/AIGrammar.xcodeproj/project.xcworkspace/contents.xcworkspacedata "b/\t\t.xcodeproj/project.xcworkspace/contents.xcworkspacedata" similarity index 100% rename from AIGrammar.xcodeproj/project.xcworkspace/contents.xcworkspacedata rename to "\t\t.xcodeproj/project.xcworkspace/contents.xcworkspacedata" diff --git a/AIGrammar.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist "b/\t\t.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist" similarity index 100% rename from AIGrammar.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist rename to "\t\t.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist" diff --git "a/\t\t.xcodeproj/xcshareddata/xcschemes/AIGrammar.xcscheme" "b/\t\t.xcodeproj/xcshareddata/xcschemes/AIGrammar.xcscheme" new file mode 100644 index 0000000..db74c74 --- /dev/null +++ "b/\t\t.xcodeproj/xcshareddata/xcschemes/AIGrammar.xcscheme" @@ -0,0 +1,101 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git "a/\t\t.xcodeproj/xcuserdata/oscar.xcuserdatad/xcschemes/xcschememanagement.plist" "b/\t\t.xcodeproj/xcuserdata/oscar.xcuserdatad/xcschemes/xcschememanagement.plist" new file mode 100644 index 0000000..fbd38e8 --- /dev/null +++ "b/\t\t.xcodeproj/xcuserdata/oscar.xcuserdatad/xcschemes/xcschememanagement.plist" @@ -0,0 +1,32 @@ + + + + + SchemeUserState + + AIGrammar.xcscheme_^#shared#^_ + + orderHint + 13 + + + SuppressBuildableAutocreation + + 5500A38B2BB3C7E80065A1D3 + + primary + + + 5500A3A02BB3C7EC0065A1D3 + + primary + + + 5500A3AA2BB3C7EC0065A1D3 + + primary + + + + + diff --git a/AIGrammar.xcodeproj/xcuserdata/oscar.xcuserdatad/xcschemes/xcschememanagement.plist b/AIGrammar/AIGrammar.entitlements similarity index 54% rename from AIGrammar.xcodeproj/xcuserdata/oscar.xcuserdatad/xcschemes/xcschememanagement.plist rename to AIGrammar/AIGrammar.entitlements index 7a55041..c6c92d9 100644 --- a/AIGrammar.xcodeproj/xcuserdata/oscar.xcuserdatad/xcschemes/xcschememanagement.plist +++ b/AIGrammar/AIGrammar.entitlements @@ -2,13 +2,7 @@ - SchemeUserState - - AIGrammar.xcscheme_^#shared#^_ - - orderHint - 0 - - + com.apple.developer.in-app-payments + diff --git a/AIGrammar/AllTabView.swift b/AIGrammar/AllTabView.swift new file mode 100644 index 0000000..2115223 --- /dev/null +++ b/AIGrammar/AllTabView.swift @@ -0,0 +1,80 @@ +// +// AllTab.swift +// AIGrammar +// +// Created by oscar on 2024/3/27. +// + +import SwiftUI + +@main +struct LearningToolApp: App { + var body: some Scene { + WindowGroup { + ContentView() + } + } +} + +struct ContentView: View { + var body: some View { + TabView { + GrammarCheckView() + .tabItem { + Image(systemName: "book.fill") + Text("Grammar Check") + } + + WordsView() + .tabItem { + Image(systemName: "text.bubble") + Text("Words") + } + + TranslateView() + .tabItem { + Image(systemName: "globe") + Text("Translate") + } + + SettingsView() + .tabItem { + Image(systemName: "gear") + Text("Settings") + } + } + } +} + +struct GrammarCheckView: View { + var body: some View { + // Your Grammar Check View content goes here. + Text("Grammar Check") + } +} + +struct WordsView: View { + var body: some View { + // Your Words View content goes here. + Text("Words") + } +} + +struct TranslateView: View { + var body: some View { + // Your Translate View content goes here. + Text("Translate") + } +} + +struct SettingsView: View { + var body: some View { + // Your Settings View content goes here. + Text("Settings") + } +} + + +#Preview { + AllTab() +} diff --git a/AIGrammar/Assets.xcassets/AppIcon.appiconset/Contents.json b/AIGrammar/Assets.xcassets/AppIcon.appiconset/Contents.json index 13613e3..c68df94 100644 --- a/AIGrammar/Assets.xcassets/AppIcon.appiconset/Contents.json +++ b/AIGrammar/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -1,13 +1,120 @@ { - "images" : [ - { - "idiom" : "universal", - "platform" : "ios", - "size" : "1024x1024" + "images": [ + { + "size": "20x20", + "idiom": "universal", + "filename": "icon-20@2x.png", + "scale": "2x", + "platform": "ios" + }, + { + "size": "20x20", + "idiom": "universal", + "filename": "icon-20@3x.png", + "scale": "3x", + "platform": "ios" + }, + { + "size": "29x29", + "idiom": "universal", + "filename": "icon-29@2x.png", + "scale": "2x", + "platform": "ios" + }, + { + "size": "29x29", + "idiom": "universal", + "filename": "icon-29@3x.png", + "scale": "3x", + "platform": "ios" + }, + { + "size": "38x38", + "idiom": "universal", + "filename": "icon-38@2x.png", + "scale": "2x", + "platform": "ios" + }, + { + "size": "38x38", + "idiom": "universal", + "filename": "icon-38@3x.png", + "scale": "3x", + "platform": "ios" + }, + { + "size": "40x40", + "idiom": "universal", + "filename": "icon-40@2x.png", + "scale": "2x", + "platform": "ios" + }, + { + "size": "40x40", + "idiom": "universal", + "filename": "icon-40@3x.png", + "scale": "3x", + "platform": "ios" + }, + { + "size": "60x60", + "idiom": "universal", + "filename": "icon-60@2x.png", + "scale": "2x", + "platform": "ios" + }, + { + "size": "60x60", + "idiom": "universal", + "filename": "icon-60@3x.png", + "scale": "3x", + "platform": "ios" + }, + { + "size": "64x64", + "idiom": "universal", + "filename": "icon-64@2x.png", + "scale": "2x", + "platform": "ios" + }, + { + "size": "64x64", + "idiom": "universal", + "filename": "icon-64@3x.png", + "scale": "3x", + "platform": "ios" + }, + { + "size": "68x68", + "idiom": "universal", + "filename": "icon-68@2x.png", + "scale": "2x", + "platform": "ios" + }, + { + "size": "76x76", + "idiom": "universal", + "filename": "icon-76@2x.png", + "scale": "2x", + "platform": "ios" + }, + { + "size": "83.5x83.5", + "idiom": "universal", + "filename": "icon-83.5@2x.png", + "scale": "2x", + "platform": "ios" + }, + { + "size": "1024x1024", + "idiom": "universal", + "filename": "icon-1024.png", + "scale": "1x", + "platform": "ios" + } + ], + "info": { + "version": 1, + "author": "icon.wuruihong.com" } - ], - "info" : { - "author" : "xcode", - "version" : 1 - } -} +} \ No newline at end of file diff --git a/AIGrammar/Assets.xcassets/AppIcon.appiconset/icon-1024.png b/AIGrammar/Assets.xcassets/AppIcon.appiconset/icon-1024.png new file mode 100644 index 0000000..697f327 Binary files /dev/null and b/AIGrammar/Assets.xcassets/AppIcon.appiconset/icon-1024.png differ diff --git a/AIGrammar/Assets.xcassets/AppIcon.appiconset/icon-20@2x.png b/AIGrammar/Assets.xcassets/AppIcon.appiconset/icon-20@2x.png new file mode 100644 index 0000000..279a758 Binary files /dev/null and b/AIGrammar/Assets.xcassets/AppIcon.appiconset/icon-20@2x.png differ diff --git a/AIGrammar/Assets.xcassets/AppIcon.appiconset/icon-20@3x.png b/AIGrammar/Assets.xcassets/AppIcon.appiconset/icon-20@3x.png new file mode 100644 index 0000000..86d6205 Binary files /dev/null and b/AIGrammar/Assets.xcassets/AppIcon.appiconset/icon-20@3x.png differ diff --git a/AIGrammar/Assets.xcassets/AppIcon.appiconset/icon-29@2x.png b/AIGrammar/Assets.xcassets/AppIcon.appiconset/icon-29@2x.png new file mode 100644 index 0000000..e1c3f93 Binary files /dev/null and b/AIGrammar/Assets.xcassets/AppIcon.appiconset/icon-29@2x.png differ diff --git a/AIGrammar/Assets.xcassets/AppIcon.appiconset/icon-29@3x.png b/AIGrammar/Assets.xcassets/AppIcon.appiconset/icon-29@3x.png new file mode 100644 index 0000000..5a32cb2 Binary files /dev/null and b/AIGrammar/Assets.xcassets/AppIcon.appiconset/icon-29@3x.png differ diff --git a/AIGrammar/Assets.xcassets/AppIcon.appiconset/icon-38@2x.png b/AIGrammar/Assets.xcassets/AppIcon.appiconset/icon-38@2x.png new file mode 100644 index 0000000..9f192ea Binary files /dev/null and b/AIGrammar/Assets.xcassets/AppIcon.appiconset/icon-38@2x.png differ diff --git a/AIGrammar/Assets.xcassets/AppIcon.appiconset/icon-38@3x.png b/AIGrammar/Assets.xcassets/AppIcon.appiconset/icon-38@3x.png new file mode 100644 index 0000000..195391f Binary files /dev/null and b/AIGrammar/Assets.xcassets/AppIcon.appiconset/icon-38@3x.png differ diff --git a/AIGrammar/Assets.xcassets/AppIcon.appiconset/icon-40@2x.png b/AIGrammar/Assets.xcassets/AppIcon.appiconset/icon-40@2x.png new file mode 100644 index 0000000..3dc20a6 Binary files /dev/null and b/AIGrammar/Assets.xcassets/AppIcon.appiconset/icon-40@2x.png differ diff --git a/AIGrammar/Assets.xcassets/AppIcon.appiconset/icon-40@3x.png b/AIGrammar/Assets.xcassets/AppIcon.appiconset/icon-40@3x.png new file mode 100644 index 0000000..763a246 Binary files /dev/null and b/AIGrammar/Assets.xcassets/AppIcon.appiconset/icon-40@3x.png differ diff --git a/AIGrammar/Assets.xcassets/AppIcon.appiconset/icon-60@2x.png b/AIGrammar/Assets.xcassets/AppIcon.appiconset/icon-60@2x.png new file mode 100644 index 0000000..763a246 Binary files /dev/null and b/AIGrammar/Assets.xcassets/AppIcon.appiconset/icon-60@2x.png differ diff --git a/AIGrammar/Assets.xcassets/AppIcon.appiconset/icon-60@3x.png b/AIGrammar/Assets.xcassets/AppIcon.appiconset/icon-60@3x.png new file mode 100644 index 0000000..edfd7ab Binary files /dev/null and b/AIGrammar/Assets.xcassets/AppIcon.appiconset/icon-60@3x.png differ diff --git a/AIGrammar/Assets.xcassets/AppIcon.appiconset/icon-64@2x.png b/AIGrammar/Assets.xcassets/AppIcon.appiconset/icon-64@2x.png new file mode 100644 index 0000000..03c97ba Binary files /dev/null and b/AIGrammar/Assets.xcassets/AppIcon.appiconset/icon-64@2x.png differ diff --git a/AIGrammar/Assets.xcassets/AppIcon.appiconset/icon-64@3x.png b/AIGrammar/Assets.xcassets/AppIcon.appiconset/icon-64@3x.png new file mode 100644 index 0000000..738f755 Binary files /dev/null and b/AIGrammar/Assets.xcassets/AppIcon.appiconset/icon-64@3x.png differ diff --git a/AIGrammar/Assets.xcassets/AppIcon.appiconset/icon-68@2x.png b/AIGrammar/Assets.xcassets/AppIcon.appiconset/icon-68@2x.png new file mode 100644 index 0000000..c6f1990 Binary files /dev/null and b/AIGrammar/Assets.xcassets/AppIcon.appiconset/icon-68@2x.png differ diff --git a/AIGrammar/Assets.xcassets/AppIcon.appiconset/icon-76@2x.png b/AIGrammar/Assets.xcassets/AppIcon.appiconset/icon-76@2x.png new file mode 100644 index 0000000..e5dd69b Binary files /dev/null and b/AIGrammar/Assets.xcassets/AppIcon.appiconset/icon-76@2x.png differ diff --git a/AIGrammar/Assets.xcassets/AppIcon.appiconset/icon-83.5@2x.png b/AIGrammar/Assets.xcassets/AppIcon.appiconset/icon-83.5@2x.png new file mode 100644 index 0000000..8560367 Binary files /dev/null and b/AIGrammar/Assets.xcassets/AppIcon.appiconset/icon-83.5@2x.png differ diff --git a/AIGrammar/Assets.xcassets/vipimg.imageset/Contents.json b/AIGrammar/Assets.xcassets/vipimg.imageset/Contents.json new file mode 100644 index 0000000..a9c8059 --- /dev/null +++ b/AIGrammar/Assets.xcassets/vipimg.imageset/Contents.json @@ -0,0 +1,33 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + }, + { + "filename" : "crown.png", + "idiom" : "iphone", + "scale" : "1x" + }, + { + "idiom" : "iphone", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/AIGrammar/Assets.xcassets/vipimg.imageset/crown.png b/AIGrammar/Assets.xcassets/vipimg.imageset/crown.png new file mode 100644 index 0000000..98d92a7 Binary files /dev/null and b/AIGrammar/Assets.xcassets/vipimg.imageset/crown.png differ diff --git a/AIGrammar/CommView/LoadingView.swift b/AIGrammar/CommView/LoadingView.swift new file mode 100644 index 0000000..46636d6 --- /dev/null +++ b/AIGrammar/CommView/LoadingView.swift @@ -0,0 +1,18 @@ +// +// LoadingView.swift +// AIGrammar +// +// Created by oscar on 2024/7/7. +// + +import SwiftUI + +struct LoadingView: View { + var body: some View { + Text(/*@START_MENU_TOKEN@*/"Hello, World!"/*@END_MENU_TOKEN@*/) + } +} + +#Preview { + LoadingView() +} diff --git a/AIGrammar/GrammarSubView/CameraView.swift b/AIGrammar/GrammarSubView/CameraView.swift new file mode 100644 index 0000000..8e59d0a --- /dev/null +++ b/AIGrammar/GrammarSubView/CameraView.swift @@ -0,0 +1,18 @@ +// +// CameraView.swift +// AIGrammar +// +// Created by oscar on 2024/4/3. +// + +import SwiftUI + +struct CameraView: View { + var body: some View { + Text(/*@START_MENU_TOKEN@*/"Hello, World!"/*@END_MENU_TOKEN@*/) + } +} + +#Preview { + CameraView() +} diff --git a/AIGrammar/GrammarSubView/IAPTestView.swift b/AIGrammar/GrammarSubView/IAPTestView.swift new file mode 100644 index 0000000..112384c --- /dev/null +++ b/AIGrammar/GrammarSubView/IAPTestView.swift @@ -0,0 +1,18 @@ +// +// IAPTestView.swift +// AIGrammar +// +// Created by oscar on 2024/6/19. +// + +import SwiftUI + +struct IAPTestView: View { + var body: some View { + Text(/*@START_MENU_TOKEN@*/"Hello, World!"/*@END_MENU_TOKEN@*/) + } +} + +#Preview { + IAPTestView() +} diff --git a/AIGrammar/GrammarSubView/InputView.swift b/AIGrammar/GrammarSubView/InputView.swift new file mode 100644 index 0000000..693f8d7 --- /dev/null +++ b/AIGrammar/GrammarSubView/InputView.swift @@ -0,0 +1,18 @@ +// +// InputView.swift +// AIGrammar +// +// Created by oscar on 2024/4/1. +// + +import SwiftUI + +struct InputView: View { + var body: some View { + Text(/*@START_MENU_TOKEN@*/"Hello, World!"/*@END_MENU_TOKEN@*/) + } +} + +#Preview { + InputView() +} diff --git a/AIGrammar/GrammarSubView/ResultView.swift b/AIGrammar/GrammarSubView/ResultView.swift new file mode 100644 index 0000000..42d86d3 --- /dev/null +++ b/AIGrammar/GrammarSubView/ResultView.swift @@ -0,0 +1,18 @@ +// +// ResultView.swift +// AIGrammar +// +// Created by oscar on 2024/4/1. +// + +import SwiftUI + +struct ResultView: View { + var body: some View { + Text(/*@START_MENU_TOKEN@*/"Hello, World!"/*@END_MENU_TOKEN@*/) + } +} + +#Preview { + ResultView() +} diff --git a/AIGrammar/GrammarSubView/RichText.swift b/AIGrammar/GrammarSubView/RichText.swift new file mode 100644 index 0000000..d5fbd20 --- /dev/null +++ b/AIGrammar/GrammarSubView/RichText.swift @@ -0,0 +1,18 @@ +// +// RichText.swift +// AIGrammar +// +// Created by oscar on 2024/4/3. +// + +import SwiftUI + +struct RichText: View { + var body: some View { + Text(/*@START_MENU_TOKEN@*/"Hello, World!"/*@END_MENU_TOKEN@*/) + } +} + +#Preview { + RichText() +} diff --git a/AIGrammar/GrammarSubView/ShareSheet.swift b/AIGrammar/GrammarSubView/ShareSheet.swift new file mode 100644 index 0000000..de56b03 --- /dev/null +++ b/AIGrammar/GrammarSubView/ShareSheet.swift @@ -0,0 +1,18 @@ +// +// ShareSheet.swift +// AIGrammar +// +// Created by oscar on 2024/4/3. +// + +import SwiftUI + +struct ShareSheet: View { + var body: some View { + Text(/*@START_MENU_TOKEN@*/"Hello, World!"/*@END_MENU_TOKEN@*/) + } +} + +#Preview { + ShareSheet() +} diff --git a/AIGrammar/View/GrammarCheckView.swift b/AIGrammar/View/GrammarCheckView.swift new file mode 100644 index 0000000..1a58fc8 --- /dev/null +++ b/AIGrammar/View/GrammarCheckView.swift @@ -0,0 +1,18 @@ +// +// GrammarCheckView.swift +// AIGrammar +// +// Created by oscar on 2024/3/27. +// + +import SwiftUI + +struct GrammarCheckView: View { + var body: some View { + Text(/*@START_MENU_TOKEN@*/"Hello, World!"/*@END_MENU_TOKEN@*/) + } +} + +#Preview { + GrammarCheckView() +} diff --git a/AIGrammar/View/IAPView.swift b/AIGrammar/View/IAPView.swift new file mode 100644 index 0000000..15609a6 --- /dev/null +++ b/AIGrammar/View/IAPView.swift @@ -0,0 +1,18 @@ +// +// IAPView.swift +// AIGrammar +// +// Created by oscar on 2024/7/9. +// + +import SwiftUI + +struct IAPView: View { + var body: some View { + Text(/*@START_MENU_TOKEN@*/"Hello, World!"/*@END_MENU_TOKEN@*/) + } +} + +#Preview { + IAPView() +} diff --git a/AIGrammar/View/SettingsView.swift b/AIGrammar/View/SettingsView.swift new file mode 100644 index 0000000..2bfcd6a --- /dev/null +++ b/AIGrammar/View/SettingsView.swift @@ -0,0 +1,18 @@ +// +// SettingsView.swift +// AIGrammar +// +// Created by oscar on 2024/3/27. +// + +import SwiftUI + +struct SettingsView: View { + var body: some View { + Text(/*@START_MENU_TOKEN@*/"Hello, World!"/*@END_MENU_TOKEN@*/) + } +} + +#Preview { + SettingsView() +} diff --git a/AIGrammar/View/TranslateView.swift b/AIGrammar/View/TranslateView.swift new file mode 100644 index 0000000..b2aadaf --- /dev/null +++ b/AIGrammar/View/TranslateView.swift @@ -0,0 +1,18 @@ +// +// TranslateView.swift +// AIGrammar +// +// Created by oscar on 2024/3/27. +// + +import SwiftUI + +struct TranslateView: View { + var body: some View { + Text(/*@START_MENU_TOKEN@*/"Hello, World!"/*@END_MENU_TOKEN@*/) + } +} + +#Preview { + TranslateView() +} diff --git a/AIGrammar/View/WordsView.swift b/AIGrammar/View/WordsView.swift new file mode 100644 index 0000000..f83f4a4 --- /dev/null +++ b/AIGrammar/View/WordsView.swift @@ -0,0 +1,18 @@ +// +// WordsView.swift +// AIGrammar +// +// Created by oscar on 2024/3/27. +// + +import SwiftUI + +struct WordsView: View { + var body: some View { + Text(/*@START_MENU_TOKEN@*/"Hello, World!"/*@END_MENU_TOKEN@*/) + } +} + +#Preview { + WordsView() +} diff --git a/AIGrammar/ViewModel/Config.swift b/AIGrammar/ViewModel/Config.swift new file mode 100644 index 0000000..f29b2d0 --- /dev/null +++ b/AIGrammar/ViewModel/Config.swift @@ -0,0 +1,8 @@ +// +// config.swift +// AIGrammar +// +// Created by oscar on 2024/3/28. +// + +import Foundation diff --git a/AIGrammar/ViewModel/GrammarData.swift b/AIGrammar/ViewModel/GrammarData.swift new file mode 100644 index 0000000..591bca5 --- /dev/null +++ b/AIGrammar/ViewModel/GrammarData.swift @@ -0,0 +1,22 @@ +// +// DemoData.swift +// AIGrammar +// +// Created by oscar on 2024/4/2. +// + +import Foundation + +struct GrammarRes { + var tPlain : String + var tType : String + var tReason : String + var tCorrection : [String] +} + +struct GrammarData { + var tInputText : String + var tCorrectText : String + var tResult : [GrammarRes] +} + diff --git a/AIGrammar/lib/ColorToString.swift b/AIGrammar/lib/ColorToString.swift new file mode 100644 index 0000000..a6070d6 --- /dev/null +++ b/AIGrammar/lib/ColorToString.swift @@ -0,0 +1,8 @@ +// +// ColorToString.swift +// AIGrammar +// +// Created by oscar on 2024/3/28. +// + +import Foundation diff --git a/AIGrammar/lib/CommFunc.swift b/AIGrammar/lib/CommFunc.swift new file mode 100644 index 0000000..3115377 --- /dev/null +++ b/AIGrammar/lib/CommFunc.swift @@ -0,0 +1,8 @@ +// +// CommFunc.swift +// AIGrammar +// +// Created by oscar on 2024/8/5. +// + +import Foundation diff --git a/AIGrammar/lib/IapManager.swift b/AIGrammar/lib/IapManager.swift new file mode 100644 index 0000000..c308a8e --- /dev/null +++ b/AIGrammar/lib/IapManager.swift @@ -0,0 +1,8 @@ +// +// Iap.swift +// AIGrammar +// +// Created by oscar on 2024/7/3. +// + +import Foundation diff --git a/AIGrammar/lib/InitAPP.swift b/AIGrammar/lib/InitAPP.swift new file mode 100644 index 0000000..04161a6 --- /dev/null +++ b/AIGrammar/lib/InitAPP.swift @@ -0,0 +1,10 @@ +// +// InitAPP.swift +// AIGrammar +// +// Created by oscar on 2024/6/26. +// + +import Foundation + + diff --git a/AIGrammar/lib/LogManager.swift b/AIGrammar/lib/LogManager.swift new file mode 100644 index 0000000..3fb527a --- /dev/null +++ b/AIGrammar/lib/LogManager.swift @@ -0,0 +1,8 @@ +// +// LogManager.swift +// AIGrammar +// +// Created by oscar on 2024/7/3. +// + +import Foundation diff --git a/AIGrammar/lib/NetworkManager.swift b/AIGrammar/lib/NetworkManager.swift new file mode 100644 index 0000000..a73c3be --- /dev/null +++ b/AIGrammar/lib/NetworkManager.swift @@ -0,0 +1,233 @@ +// +// request.swift +// AIGrammar +// +// Created by oscar on 2024/6/4. +// + +import Foundation +import Alamofire +import SwiftJWT +import SwiftyBeaver + +struct MyClaims: Claims { + var deviceID: String + var gid: Int + var exp1: Int +} + +struct APIResponse: Decodable { + let ret: Int + let message: String + let data: T? +} + +struct Translation: Identifiable, Codable, Equatable { + var id = UUID() + var input: String + var translation: String +} + +struct TranslationResponse: Codable { + let translation: String +} + +struct WordDetails { + var word: String = "" + var explanations: [String] = [] + var phrases: [String] = [] + var synonyms: [String] = [] +} + +struct WordDetailsResponse: Codable { + let word: String + let explain: [String]? + let phrase: [String]? + let sync: [String]? + + // Mapping to WordDetails for use in UI + func toWordDetails() -> WordDetails { + return WordDetails( + word: word, + explanations: explain ?? [], + phrases: phrase ?? [], + synonyms: sync ?? [] + ) + } +} + +struct VIPStatusResponse: Codable { + let id: Int + let userid: String + let username: String + let vip: Int +} + + +struct NetworkManager { + static let shared = NetworkManager() + private let jwtSecret = globalEnvironment.jwtSecret + + // 语法检查功能 + func checkGrammar(inputText: String, completion: @escaping ([GrammarRes]?, Error?) -> Void) { + let url = globalEnvironment.grammarURL + let headers: HTTPHeaders = createAuthorizationHeader() + + let parameters: [String: Any] = [ + "input": inputText, + "lang": "eng" + ] + AF.request(url, method: .post, parameters: parameters, encoding: URLEncoding.httpBody, headers: headers) + .responseDecodable(of: [GrammarRes].self) { response in + switch response.result { + case .success(let results): + completion(results, nil) + case .failure(let error): + completion(nil, error) + } + } + } + + // 单词的词典功能 + func fetchWordDetails(inputText: String, lang: String = "eng", completion: @escaping (Result) -> Void) { + + guard !inputText.isEmpty else { return } + let parameters: [String: Any] = ["input": inputText, "lang": lang] + let url = globalEnvironment.dictURL + let headers: HTTPHeaders = createAuthorizationHeader() + + AF.request(url, method: .post, parameters: parameters, encoding: URLEncoding.httpBody, headers: headers) + .responseDecodable(of: WordDetailsResponse.self) { response in + switch response.result { + case .success(let detailsResponse): + print("Success: Received data for \(detailsResponse.word)") + let details = detailsResponse.toWordDetails() // Convert here + completion(.success(details)) + case .failure(let error): + print("Error: \(error)") + print("Response Data: \(String(data: response.data ?? Data(), encoding: .utf8) ?? "No data")") + + completion(.failure(error)) + } + } + } + + // 翻译功能 + func translate(inputText: String, lang: String = "chs", completion: @escaping (Result) -> Void) { + + guard !inputText.isEmpty else { return } + let url = globalEnvironment.translateURL + let parameters: [String: Any] = ["input": inputText, "lang": lang] + let headers: HTTPHeaders = createAuthorizationHeader() + + AF.request(url, method: .post, parameters: parameters, encoding: URLEncoding.httpBody, headers: headers) + .responseDecodable(of: TranslationResponse.self) { response in + switch response.result { + case .success(let translationResponse): + let newTranslation = Translation(input: inputText, translation: translationResponse.translation) + completion(.success(newTranslation)) + case .failure(let error): + completion(.failure(error)) + } + } + } + + // 翻译的点赞、点踩功能 + func sendFeedback(input: String, output: String, isPositive: Bool) { + let url = globalEnvironment.feedbackURL + let parameters: [String: Any] = [ + "product": "trans", + "input": input, + "output": output, + "res": isPositive ? "good" : "bad" + ] + + let headers: HTTPHeaders = createAuthorizationHeader() + AF.request(url, method: .post, parameters: parameters, encoding: URLEncoding.httpBody, headers: headers).response { response in + switch response.result { + case .success(let data): + print("Feedback sent successfully: \(String(describing: data))") + case .failure(let error): + print("Error sending feedback: \(error)") + } + } + + } + + // 查询VIP状态 + func getUserProfile(completion: @escaping (Result) -> Void) { + let url = globalEnvironment.userURL + + let parameters: [String: Any] = [:] + let headers: HTTPHeaders = createAuthorizationHeader() + + performRequest( + endpoint: url, + parameters: parameters, + method: .post, + encoding: URLEncoding.httpBody, + headers: headers, // 示例:使用JWT token + completion: { (result: Result) in + switch result { + case .success(let vipData): + logger.info("VIP Status: \(vipData.vip)") + completion(.success(vipData)) + case .failure(let error): + logger.error("Error: \(error.localizedDescription)") + completion(.failure(error)) + } + } + ) + + } + + func performRequest( + endpoint: String, + parameters: Parameters, // 明确使用 Alamofire 的 Parameters 类型 + method: HTTPMethod = .post, + encoding: URLEncoding = .httpBody, + headers: HTTPHeaders? = nil, + completion: @escaping (Result) -> Void + ) { + let url = endpoint + let defaultHeaders: HTTPHeaders = [.contentType("application/x-www-form-urlencoded")] + let combinedHeaders = headers ?? defaultHeaders + + // 确保参数是正确的类型 + AF.request(url, method: .post, parameters: parameters, encoding: encoding, headers: combinedHeaders).responseDecodable(of: APIResponse.self) { response in + switch response.result { + case .success(let apiResponse): + if apiResponse.ret == 0, let data = apiResponse.data { + completion(.success(data)) + } else { + let error = NSError(domain: "", code: apiResponse.ret, userInfo: [NSLocalizedDescriptionKey: apiResponse.message]) + completion(.failure(error)) + } + case .failure(let error): + completion(.failure(error)) + } + } + } + + private func createAuthorizationHeader() -> HTTPHeaders { + // Generate JWT and return headers + guard let jwtToken = generateJWT(deviceID: globalEnvironment.deviceID, gID: globalEnvironment.GID, jwtSecret: jwtSecret) else { + return [:] + } + return ["Authorization": "Bearer \(jwtToken)"] + } + + private func generateJWT(deviceID: String, gID: Int, jwtSecret: String) -> String? { + let claims = MyClaims(deviceID: deviceID, gid: gID, exp1: Int(Date().timeIntervalSince1970) + 86400) + var jwt = JWT(claims: claims) + do { + let jwtSigner = JWTSigner.hs256(key: Data(jwtSecret.utf8)) + let signedJWT = try jwt.sign(using: jwtSigner) + return signedJWT + } catch { + logger.error("JWT encoding failed with error: \(error)") + return nil + } + } +} +