From 00ebf5a4a89bd49cb05ed8cd20758c3671786adc Mon Sep 17 00:00:00 2001 From: "hsj._.06" Date: Thu, 5 Oct 2023 14:37:19 +0900 Subject: [PATCH 01/15] =?UTF-8?q?fix=20::=20XCConfig=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- XCConfig/Environment/DEV.xcconfig | 3 +++ XCConfig/Environment/PROD.xcconfig | 3 +++ XCConfig/Environment/STAGE.xcconfig | 3 +++ XCConfig/JOBIS-DSM-iOS/DEV.xcconfig | 3 --- XCConfig/JOBIS-DSM-iOS/PROD.xcconfig | 3 --- XCConfig/JOBIS-DSM-iOS/STAGE.xcconfig | 3 --- 6 files changed, 9 insertions(+), 9 deletions(-) create mode 100644 XCConfig/Environment/DEV.xcconfig create mode 100644 XCConfig/Environment/PROD.xcconfig create mode 100644 XCConfig/Environment/STAGE.xcconfig diff --git a/XCConfig/Environment/DEV.xcconfig b/XCConfig/Environment/DEV.xcconfig new file mode 100644 index 00000000..ee4808c6 --- /dev/null +++ b/XCConfig/Environment/DEV.xcconfig @@ -0,0 +1,3 @@ +#include "../Shared.xcconfig" +API_BASE_URL = https:/$()/dev-server.team-return.com +S3_BASE_URL = https:/$()/jobis-store.s3.ap-northeast-2.amazonaws.com diff --git a/XCConfig/Environment/PROD.xcconfig b/XCConfig/Environment/PROD.xcconfig new file mode 100644 index 00000000..1f1a48fa --- /dev/null +++ b/XCConfig/Environment/PROD.xcconfig @@ -0,0 +1,3 @@ +#include "../Shared.xcconfig" +API_BASE_URL = https:/$()/prod-server.team-return.com +S3_BASE_URL = https:/$()/jobis-store.s3.ap-northeast-2.amazonaws.com diff --git a/XCConfig/Environment/STAGE.xcconfig b/XCConfig/Environment/STAGE.xcconfig new file mode 100644 index 00000000..ee4808c6 --- /dev/null +++ b/XCConfig/Environment/STAGE.xcconfig @@ -0,0 +1,3 @@ +#include "../Shared.xcconfig" +API_BASE_URL = https:/$()/dev-server.team-return.com +S3_BASE_URL = https:/$()/jobis-store.s3.ap-northeast-2.amazonaws.com diff --git a/XCConfig/JOBIS-DSM-iOS/DEV.xcconfig b/XCConfig/JOBIS-DSM-iOS/DEV.xcconfig index f307d892..cc342c48 100644 --- a/XCConfig/JOBIS-DSM-iOS/DEV.xcconfig +++ b/XCConfig/JOBIS-DSM-iOS/DEV.xcconfig @@ -1,6 +1,3 @@ #include "../Shared.xcconfig" BUNDLE_DISPLAY_NAME = JOBIS (dev) - APP_BUNDLE_ID = com.team.return.JOBIS-DSM-iOS.dev -API_BASE_URL = https:/$()/dev-server.team-return.com -S3_BASE_URL = https:/$()/jobis-store.s3.ap-northeast-2.amazonaws.com/ diff --git a/XCConfig/JOBIS-DSM-iOS/PROD.xcconfig b/XCConfig/JOBIS-DSM-iOS/PROD.xcconfig index 0d91ae2a..9e1254d1 100644 --- a/XCConfig/JOBIS-DSM-iOS/PROD.xcconfig +++ b/XCConfig/JOBIS-DSM-iOS/PROD.xcconfig @@ -1,6 +1,3 @@ #include "../Shared.xcconfig" BUNDLE_DISPLAY_NAME = JOBIS - APP_BUNDLE_ID = com.team.return.JOBIS-DSM-iOS -API_BASE_URL = https:/$()/prod-server.team-return.com -S3_BASE_URL = https:/$()/jobis-store.s3.ap-northeast-2.amazonaws.com/ diff --git a/XCConfig/JOBIS-DSM-iOS/STAGE.xcconfig b/XCConfig/JOBIS-DSM-iOS/STAGE.xcconfig index 416ee0fe..467dd35a 100644 --- a/XCConfig/JOBIS-DSM-iOS/STAGE.xcconfig +++ b/XCConfig/JOBIS-DSM-iOS/STAGE.xcconfig @@ -1,6 +1,3 @@ #include "../Shared.xcconfig" BUNDLE_DISPLAY_NAME = JOBIS (stage) - APP_BUNDLE_ID = com.team.return.JOBIS-DSM-iOS.stage -API_BASE_URL = https:/$()/dev-server.team-return.com -S3_BASE_URL = https:/$()/jobis-store.s3.ap-northeast-2.amazonaws.com/ From 8230ffb1cbe693b77dd3735d57cef140cba0583d Mon Sep 17 00:00:00 2001 From: "hsj._.06" Date: Thu, 5 Oct 2023 14:41:20 +0900 Subject: [PATCH 02/15] feat :: Shared.Environment --- .../Dependency+Target.swift | 4 +++ .../ModulePaths.swift | 1 + Projects/Shared/DesignSystem/Project.swift | 5 +++- .../DesignSystem/Sources/Image/URLImage.swift | 13 +++------- Projects/Shared/Environment/Project.swift | 14 +++++++++++ .../Environment/Sources/Environment.swift | 25 +++++++++++++++++++ 6 files changed, 52 insertions(+), 10 deletions(-) create mode 100644 Projects/Shared/Environment/Project.swift create mode 100644 Projects/Shared/Environment/Sources/Environment.swift diff --git a/Plugin/DependencyPlugin/ProjectDescriptionHelpers/Dependency+Target.swift b/Plugin/DependencyPlugin/ProjectDescriptionHelpers/Dependency+Target.swift index 4d2d5701..fd7258dd 100644 --- a/Plugin/DependencyPlugin/ProjectDescriptionHelpers/Dependency+Target.swift +++ b/Plugin/DependencyPlugin/ProjectDescriptionHelpers/Dependency+Target.swift @@ -282,6 +282,10 @@ public extension TargetDependency.Core { } public extension TargetDependency.Shared { + static let Environment = TargetDependency.project( + target: ModulePaths.Shared.Environment.targetName(type: .sources), + path: .relativeToShared(ModulePaths.Shared.Environment.rawValue) + ) static let DesignSystem = TargetDependency.project( target: ModulePaths.Shared.DesignSystem.targetName(type: .sources), path: .relativeToShared(ModulePaths.Shared.DesignSystem.rawValue) diff --git a/Plugin/DependencyPlugin/ProjectDescriptionHelpers/ModulePaths.swift b/Plugin/DependencyPlugin/ProjectDescriptionHelpers/ModulePaths.swift index b20ef8bd..9b0c6c9c 100644 --- a/Plugin/DependencyPlugin/ProjectDescriptionHelpers/ModulePaths.swift +++ b/Plugin/DependencyPlugin/ProjectDescriptionHelpers/ModulePaths.swift @@ -65,6 +65,7 @@ public extension ModulePaths { public extension ModulePaths { enum Shared: String { + case Environment case DesignSystem case UtilityModule case GlobalThirdPartyLibrary diff --git a/Projects/Shared/DesignSystem/Project.swift b/Projects/Shared/DesignSystem/Project.swift index 59e373a1..b689751c 100644 --- a/Projects/Shared/DesignSystem/Project.swift +++ b/Projects/Shared/DesignSystem/Project.swift @@ -6,7 +6,10 @@ let project = Project.makeModule( name: ModulePaths.Shared.DesignSystem.rawValue, product: .framework, targets: [.demo], - externalDependencies: [.SPM.Kingfisher], + externalDependencies: [ + .SPM.Kingfisher, + .Shared.Environment + ], resources: ["Resources/**"], additionalPlistRows: [ "S3_BASE_URL": .string("$(S3_BASE_URL)") diff --git a/Projects/Shared/DesignSystem/Sources/Image/URLImage.swift b/Projects/Shared/DesignSystem/Sources/Image/URLImage.swift index 3baca499..c1b31296 100644 --- a/Projects/Shared/DesignSystem/Sources/Image/URLImage.swift +++ b/Projects/Shared/DesignSystem/Sources/Image/URLImage.swift @@ -1,5 +1,6 @@ import SwiftUI import Kingfisher +import Environment public struct URLImage: View { public enum ImageShape { @@ -11,16 +12,10 @@ public struct URLImage: View { let shape: ImageShape public init(imageURL urlString: String, shape: ImageShape) { - let baseURL = Bundle.main.object(forInfoDictionaryKey: "S3_BASE_URL") as? String ?? "" - - if let encoded = (baseURL + urlString) - .addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed), - let imageURL = URL(string: encoded) { - self.imageURL = imageURL - } else { - self.imageURL = URL(string: urlString) + var baseURL: URL { + Environment.getUrlValue(key: .s3BaseUrl) ?? URL(string: "https://www.google.com")! } - + self.imageURL = baseURL.appendingPathComponent(urlString) self.shape = shape } diff --git a/Projects/Shared/Environment/Project.swift b/Projects/Shared/Environment/Project.swift new file mode 100644 index 00000000..71e7c1de --- /dev/null +++ b/Projects/Shared/Environment/Project.swift @@ -0,0 +1,14 @@ +import ProjectDescription +import ProjectDescriptionHelpers +import DependencyPlugin + +let project = Project.makeModule( + name: ModulePaths.Shared.Environment.rawValue, + product: .framework, + targets: [], + internalDependencies: [], + additionalPlistRows: [ + "API_BASE_URL": .string("$(API_BASE_URL)"), + "S3_BASE_URL": .string("$(S3_BASE_URL)") + ] +) diff --git a/Projects/Shared/Environment/Sources/Environment.swift b/Projects/Shared/Environment/Sources/Environment.swift new file mode 100644 index 00000000..ad307691 --- /dev/null +++ b/Projects/Shared/Environment/Sources/Environment.swift @@ -0,0 +1,25 @@ +import Foundation + +public enum Environment { + + // MARK: - Keys + public enum UrlKeys: String { + case apiBaseUrl = "API_BASE_URL" + case s3BaseUrl = "S3_BASE_URL" + } + + // MARK: - Plist + private static let infoDictionary: [String: Any] = { + guard let dict = Bundle(identifier: "com.team.return.Environment")?.infoDictionary else { + fatalError("Plist file not found") + } + + return dict + }() + + // MARK: - Get Value + public static func getUrlValue(key: Environment.UrlKeys) -> URL? { + return URL(string: Environment.infoDictionary[key.rawValue] as? String ?? "") + } + +} From d3c8596a47df492a1a22099705a7590576e41c1f Mon Sep 17 00:00:00 2001 From: "hsj._.06" Date: Thu, 5 Oct 2023 14:42:01 +0900 Subject: [PATCH 03/15] =?UTF-8?q?feat=20::=20Environment=20=EC=A0=81?= =?UTF-8?q?=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Projects/App/Support/Info.plist | 2 -- .../BaseDomain/Derived/InfoPlists/BaseDomain-Info.plist | 2 -- Projects/Domain/BaseDomain/Project.swift | 6 ++---- Projects/Domain/BaseDomain/Sources/JobisAPI.swift | 5 ++--- 4 files changed, 4 insertions(+), 11 deletions(-) diff --git a/Projects/App/Support/Info.plist b/Projects/App/Support/Info.plist index c00d7dd6..a9de19e2 100644 --- a/Projects/App/Support/Info.plist +++ b/Projects/App/Support/Info.plist @@ -4,8 +4,6 @@ AppIdentifierPrefix $(AppIdentifierPrefix) - BASE_URL - $(API_BASE_URL) CFBundleDevelopmentRegion $(DEVELOPMENT_LANGUAGE) CFBundleDisplayName diff --git a/Projects/Domain/BaseDomain/Derived/InfoPlists/BaseDomain-Info.plist b/Projects/Domain/BaseDomain/Derived/InfoPlists/BaseDomain-Info.plist index ef76a48a..323e5ecf 100644 --- a/Projects/Domain/BaseDomain/Derived/InfoPlists/BaseDomain-Info.plist +++ b/Projects/Domain/BaseDomain/Derived/InfoPlists/BaseDomain-Info.plist @@ -2,8 +2,6 @@ - BASE_URL - $(API_BASE_URL) CFBundleDevelopmentRegion $(DEVELOPMENT_LANGUAGE) CFBundleExecutable diff --git a/Projects/Domain/BaseDomain/Project.swift b/Projects/Domain/BaseDomain/Project.swift index b944e364..37b6274e 100644 --- a/Projects/Domain/BaseDomain/Project.swift +++ b/Projects/Domain/BaseDomain/Project.swift @@ -13,9 +13,7 @@ let project = Project.makeModule( internalDependencies: [ .Core.JwtStoreInterface, .Shared.GlobalThirdPartyLibrary, - .Shared.UtilityModule - ], - additionalPlistRows: [ - "BASE_URL": .string("$(API_BASE_URL)") + .Shared.UtilityModule, + .Shared.Environment ] ) diff --git a/Projects/Domain/BaseDomain/Sources/JobisAPI.swift b/Projects/Domain/BaseDomain/Sources/JobisAPI.swift index 98b59cd5..b0e06d1a 100644 --- a/Projects/Domain/BaseDomain/Sources/JobisAPI.swift +++ b/Projects/Domain/BaseDomain/Sources/JobisAPI.swift @@ -1,5 +1,6 @@ import Foundation import Moya +import Environment public protocol JobisAPI: TargetType, JwtAuthorizable { associatedtype ErrorType: Error @@ -10,9 +11,7 @@ public protocol JobisAPI: TargetType, JwtAuthorizable { public extension JobisAPI { var baseURL: URL { - URL( - string: Bundle.main.object(forInfoDictionaryKey: "BASE_URL") as? String ?? "" - ) ?? URL(string: "https://www.google.com")! + Environment.getUrlValue(key: .apiBaseUrl) ?? URL(string: "https://www.google.com")! } var path: String { From 643df22cc38960c2a0f2460ae97034e83e0096fe Mon Sep 17 00:00:00 2001 From: "hsj._.06" Date: Thu, 5 Oct 2023 14:42:15 +0900 Subject: [PATCH 04/15] =?UTF-8?q?feat=20::=20=EC=BA=90=EC=8B=9C=20?= =?UTF-8?q?=EC=A0=9C=EA=B1=B0=20=EB=AA=85=EB=A0=B9=EC=96=B4=20=EB=A7=8C?= =?UTF-8?q?=EB=93=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Makefile | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Makefile b/Makefile index a5491254..94638536 100644 --- a/Makefile +++ b/Makefile @@ -10,6 +10,9 @@ clean: rm -rf **/*.xcodeproj rm -rf *.xcworkspace +cache_clean: + rm -rf ~/Library/Developer/Xcode/DerivedData/* + reset: tuist clean rm -rf **/*.xcodeproj From cd185f1437cdb7561142c4b9ad0aded59eef8a1f Mon Sep 17 00:00:00 2001 From: "hsj._.06" Date: Thu, 5 Oct 2023 14:56:21 +0900 Subject: [PATCH 05/15] =?UTF-8?q?refactoring=20::=20=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=EA=B0=84=ED=8E=B8=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Projects/Domain/BaseDomain/Sources/JobisAPI.swift | 4 +--- .../Shared/DesignSystem/Sources/Image/URLImage.swift | 4 +--- Projects/Shared/Environment/Sources/Environment.swift | 11 +++++++++-- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/Projects/Domain/BaseDomain/Sources/JobisAPI.swift b/Projects/Domain/BaseDomain/Sources/JobisAPI.swift index b0e06d1a..3926371e 100644 --- a/Projects/Domain/BaseDomain/Sources/JobisAPI.swift +++ b/Projects/Domain/BaseDomain/Sources/JobisAPI.swift @@ -10,9 +10,7 @@ public protocol JobisAPI: TargetType, JwtAuthorizable { } public extension JobisAPI { - var baseURL: URL { - Environment.getUrlValue(key: .apiBaseUrl) ?? URL(string: "https://www.google.com")! - } + var baseURL: URL { Environment.getUrlValue(key: .apiBaseUrl) } var path: String { domain.asURLString + urlPath diff --git a/Projects/Shared/DesignSystem/Sources/Image/URLImage.swift b/Projects/Shared/DesignSystem/Sources/Image/URLImage.swift index c1b31296..5091e961 100644 --- a/Projects/Shared/DesignSystem/Sources/Image/URLImage.swift +++ b/Projects/Shared/DesignSystem/Sources/Image/URLImage.swift @@ -12,9 +12,7 @@ public struct URLImage: View { let shape: ImageShape public init(imageURL urlString: String, shape: ImageShape) { - var baseURL: URL { - Environment.getUrlValue(key: .s3BaseUrl) ?? URL(string: "https://www.google.com")! - } + var baseURL: URL { Environment.getUrlValue(key: .s3BaseUrl) } self.imageURL = baseURL.appendingPathComponent(urlString) self.shape = shape } diff --git a/Projects/Shared/Environment/Sources/Environment.swift b/Projects/Shared/Environment/Sources/Environment.swift index ad307691..382252d0 100644 --- a/Projects/Shared/Environment/Sources/Environment.swift +++ b/Projects/Shared/Environment/Sources/Environment.swift @@ -18,8 +18,15 @@ public enum Environment { }() // MARK: - Get Value - public static func getUrlValue(key: Environment.UrlKeys) -> URL? { - return URL(string: Environment.infoDictionary[key.rawValue] as? String ?? "") + public static func getUrlValue(key: Environment.UrlKeys) -> URL { + guard let urlString = Environment + .infoDictionary[key.rawValue] as? String else { + fatalError("Plist url not found") + } + guard let url = URL(string: urlString) else { + fatalError("\(key.rawValue) is not URL") + } + return url } } From 7d919a000530fc31b93a6ee328b16feb3043fdfd Mon Sep 17 00:00:00 2001 From: "hsj._.06" Date: Thu, 5 Oct 2023 23:21:13 +0900 Subject: [PATCH 06/15] =?UTF-8?q?fix=20::=20STAGE=20URL=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- XCConfig/Environment/STAGE.xcconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/XCConfig/Environment/STAGE.xcconfig b/XCConfig/Environment/STAGE.xcconfig index ee4808c6..1f1a48fa 100644 --- a/XCConfig/Environment/STAGE.xcconfig +++ b/XCConfig/Environment/STAGE.xcconfig @@ -1,3 +1,3 @@ #include "../Shared.xcconfig" -API_BASE_URL = https:/$()/dev-server.team-return.com +API_BASE_URL = https:/$()/prod-server.team-return.com S3_BASE_URL = https:/$()/jobis-store.s3.ap-northeast-2.amazonaws.com From 15ce6470b9b5c533a00212b72e980d7ec2aecdc2 Mon Sep 17 00:00:00 2001 From: "hsj._.06" Date: Thu, 5 Oct 2023 23:22:12 +0900 Subject: [PATCH 07/15] =?UTF-8?q?fix=20::=20Textfield=20placeholder=20zind?= =?UTF-8?q?ex=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Form/DeleteableJOBISFormTextField.swift | 19 ++++++-------- .../TextField/Form/JOBISFormTextEditor.swift | 20 +++++++------- .../TextField/Form/JOBISFormTextField.swift | 22 ++++++++-------- .../Form/SearchJOBISFormTextField.swift | 26 +++++++++---------- .../Form/SecureJOBISFormTextField.swift | 26 +++++++++---------- 5 files changed, 55 insertions(+), 58 deletions(-) diff --git a/Projects/Shared/DesignSystem/Sources/Input/TextField/Form/DeleteableJOBISFormTextField.swift b/Projects/Shared/DesignSystem/Sources/Input/TextField/Form/DeleteableJOBISFormTextField.swift index c925f853..ff9a9bc7 100644 --- a/Projects/Shared/DesignSystem/Sources/Input/TextField/Form/DeleteableJOBISFormTextField.swift +++ b/Projects/Shared/DesignSystem/Sources/Input/TextField/Form/DeleteableJOBISFormTextField.swift @@ -25,6 +25,13 @@ public struct DeleteableJOBISFormTextField: View { public var body: some View { ZStack(alignment: .leading) { + Text(label) + .JOBISFont( + .body(.body4), + color: isEnabled ? .Sub.gray60 : .Sub.gray50 + ) + .opacity(text.isEmpty ? 1 : 0) + HStack { TextField("", text: $text) .JOBISFont( @@ -41,16 +48,6 @@ public struct DeleteableJOBISFormTextField: View { .foregroundColor(.Sub.gray90) } } - - Text(label) - .JOBISFont( - .body(.body4), - color: isEnabled ? .Sub.gray60 : .Sub.gray50 - ) - .opacity(text.isEmpty ? 1 : 0) - .onTapGesture { - isFocused = true - } } .padding(.vertical, 10) .padding(.horizontal, 12) @@ -65,7 +62,7 @@ public struct DeleteableJOBISFormTextField: View { lineWidth: 1 ) } - .animation(.easeIn(duration: 0.3), value: isFocused) + .animation(.easeIn(duration: 0.2), value: isFocused) } } diff --git a/Projects/Shared/DesignSystem/Sources/Input/TextField/Form/JOBISFormTextEditor.swift b/Projects/Shared/DesignSystem/Sources/Input/TextField/Form/JOBISFormTextEditor.swift index 01e89c73..8d16ea82 100644 --- a/Projects/Shared/DesignSystem/Sources/Input/TextField/Form/JOBISFormTextEditor.swift +++ b/Projects/Shared/DesignSystem/Sources/Input/TextField/Form/JOBISFormTextEditor.swift @@ -19,6 +19,15 @@ public struct JOBISFormTextEditor: View { public var body: some View { ZStack(alignment: .topLeading) { + Text(placeholder) + .JOBISFont( + .body(.body4), + color: isEnabled ? .Sub.gray60 : .Sub.gray50 + ) + .opacity(text.isEmpty ? 1 : 0) + .padding(.top, 10) + .padding(.leading, 12) + TextEditor(text: $text) .JOBISFont( .body(.body4), @@ -30,15 +39,6 @@ public struct JOBISFormTextEditor: View { isEnabled ? Color.Sub.gray10 : .Sub.gray30 ) - - Text(placeholder) - .JOBISFont( - .body(.body4), - color: isEnabled ? .Sub.gray60 : .Sub.gray50 - ) - .opacity(text.isEmpty ? 1 : 0) - .padding(.top, 10) - .padding(.leading, 12) } .frame(minHeight: minHeight) .overlay( @@ -52,7 +52,7 @@ public struct JOBISFormTextEditor: View { isEnabled ? Color.Sub.gray10 : .Sub.gray30 ) - .animation(.easeIn(duration: 0.3), value: isFocused) + .animation(.easeIn(duration: 0.2), value: isFocused) } } diff --git a/Projects/Shared/DesignSystem/Sources/Input/TextField/Form/JOBISFormTextField.swift b/Projects/Shared/DesignSystem/Sources/Input/TextField/Form/JOBISFormTextField.swift index 75678afb..1b003ca2 100644 --- a/Projects/Shared/DesignSystem/Sources/Input/TextField/Form/JOBISFormTextField.swift +++ b/Projects/Shared/DesignSystem/Sources/Input/TextField/Form/JOBISFormTextField.swift @@ -28,14 +28,6 @@ public struct JOBISFormTextField: View { public var body: some View { ZStack(alignment: .leading) { - TextField("", text: $text) - .JOBISFont( - .body(.body4), - color: isEnabled ? .Sub.gray90 : .Sub.gray50 - ) - .focused($isFocused) - .onSubmit(onCommit) - Text(label) .JOBISFont( .body(.body4), @@ -45,6 +37,14 @@ public struct JOBISFormTextField: View { .onTapGesture { isFocused = true } + + TextField("", text: $text) + .JOBISFont( + .body(.body4), + color: isEnabled ? .Sub.gray90 : .Sub.gray50 + ) + .focused($isFocused) + .onSubmit(onCommit) } .padding(.vertical, 10) .padding(.horizontal, 12) @@ -70,9 +70,9 @@ public struct JOBISFormTextField: View { .offset(y: 20) } } - .animation(.easeIn(duration: 0.3), value: isErrorAndNotEmpty) - .animation(.easeIn(duration: 0.3), value: isError) - .animation(.easeIn(duration: 0.3), value: isFocused) + .animation(.easeIn(duration: 0.2), value: isErrorAndNotEmpty) + .animation(.easeIn(duration: 0.2), value: isError) + .animation(.easeIn(duration: 0.2), value: isFocused) } } diff --git a/Projects/Shared/DesignSystem/Sources/Input/TextField/Form/SearchJOBISFormTextField.swift b/Projects/Shared/DesignSystem/Sources/Input/TextField/Form/SearchJOBISFormTextField.swift index f054619a..eb331b17 100644 --- a/Projects/Shared/DesignSystem/Sources/Input/TextField/Form/SearchJOBISFormTextField.swift +++ b/Projects/Shared/DesignSystem/Sources/Input/TextField/Form/SearchJOBISFormTextField.swift @@ -28,6 +28,16 @@ public struct SearchJOBISFormTextField: View { public var body: some View { ZStack(alignment: .leading) { + Text(label) + .JOBISFont( + .body(.body4), + color: isEnabled ? .Sub.gray60 : .Sub.gray50 + ) + .opacity(text.isEmpty ? 1 : 0) + .onTapGesture { + isFocused = true + } + HStack { TextField("", text: $text) .JOBISFont( @@ -46,16 +56,6 @@ public struct SearchJOBISFormTextField: View { ) } } - - Text(label) - .JOBISFont( - .body(.body4), - color: isEnabled ? .Sub.gray60 : .Sub.gray50 - ) - .opacity(text.isEmpty ? 1 : 0) - .onTapGesture { - isFocused = true - } } .padding(.vertical, 10) .padding(.horizontal, 12) @@ -81,9 +81,9 @@ public struct SearchJOBISFormTextField: View { .offset(y: 20) } } - .animation(.easeIn(duration: 0.3), value: isErrorAndNotEmpty) - .animation(.easeIn(duration: 0.3), value: isError) - .animation(.easeIn(duration: 0.3), value: isFocused) + .animation(.easeIn(duration: 0.2), value: isErrorAndNotEmpty) + .animation(.easeIn(duration: 0.2), value: isError) + .animation(.easeIn(duration: 0.2), value: isFocused) } } diff --git a/Projects/Shared/DesignSystem/Sources/Input/TextField/Form/SecureJOBISFormTextField.swift b/Projects/Shared/DesignSystem/Sources/Input/TextField/Form/SecureJOBISFormTextField.swift index 26b418f3..eab84fe3 100644 --- a/Projects/Shared/DesignSystem/Sources/Input/TextField/Form/SecureJOBISFormTextField.swift +++ b/Projects/Shared/DesignSystem/Sources/Input/TextField/Form/SecureJOBISFormTextField.swift @@ -29,6 +29,16 @@ public struct SecureJOBISFormTextField: View { public var body: some View { ZStack(alignment: .leading) { + Text(label) + .JOBISFont( + .body(.body4), + color: isEnabled ? .Sub.gray60 : .Sub.gray50 + ) + .opacity(text.isEmpty ? 1 : 0) + .onTapGesture { + isFocused = true + } + HStack { Group { if isSecure { @@ -56,16 +66,6 @@ public struct SecureJOBISFormTextField: View { ) } } - - Text(label) - .JOBISFont( - .body(.body4), - color: isEnabled ? .Sub.gray60 : .Sub.gray50 - ) - .opacity(text.isEmpty ? 1 : 0) - .onTapGesture { - isFocused = true - } } .padding(.vertical, 10) .padding(.horizontal, 12) @@ -91,9 +91,9 @@ public struct SecureJOBISFormTextField: View { .offset(y: 20) } } - .animation(.easeIn(duration: 0.3), value: isErrorAndNotEmpty) - .animation(.easeIn(duration: 0.3), value: isError) - .animation(.easeIn(duration: 0.3), value: isFocused) + .animation(.easeIn(duration: 0.2), value: isErrorAndNotEmpty) + .animation(.easeIn(duration: 0.2), value: isError) + .animation(.easeIn(duration: 0.2), value: isFocused) } } From e28ad8bde5ea9d4c5393379eafe2b44dbe5a3aec Mon Sep 17 00:00:00 2001 From: "hsj._.06" Date: Thu, 5 Oct 2023 23:22:35 +0900 Subject: [PATCH 08/15] =?UTF-8?q?feat=20::=20=EB=B3=91=ED=8A=B9=20?= =?UTF-8?q?=EC=95=84=EC=9D=B4=EC=BD=98=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Contents.json | 2 +- .../Frame 20767.svg | 5 +++++ .../MilitaryServiceExceptionImage.png | Bin 4933 -> 0 bytes 3 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 Projects/Shared/DesignSystem/Resources/Icons.xcassets/MilitaryServiceExceptionIcon.imageset/Frame 20767.svg delete mode 100644 Projects/Shared/DesignSystem/Resources/Icons.xcassets/MilitaryServiceExceptionIcon.imageset/MilitaryServiceExceptionImage.png diff --git a/Projects/Shared/DesignSystem/Resources/Icons.xcassets/MilitaryServiceExceptionIcon.imageset/Contents.json b/Projects/Shared/DesignSystem/Resources/Icons.xcassets/MilitaryServiceExceptionIcon.imageset/Contents.json index 38ae44e6..7643931f 100644 --- a/Projects/Shared/DesignSystem/Resources/Icons.xcassets/MilitaryServiceExceptionIcon.imageset/Contents.json +++ b/Projects/Shared/DesignSystem/Resources/Icons.xcassets/MilitaryServiceExceptionIcon.imageset/Contents.json @@ -1,7 +1,7 @@ { "images" : [ { - "filename" : "MilitaryServiceExceptionImage.png", + "filename" : "Frame 20767.svg", "idiom" : "universal", "scale" : "1x" }, diff --git a/Projects/Shared/DesignSystem/Resources/Icons.xcassets/MilitaryServiceExceptionIcon.imageset/Frame 20767.svg b/Projects/Shared/DesignSystem/Resources/Icons.xcassets/MilitaryServiceExceptionIcon.imageset/Frame 20767.svg new file mode 100644 index 00000000..3bdea7d4 --- /dev/null +++ b/Projects/Shared/DesignSystem/Resources/Icons.xcassets/MilitaryServiceExceptionIcon.imageset/Frame 20767.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/Projects/Shared/DesignSystem/Resources/Icons.xcassets/MilitaryServiceExceptionIcon.imageset/MilitaryServiceExceptionImage.png b/Projects/Shared/DesignSystem/Resources/Icons.xcassets/MilitaryServiceExceptionIcon.imageset/MilitaryServiceExceptionImage.png deleted file mode 100644 index 89b7e1f08c15580c9a666e4abc9390b6fb501691..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4933 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 D7AJb{ From 6bc340772cfacfc7fcc7317af6bb1adcabdd77ce Mon Sep 17 00:00:00 2001 From: "hsj._.06" Date: Thu, 5 Oct 2023 23:23:16 +0900 Subject: [PATCH 09/15] =?UTF-8?q?refactoring=20::=20=EC=93=B0=EC=A7=80=20?= =?UTF-8?q?=EC=95=8A=EB=8A=94=20Stack=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Sources/MyPage/MyPageView.swift | 32 ++++++++----------- 1 file changed, 14 insertions(+), 18 deletions(-) diff --git a/Projects/Feature/MyPageFeature/Sources/MyPage/MyPageView.swift b/Projects/Feature/MyPageFeature/Sources/MyPage/MyPageView.swift index a0254bb7..52963fef 100644 --- a/Projects/Feature/MyPageFeature/Sources/MyPage/MyPageView.swift +++ b/Projects/Feature/MyPageFeature/Sources/MyPage/MyPageView.swift @@ -36,25 +36,21 @@ struct MyPageView: View { ScrollView { VStack(spacing: 40) { HStack(spacing: 22) { - VStack { - ZStack(alignment: .bottomTrailing) { - Group { - URLImage( - imageURL: viewModel.studentInfo?.profileImageUrl ?? "", - shape: .square(85) - ) - } - .frame(width: 85, height: 85) + ZStack(alignment: .bottomTrailing) { + URLImage( + imageURL: viewModel.studentInfo?.profileImageUrl ?? "", + shape: .square(85) + ) + .frame(width: 85, height: 85) + .clipShape(Circle()) + + Image(systemName: "pencil.circle.fill") + .resizable() + .frame(width: 26, height: 26) + .foregroundColor(.Main.lightBlue) + .background(Color.white) .clipShape(Circle()) - - Image(systemName: "pencil.circle.fill") - .resizable() - .frame(width: 26, height: 26) - .foregroundColor(.Main.lightBlue) - .background(Color.white) - .clipShape(Circle()) - .unredacted() - } + .unredacted() } .onTapGesture { viewModel.isShowImagePicker.toggle() From 2c760559cd7dfb1a40135c8a16c00b51c2c83db9 Mon Sep 17 00:00:00 2001 From: "hsj._.06" Date: Thu, 5 Oct 2023 23:27:51 +0900 Subject: [PATCH 10/15] =?UTF-8?q?fix=20::=20RecruitmentDetailView=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Detail/RecruitmentDetailView.swift | 76 +++++++++---------- 1 file changed, 38 insertions(+), 38 deletions(-) diff --git a/Projects/Feature/RecruitmentFeature/Sources/Detail/RecruitmentDetailView.swift b/Projects/Feature/RecruitmentFeature/Sources/Detail/RecruitmentDetailView.swift index f3cc5940..103b90bf 100644 --- a/Projects/Feature/RecruitmentFeature/Sources/Detail/RecruitmentDetailView.swift +++ b/Projects/Feature/RecruitmentFeature/Sources/Detail/RecruitmentDetailView.swift @@ -25,58 +25,57 @@ struct RecruitmentDetailView: View { var body: some View { ZStack { if let detailInfo = viewModel.recruitmentDetail { - ScrollView { - LazyVStack(alignment: .leading, spacing: 10) { - HStack(spacing: 12) { - URLImage(imageURL: detailInfo.companyProfileUrl, shape: .square(80)) - .cornerRadius(15) - - Text(detailInfo.companyName) - .JOBISFont(.body(.body1), color: .Sub.gray90) - } - .padding(.bottom, 2) - if !isDetail { - GrayBtn(text: "기업 보기", size: .large) { - viewModel.isNavigateCompanyDetail.toggle() + VStack { + ScrollView { + LazyVStack(alignment: .leading, spacing: 10) { + HStack(spacing: 12) { + URLImage(imageURL: detailInfo.companyProfileUrl, shape: .square(80)) + .cornerRadius(15) + + Text(detailInfo.companyName) + .JOBISFont(.body(.body1), color: .Sub.gray90) + } + .padding(.bottom, 2) + + if !isDetail { + GrayBtn(text: "기업 보기", size: .large) { + viewModel.isNavigateCompanyDetail.toggle() + } + .navigate( + to: findCompanyDetailFactory.makeView( + id: String(detailInfo.companyID), + isDetail: true + ).eraseToAnyView(), + when: $viewModel.isNavigateCompanyDetail + ) } - .navigate( - to: findCompanyDetailFactory.makeView( - id: String(detailInfo.companyID), - isDetail: true - ).eraseToAnyView(), - when: $viewModel.isNavigateCompanyDetail - ) - } - Divider() - .foregroundColor(.Sub.gray40) + Divider() + .foregroundColor(.Sub.gray40) - VStack(alignment: .leading, spacing: 10) { - recruitmentInfoCell( - title: "모집기간", - content: detailInfo.startDate + " ~ " + detailInfo.endDate - ) + VStack(alignment: .leading, spacing: 10) { + recruitmentInfoCell( + title: "모집기간", + content: detailInfo.startDate + " ~ " + detailInfo.endDate + ) - areaView(areas: detailInfo.areas) + areaView(areas: detailInfo.areas) - ForEach(Array(zip(viewModel.titles, viewModel.contents)), id: \.0) { title, content in - recruitmentInfoCell(title: title, content: content) + ForEach(Array(zip(viewModel.titles, viewModel.contents)), id: \.0) { title, content in + recruitmentInfoCell(title: title, content: content) + } } } + .padding(.horizontal, 20) } - .padding(.bottom, 100) - .padding(.horizontal, 20) - } - - VStack { - Spacer() SolidBtn(text: "지원하기", size: .large) { viewModel.isTappedApplyButton.toggle() } + .padding(.vertical, 10) + .padding(.horizontal, 20) } - .padding(.horizontal, 20) Color.black .opacity(viewModel.isTappedApplyButton ? 0.2 : 0) @@ -100,6 +99,7 @@ struct RecruitmentDetailView: View { .frame(maxHeight: .infinity) } } + .frame(maxHeight: .infinity) .navigationBarTitleDisplayMode(.inline) .onAppear { viewModel.onAppear() From ab0ea710b26ccaef52ba14fa713c1441c7216965 Mon Sep 17 00:00:00 2001 From: "hsj._.06" Date: Thu, 5 Oct 2023 23:28:42 +0900 Subject: [PATCH 11/15] =?UTF-8?q?refactoring=20::=20=ED=9A=8C=EC=9B=90?= =?UTF-8?q?=EA=B0=80=EC=9E=85=20=EB=B7=B0=20=EC=84=B1=EB=8A=A5=20=EB=B0=8F?= =?UTF-8?q?=20=EB=94=94=EC=9E=90=EC=9D=B8=20=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Sources/InfoSetting/InfoSettingView.swift | 5 ++-- .../SignupEmailVerifyView.swift | 2 +- .../SignupPassword/SignupPasswordView.swift | 30 +++++++++---------- .../SignupFeature/Sources/SignupView.swift | 13 ++++---- .../Sources/SignupViewModel.swift | 24 ++++----------- 5 files changed, 30 insertions(+), 44 deletions(-) diff --git a/Projects/Feature/SignupFeature/Sources/InfoSetting/InfoSettingView.swift b/Projects/Feature/SignupFeature/Sources/InfoSetting/InfoSettingView.swift index ba199c51..21f85af7 100644 --- a/Projects/Feature/SignupFeature/Sources/InfoSetting/InfoSettingView.swift +++ b/Projects/Feature/SignupFeature/Sources/InfoSetting/InfoSettingView.swift @@ -20,13 +20,12 @@ struct InfoSettingView: View { } var body: some View { - VStack(alignment: .leading) { + VStack(alignment: .leading, spacing: 12) { Text("개인정보 입력") .JOBISFont(.heading(.heading5), color: .Sub.gray90) - .padding(.vertical, 32) + .padding(.vertical, 20) genderButton() - .padding(.bottom, 28) JOBISFormTextField( "이름을 입력하세요.", diff --git a/Projects/Feature/SignupFeature/Sources/SignupEmailVerify/SignupEmailVerifyView.swift b/Projects/Feature/SignupFeature/Sources/SignupEmailVerify/SignupEmailVerifyView.swift index f3bf9b4a..90aa5412 100644 --- a/Projects/Feature/SignupFeature/Sources/SignupEmailVerify/SignupEmailVerifyView.swift +++ b/Projects/Feature/SignupFeature/Sources/SignupEmailVerify/SignupEmailVerifyView.swift @@ -22,7 +22,7 @@ struct SignupEmailVerifyView: View { VStack(alignment: .leading, spacing: 0) { Text("이메일 인증") .JOBISFont(.heading(.heading5), color: .Sub.gray90) - .padding(.vertical, 45) + .padding(.vertical, 20) JOBISFormTextField( "이메일을 입력해주세요.", diff --git a/Projects/Feature/SignupFeature/Sources/SignupPassword/SignupPasswordView.swift b/Projects/Feature/SignupFeature/Sources/SignupPassword/SignupPasswordView.swift index 7712aefd..c4d172da 100644 --- a/Projects/Feature/SignupFeature/Sources/SignupPassword/SignupPasswordView.swift +++ b/Projects/Feature/SignupFeature/Sources/SignupPassword/SignupPasswordView.swift @@ -18,26 +18,26 @@ struct SignupPasswordView: View { } var body: some View { - VStack(alignment: .leading, spacing: 10) { + VStack(alignment: .leading, spacing: 12) { Text("비밀번호 설정") .JOBISFont(.heading(.heading5), color: .Sub.gray90) - .padding(.top, 45) + .padding(.vertical, 20) - Text("8 ~ 16자, 영문자, 숫자, 특수문자 포함") - .JOBISFont(.body(.body4), color: .Sub.gray60) - .padding(.bottom, 35) + VStack(alignment: .leading, spacing: 1) { + SecureJOBISFormTextField( + "비밀번호를 입력해주세요.", + text: $viewModel.password, + isError: viewModel.isPasswordRegexError, + errorMessage: "비밀번호 형식이 올바르지 않습니다." + ) { + focusField = .checkPassword + } + .focused($focusField, equals: .password) + .textContentType(.password) - SecureJOBISFormTextField( - "비밀번호를 입력해주세요.", - text: $viewModel.password, - isError: viewModel.isPasswordRegexError, - errorMessage: "비밀번호 형식이 올바르지 않습니다." - ) { - focusField = .checkPassword + Text("8 ~ 16자, 영문자, 숫자, 특수문자 포함") + .JOBISFont(.body(.body4), color: .Sub.gray60) } - .focused($focusField, equals: .password) - .textContentType(.password) - .padding(.bottom, 25) SecureJOBISFormTextField( "비밀번호를 다시 입력해주세요.", diff --git a/Projects/Feature/SignupFeature/Sources/SignupView.swift b/Projects/Feature/SignupFeature/Sources/SignupView.swift index 54c9032a..e3d924f6 100644 --- a/Projects/Feature/SignupFeature/Sources/SignupView.swift +++ b/Projects/Feature/SignupFeature/Sources/SignupView.swift @@ -34,7 +34,7 @@ struct SignupView: View { nextButton() } .padding(.horizontal, 26) - .animation(.default, value: viewModel.progressValue) + .animation(.default, value: viewModel.signupType) .jobisBackButton(title: "회원가입") { viewModel.backButtonDidTap { dismiss() @@ -74,18 +74,19 @@ struct SignupView: View { guard newValue else { return } appState.sceneFlow = .main } - .ignoresSafeArea(.keyboard, edges: .bottom) } @ViewBuilder func nextButton() -> some View { VStack(spacing: 0) { VStack(alignment: .trailing, spacing: 4) { - Text(String(viewModel.progressValue) + "/3") + Text(String(viewModel.signupType.rawValue) + "/4") .JOBISFont(.etc(.caption), color: .Sub.gray60) - ProgressView(value: Double(viewModel.progressValue)/3) - .progressViewStyle(LinearProgressViewStyle(tint: .Main.lightBlue)) + ProgressView( + value: Double(viewModel.signupType.rawValue)/Double(SignupViewModel.SignupType.infoAgree.rawValue) + ) + .progressViewStyle(LinearProgressViewStyle(tint: .Main.lightBlue)) } SolidBtn( @@ -106,7 +107,7 @@ struct SignupView: View { VStack(alignment: .leading) { Text("약관 동의") .JOBISFont(.heading(.heading1), color: .Sub.gray90) - .padding(.top, 24) + .padding(.vertical, 20) JOBISWebView(urlToLoad: url) .frame(maxWidth: .infinity, maxHeight: .infinity) diff --git a/Projects/Feature/SignupFeature/Sources/SignupViewModel.swift b/Projects/Feature/SignupFeature/Sources/SignupViewModel.swift index 950be9d9..779a3eb0 100644 --- a/Projects/Feature/SignupFeature/Sources/SignupViewModel.swift +++ b/Projects/Feature/SignupFeature/Sources/SignupViewModel.swift @@ -6,11 +6,11 @@ import UIKit import UtilityModule final class SignupViewModel: BaseViewModel { - enum SignupType { - case infoSetting - case emailVerify - case password - case infoAgree + enum SignupType: Int { + case infoSetting = 1 + case emailVerify = 2 + case password = 3 + case infoAgree = 4 } @Published var isSuccessSignup = false @Published var isAgreeTerms = false @@ -28,15 +28,6 @@ final class SignupViewModel: BaseViewModel { } } } - @Published var progressValue: Int = 0 { - didSet { - if progressValue > 3 { - progressValue -= 1 - } else if progressValue < 0 { - progressValue += 1 - } - } - } @Published var isMan: Bool = false { didSet { if self.isMan == true { @@ -157,15 +148,12 @@ final class SignupViewModel: BaseViewModel { case .emailVerify: signupType = .infoSetting - progressValue -= 1 case .password: signupType = .emailVerify - progressValue -= 1 case .infoAgree: signupType = .emailVerify - progressValue -= 1 } } @@ -193,7 +181,6 @@ final class SignupViewModel: BaseViewModel { verifyAuthCodeUseCase.execute(email: email, authCode: authCode) ) { [weak self] _ in self?.signupType = .password - self?.progressValue += 1 } onReceiveError: { [weak self] _ in self?.isAuthCodeError = true } @@ -211,7 +198,6 @@ final class SignupViewModel: BaseViewModel { studentExistsUseCase.execute(gcn: gcn, name: name) ) { [weak self] in self?.signupType = .emailVerify - self?.progressValue += 1 } onReceiveError: { [weak self] _ in self?.isInfoSettingError = true } From 1faf99a00040b84f780fe9079e2d84c7af4160fc Mon Sep 17 00:00:00 2001 From: "hsj._.06" Date: Fri, 6 Oct 2023 10:34:13 +0900 Subject: [PATCH 12/15] =?UTF-8?q?feat=20::=20bookmark=20onAppear=20?= =?UTF-8?q?=EC=8B=9C=20=EC=A7=80=EC=9B=8C=EC=A7=80=EB=8A=94=20=EB=B2=84?= =?UTF-8?q?=EA=B7=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Interface/Entity/RecruitmentEntity.swift | 2 +- .../Components/RecruitmentListCell.swift | 27 +++++++------- .../Sources/Recruitment/RecruitmentView.swift | 36 +++++++++---------- .../Recruitment/RecruitmentViewModel.swift | 6 ++-- 4 files changed, 35 insertions(+), 36 deletions(-) diff --git a/Projects/Domain/RecruitmentsDomain/Interface/Entity/RecruitmentEntity.swift b/Projects/Domain/RecruitmentsDomain/Interface/Entity/RecruitmentEntity.swift index f0edc278..f22afd7c 100644 --- a/Projects/Domain/RecruitmentsDomain/Interface/Entity/RecruitmentEntity.swift +++ b/Projects/Domain/RecruitmentsDomain/Interface/Entity/RecruitmentEntity.swift @@ -8,7 +8,7 @@ public struct RecruitmentEntity: Equatable, Hashable { public let military: Bool public let totalHiring: Int public let jobCodeList: String - public let bookmarked: Bool + public var bookmarked: Bool public init( recruitID: Int, diff --git a/Projects/Feature/RecruitmentFeature/Sources/Recruitment/Components/RecruitmentListCell.swift b/Projects/Feature/RecruitmentFeature/Sources/Recruitment/Components/RecruitmentListCell.swift index e617885c..5f32efd9 100644 --- a/Projects/Feature/RecruitmentFeature/Sources/Recruitment/Components/RecruitmentListCell.swift +++ b/Projects/Feature/RecruitmentFeature/Sources/Recruitment/Components/RecruitmentListCell.swift @@ -5,23 +5,26 @@ import DesignSystem import Kingfisher struct RecruitmentListCell: View { - @State private var isBookmarked: Bool = false - let recruitmentEntity: RecruitmentEntity + @Binding var recruitmentEntitys: [RecruitmentEntity] + let index: Int let bookmark: () -> Void private let recruitmentDetailFactory: any RecruitmentDetailFactory init( - recruitmentEntity: RecruitmentEntity, + recruitmentEntitys: Binding<[RecruitmentEntity]>, + index: Int, recruitmentDetailFactory: any RecruitmentDetailFactory, bookmark: @escaping () -> Void ) { - self.recruitmentEntity = recruitmentEntity + _recruitmentEntitys = recruitmentEntitys + self.index = index self.bookmark = bookmark self.recruitmentDetailFactory = recruitmentDetailFactory } var body: some View { + let recruitmentEntity = recruitmentEntitys[index] NavigationLink { recruitmentDetailFactory.makeView( id: "\(recruitmentEntity.recruitID)", isDetail: false @@ -33,7 +36,7 @@ struct RecruitmentListCell: View { .cornerRadius(15) .padding(8) - VStack(alignment: .leading, spacing: 4) { + VStack(alignment: .leading, spacing: 0) { Text(recruitmentEntity.jobCodeList) .multilineTextAlignment(.leading) .JOBISFont(.body(.body2), color: .Sub.gray90) @@ -42,25 +45,28 @@ struct RecruitmentListCell: View { .JOBISFont(.etc(.caption), color: .Sub.gray60) Spacer() + + Text("실습 수당 \(recruitmentEntity.trainPay.intComma())만원") + .JOBISFont(.etc(.caption), color: .Sub.gray70) } .padding(.leading, 8) - .padding(.top, 14) + .padding(.vertical, 14) Spacer() VStack { - JOBISIcon(self.isBookmarked ? .bookmarkOn : .bookmarkOff) + JOBISIcon(recruitmentEntity.bookmarked ? .bookmarkOn : .bookmarkOff) .frame(width: 12, height: 16) .padding(5) .onTapGesture { - isBookmarked.toggle() + recruitmentEntitys[index].bookmarked.toggle() bookmark() } Spacer() JOBISIcon(.militaryServiceExceptionIcon) - .frame(width: 16, height: 16) + .frame(width: 20, height: 20) .opacity(recruitmentEntity.military ? 1 : 0) } .padding(.vertical, 14) @@ -70,9 +76,6 @@ struct RecruitmentListCell: View { .background(Color.Sub.gray10) .cornerRadius(15) .shadow(color: .black, opacity: 0.1, blur: 4) - .onAppear { - self.isBookmarked = self.recruitmentEntity.bookmarked - } } } } diff --git a/Projects/Feature/RecruitmentFeature/Sources/Recruitment/RecruitmentView.swift b/Projects/Feature/RecruitmentFeature/Sources/Recruitment/RecruitmentView.swift index 50470667..e737d5fb 100644 --- a/Projects/Feature/RecruitmentFeature/Sources/Recruitment/RecruitmentView.swift +++ b/Projects/Feature/RecruitmentFeature/Sources/Recruitment/RecruitmentView.swift @@ -24,9 +24,22 @@ struct RecruitmentView: View { LazyVStack { searchBar() - if let list = viewModel.recruitmentList { - ForEach(list.recruitments, id: \.self) { recruitmentEntity in - navigateToRecruitmentDetail(recruitmentEntity: recruitmentEntity) + if !viewModel.recruitmentList.recruitments.isEmpty { + ForEach(0.. some View { - Button { - viewModel.isNavigateRecruitmentDetail.toggle() - } label: { - RecruitmentListCell( - recruitmentEntity: recruitmentEntity, - recruitmentDetailFactory: recruitmentDetailFactory - ) { - viewModel.bookmark(id: recruitmentEntity.recruitID) - } - } - .onAppear { - viewModel.appendRecruitmentList(list: recruitmentEntity) - } - } } diff --git a/Projects/Feature/RecruitmentFeature/Sources/Recruitment/RecruitmentViewModel.swift b/Projects/Feature/RecruitmentFeature/Sources/Recruitment/RecruitmentViewModel.swift index 426f0b69..852ba262 100644 --- a/Projects/Feature/RecruitmentFeature/Sources/Recruitment/RecruitmentViewModel.swift +++ b/Projects/Feature/RecruitmentFeature/Sources/Recruitment/RecruitmentViewModel.swift @@ -21,7 +21,7 @@ final class RecruitmentViewModel: BaseViewModel { @Published var filteringName: String = "" @Published var listPage: Int = 1 - @Published var recruitmentList: RecruitmentListEntity? + @Published var recruitmentList: RecruitmentListEntity = .init(recruitments: []) @Published var selectedJobCode: CodeEntity? { didSet { fetchCodeList(codeType: .tech, code: selectedJobCode?.code) @@ -75,7 +75,7 @@ final class RecruitmentViewModel: BaseViewModel { } func appendRecruitmentList(list: RecruitmentEntity) { - guard self.recruitmentList?.recruitments.last == list else { return } + guard self.recruitmentList.recruitments.last == list else { return } var jobCode: String? { guard let selectedJobCode = selectedJobCode?.code else { return nil } return String(selectedJobCode) @@ -90,7 +90,7 @@ final class RecruitmentViewModel: BaseViewModel { name: companyText.isEmpty ? nil : companyText ) ) { [weak self] recruitmentList in - self?.recruitmentList?.recruitments.append(contentsOf: recruitmentList.recruitments) + self?.recruitmentList.recruitments.append(contentsOf: recruitmentList.recruitments) } } From c7141bf3667f25d34c99847deb8475d615c59884 Mon Sep 17 00:00:00 2001 From: "hsj._.06" Date: Fri, 6 Oct 2023 10:34:32 +0900 Subject: [PATCH 13/15] =?UTF-8?q?refactoring=20::=20=EB=A6=AC=ED=8C=A9?= =?UTF-8?q?=ED=86=A0=EB=A7=81=20URLImage?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Projects/Shared/DesignSystem/Sources/Image/URLImage.swift | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Projects/Shared/DesignSystem/Sources/Image/URLImage.swift b/Projects/Shared/DesignSystem/Sources/Image/URLImage.swift index 5091e961..d9bd717a 100644 --- a/Projects/Shared/DesignSystem/Sources/Image/URLImage.swift +++ b/Projects/Shared/DesignSystem/Sources/Image/URLImage.swift @@ -12,8 +12,9 @@ public struct URLImage: View { let shape: ImageShape public init(imageURL urlString: String, shape: ImageShape) { - var baseURL: URL { Environment.getUrlValue(key: .s3BaseUrl) } + let baseURL = Environment.getUrlValue(key: .s3BaseUrl) self.imageURL = baseURL.appendingPathComponent(urlString) + self.shape = shape } From ad9f74fd5d1f8f0a8cb536d8b5d73b19cf660710 Mon Sep 17 00:00:00 2001 From: "hsj._.06" Date: Fri, 6 Oct 2023 14:24:28 +0900 Subject: [PATCH 14/15] =?UTF-8?q?feat=20::=20update=20=EC=95=8C=EB=A6=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SplashFeature/Sources/SplashView.swift | 29 +++++++++ .../Sources/SplashViewModel.swift | 60 ++++++++++++++++--- 2 files changed, 82 insertions(+), 7 deletions(-) diff --git a/Projects/Feature/SplashFeature/Sources/SplashView.swift b/Projects/Feature/SplashFeature/Sources/SplashView.swift index 21579205..66199280 100644 --- a/Projects/Feature/SplashFeature/Sources/SplashView.swift +++ b/Projects/Feature/SplashFeature/Sources/SplashView.swift @@ -26,5 +26,34 @@ struct SplashView: View { appState.sceneFlow = .auth } } + .alert(isPresented: $viewModel.showUpdateAlert) { + Alert( + title: Text(viewModel.alertTitle), + message: Text(viewModel.alertMessage), + primaryButton: Alert.Button.destructive( + Text("확인"), + action: { + viewModel.openAppStore() + appState.sceneFlow = .auth + } + ), + secondaryButton: Alert.Button.cancel( + Text("취소") + ) + ) + } + .alert(isPresented: $viewModel.showUpdateForceAlert) { + Alert( + title: Text(viewModel.alertTitle), + message: Text(viewModel.alertMessage), + dismissButton: Alert.Button.destructive( + Text("확인"), + action: { + viewModel.openAppStore() + appState.sceneFlow = .auth + } + ) + ) + } } } diff --git a/Projects/Feature/SplashFeature/Sources/SplashViewModel.swift b/Projects/Feature/SplashFeature/Sources/SplashViewModel.swift index 86881118..c427a30d 100644 --- a/Projects/Feature/SplashFeature/Sources/SplashViewModel.swift +++ b/Projects/Feature/SplashFeature/Sources/SplashViewModel.swift @@ -1,10 +1,16 @@ import BaseFeature +import UIKit import Combine import AuthDomainInterface import UsersDomainInterface final class SplashViewModel: BaseViewModel { private let reissueTokenUseCase: any ReissueTokenUseCase + @Published var showUpdateAlert: Bool = false + @Published var showUpdateForceAlert: Bool = false + public var alertTitle = "" + public var alertMessage = "" + private let appleID = "6450888392" public init( reissueTokenUseCase: any ReissueTokenUseCase @@ -16,14 +22,54 @@ final class SplashViewModel: BaseViewModel { onSuccess: @escaping (AuthorityType) -> Void, onError: @escaping (Error) -> Void ) { - addCancellable(reissueTokenUseCase.execute()) { authority in - if authority { - onSuccess(.developer) - } else { - onSuccess(.student) + update { + addCancellable(reissueTokenUseCase.execute()) { authority in + if authority { + onSuccess(.developer) + } else { + onSuccess(.student) + } + } onReceiveError: { error in + onError(error) } - } onReceiveError: { error in - onError(error) + } + } + + private func update(action: () -> Void) { + let appVersion = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String + + let latestVersion: String? = { + guard let url = URL(string: "http://itunes.apple.com/lookup?id=\(self.appleID)&country=kr"), + let data = try? Data(contentsOf: url), + let json = try? JSONSerialization.jsonObject(with: data, options: .allowFragments) as? [String: Any], + let results = json["results"] as? [[String: Any]], + let appStoreVersion = results[0]["version"] as? String else { + return nil + } + return appStoreVersion + }() + + let marketingVersion = latestVersion! + let currentProjectVersion = appVersion! + let splitMarketingVersion = marketingVersion.split(separator: ".").map {$0} + let splitCurrentProjectVersion = currentProjectVersion.split(separator: ".").map {$0} + + alertTitle = "업데이트 알림" + alertMessage = "JOBIS의 새로운 버전이 있습니다.\n\(marketingVersion) 버전으로 업데이트 해주세요." + if splitCurrentProjectVersion[0] < splitMarketingVersion[0] { + showUpdateForceAlert.toggle() + } else if splitCurrentProjectVersion[1] < splitMarketingVersion[1] { + showUpdateForceAlert.toggle() + } else { + showUpdateAlert.toggle() + } + } + + func openAppStore() { + let appStoreOpenUrlString = "itms-apps://itunes.apple.com/app/apple-store/\(appleID)" + guard let url = URL(string: appStoreOpenUrlString) else { return } + if UIApplication.shared.canOpenURL(url) { + UIApplication.shared.open(url, options: [:], completionHandler: nil) } } } From 30d2a930a03add16e3d932d04f4bf6de9d7c8bb8 Mon Sep 17 00:00:00 2001 From: hongsjae Date: Fri, 6 Oct 2023 05:26:45 +0000 Subject: [PATCH 15/15] =?UTF-8?q?=F0=9F=9A=80=20::=20Deploy=20version=201.?= =?UTF-8?q?2.0=20to=20testflight?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Projects/App/Support/Info.plist | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Projects/App/Support/Info.plist b/Projects/App/Support/Info.plist index 233b536e..fde42057 100644 --- a/Projects/App/Support/Info.plist +++ b/Projects/App/Support/Info.plist @@ -19,7 +19,7 @@ CFBundlePackageType $(PRODUCT_BUNDLE_PACKAGE_TYPE) CFBundleShortVersionString - 1.1.2 + 1.2.0 CFBundleVersion 1 ITSAppUsesNonExemptEncryption