From 4a3739e13e8e2aa1dec40d354ad602b709634222 Mon Sep 17 00:00:00 2001 From: hooni Date: Sat, 31 Aug 2024 22:45:25 +0900 Subject: [PATCH 1/8] =?UTF-8?q?fix/#352=20=EC=98=A8=EB=B3=B4=EB=94=A9=20?= =?UTF-8?q?=EC=9D=B4=EB=AF=B8=EC=A7=80=20=EC=BA=90=EC=8B=B1=EB=AC=B8?= =?UTF-8?q?=EC=A0=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../xcshareddata/xcschemes/KkuMulKum.xcscheme | 9 +- .../ViewModel/ProfileSetupViewModel.swift | 91 ++++++++++++------- 2 files changed, 67 insertions(+), 33 deletions(-) diff --git a/KkuMulKum.xcodeproj/xcshareddata/xcschemes/KkuMulKum.xcscheme b/KkuMulKum.xcodeproj/xcshareddata/xcschemes/KkuMulKum.xcscheme index 55aba682..1570b9c9 100644 --- a/KkuMulKum.xcodeproj/xcshareddata/xcschemes/KkuMulKum.xcscheme +++ b/KkuMulKum.xcodeproj/xcshareddata/xcschemes/KkuMulKum.xcscheme @@ -30,7 +30,7 @@ shouldAutocreateTestPlan = "YES"> + + + + Data? { + var compression: CGFloat = 1.0 + var imageData = image.jpegData(compressionQuality: compression) + + while (imageData?.count ?? 0) > maxImageSizeBytes && compression > 0.1 { + compression -= 0.1 + imageData = image.jpegData(compressionQuality: compression) + } + + return imageData } func uploadProfileImage() async -> Bool { - print("uploadProfileImage 함수 호출됨") - guard let imageData = imageData else { - print("이미지 데이터가 없습니다.") - serverResponse.value = "이미지 데이터가 없습니다." - return false - } - - print("업로드할 이미지 데이터 크기: \(imageData.count) bytes") - - let fileName = "profile_image.jpg" - let mimeType = "image/jpeg" - - do { - let _: EmptyModel = try await authService.performRequest( - .updateProfileImage( - image: imageData, - fileName: fileName, - mimeType: mimeType - ) - ) - serverResponse.value = "프로필 이미지가 성공적으로 업로드되었습니다." - print("프로필 이미지 업로드 성공") - return true - } catch { - handleError(error as? NetworkError ?? .unknownError("알 수 없는 오류가 발생했습니다.")) - return false - } - } + print("uploadProfileImage 함수 호출됨") + guard let imageData = imageData else { + print("이미지 데이터가 없습니다.") + serverResponse.value = "이미지 데이터가 없습니다." + return false + } + + if imageData.count > maxImageSizeBytes { + print("이미지 크기가 최대 허용 크기를 초과합니다.") + serverResponse.value = "이미지 크기가 너무 큽니다. 더 작은 이미지를 선택해주세요." + return false + } + + print("업로드할 이미지 데이터 크기: \(imageData.count) bytes") + + let fileName = "profile_image.jpg" + let mimeType = "image/jpeg" + + do { + let _: EmptyModel = try await authService.performRequest( + .updateProfileImage( + image: imageData, + fileName: fileName, + mimeType: mimeType + ) + ) + serverResponse.value = "프로필 이미지가 성공적으로 업로드되었습니다." + print("프로필 이미지 업로드 성공") + + clearImageCache() + return true + } catch { + handleError(error as? NetworkError ?? .unknownError("알 수 없는 오류가 발생했습니다.")) + return false + } + } private func handleError(_ error: NetworkError) { switch error { @@ -81,4 +103,9 @@ class ProfileSetupViewModel { } print("프로필 이미지 업로드 실패: \(error.message)") } + + private func clearImageCache() { + KingfisherManager.shared.cache.clearMemoryCache() + KingfisherManager.shared.cache.clearDiskCache() + } } From ea8172e304f9e739d61f2ee351db3ce011dd8290 Mon Sep 17 00:00:00 2001 From: hooni Date: Sat, 31 Aug 2024 22:53:18 +0900 Subject: [PATCH 2/8] =?UTF-8?q?fix/#352=20=EB=B0=B1=EB=B2=84=ED=8A=BC?= =?UTF-8?q?=EC=9D=B4=EC=8A=88=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Nickname/ViewController/NicknameViewController.swift | 3 +++ 1 file changed, 3 insertions(+) diff --git a/KkuMulKum/Source/Onboarding/Nickname/ViewController/NicknameViewController.swift b/KkuMulKum/Source/Onboarding/Nickname/ViewController/NicknameViewController.swift index fe075a48..87e53880 100644 --- a/KkuMulKum/Source/Onboarding/Nickname/ViewController/NicknameViewController.swift +++ b/KkuMulKum/Source/Onboarding/Nickname/ViewController/NicknameViewController.swift @@ -35,6 +35,8 @@ class NicknameViewController: BaseViewController { setupTextField() setupTapGesture() setupNavigationBarTitle(with: "닉네임 설정") + navigationItem.leftBarButtonItem = nil + } private func setupBindings() { @@ -136,6 +138,7 @@ class NicknameViewController: BaseViewController { .disposed(by: disposeBag) view.addGestureRecognizer(tapGesture) } + } extension NicknameViewController: UITextFieldDelegate { From 2437173815e9f6160fcd66f3e2fa8e0130132f27 Mon Sep 17 00:00:00 2001 From: hooni Date: Mon, 2 Sep 2024 14:25:39 +0900 Subject: [PATCH 3/8] =?UTF-8?q?fix/#352=20=EC=9D=B4=EB=AF=B8=EC=A7=80?= =?UTF-8?q?=EC=88=98=EC=A0=95=ED=8E=98=EC=9D=B4=EC=A7=80=20=EB=84=98?= =?UTF-8?q?=EC=96=B4=EA=B0=88=EB=95=8C=20=EB=B0=94=ED=85=80=ED=83=AD?= =?UTF-8?q?=EB=B0=94=20=EC=82=AD=EC=A0=9C=EC=8B=9C=ED=82=A4=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Source/MyPage/ViewController/MyPageViewController.swift | 6 ++++-- .../Nickname/ViewController/NicknameViewController.swift | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/KkuMulKum/Source/MyPage/ViewController/MyPageViewController.swift b/KkuMulKum/Source/MyPage/ViewController/MyPageViewController.swift index 507c7b5f..b48ba48e 100644 --- a/KkuMulKum/Source/MyPage/ViewController/MyPageViewController.swift +++ b/KkuMulKum/Source/MyPage/ViewController/MyPageViewController.swift @@ -215,8 +215,10 @@ class MyPageViewController: BaseViewController, CustomActionSheetDelegate { KingfisherManager.shared.cache.clearDiskCache() }) .disposed(by: disposeBag) - - navigationController?.pushViewController(editProfileViewController, animated: true) + + editProfileViewController.hidesBottomBarWhenPushed = true + + navigationController?.pushViewController(editProfileViewController, animated: true) } private func pushAskViewController() { diff --git a/KkuMulKum/Source/Onboarding/Nickname/ViewController/NicknameViewController.swift b/KkuMulKum/Source/Onboarding/Nickname/ViewController/NicknameViewController.swift index 87e53880..947586a9 100644 --- a/KkuMulKum/Source/Onboarding/Nickname/ViewController/NicknameViewController.swift +++ b/KkuMulKum/Source/Onboarding/Nickname/ViewController/NicknameViewController.swift @@ -11,7 +11,7 @@ import RxSwift import RxCocoa class NicknameViewController: BaseViewController { - + private let nicknameView = NicknameView() private let viewModel: NicknameViewModel private let disposeBag = DisposeBag() From 095db042c180dccee8f69ac9d62b91dec4748f8c Mon Sep 17 00:00:00 2001 From: hooni Date: Mon, 2 Sep 2024 15:01:15 +0900 Subject: [PATCH 4/8] =?UTF-8?q?fix/#352=20=EB=A7=88=EC=9D=B4=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=A7=80=20=EA=B8=B0=EB=B3=B8=EC=9D=B4=EB=AF=B8?= =?UTF-8?q?=EC=A7=80=EC=A0=84=ED=99=98=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- KkuMulKum/Resource/Extension/UIButton+.swift | 20 +++++++++++++++++++ .../Source/MyPage/View/MyPageEditView.swift | 4 ++-- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/KkuMulKum/Resource/Extension/UIButton+.swift b/KkuMulKum/Resource/Extension/UIButton+.swift index 2d2492fa..d8af35b6 100644 --- a/KkuMulKum/Resource/Extension/UIButton+.swift +++ b/KkuMulKum/Resource/Extension/UIButton+.swift @@ -28,4 +28,24 @@ extension UIButton { ) setAttributedTitle(attributedString, for: .normal) } + + func addUnderlineWithMyPage( + textColor: UIColor, + underlineColor: UIColor = .gray2, + spacing: CGFloat = 12 + ) { + let font = UIFont.pretendard(.body05) + let underlineStyle = NSUnderlineStyle.single + + let attributes: [NSAttributedString.Key: Any] = [ + .font: font, + .foregroundColor: textColor, + .underlineStyle: underlineStyle.rawValue, + .underlineColor: underlineColor, + .baselineOffset: spacing / 2 + ] + + let attributedString = NSMutableAttributedString(string: self.titleLabel?.text ?? "", attributes: attributes) + setAttributedTitle(attributedString, for: .normal) + } } diff --git a/KkuMulKum/Source/MyPage/View/MyPageEditView.swift b/KkuMulKum/Source/MyPage/View/MyPageEditView.swift index 3296ddf2..2e81c419 100644 --- a/KkuMulKum/Source/MyPage/View/MyPageEditView.swift +++ b/KkuMulKum/Source/MyPage/View/MyPageEditView.swift @@ -29,8 +29,8 @@ class MyPageEditView: BaseView { } let skipButton = UIButton().then { - $0.setTitle("기본 프로필로 설정", style: .body03, color: .gray5) - $0.addUnderline() + $0.setTitle("기본 프로필로 설정", style: .body05, color: .gray5) + $0.addUnderlineWithMyPage(textColor: .gray5, underlineColor: .gray2) } let confirmButton = UIButton().then { From 33b6624ea9cb0f7b11d03d3d26fdef12897100b0 Mon Sep 17 00:00:00 2001 From: hooni Date: Mon, 2 Sep 2024 15:19:39 +0900 Subject: [PATCH 5/8] =?UTF-8?q?feat/#352=20=EB=A0=88=EB=B2=A8=EB=B6=84?= =?UTF-8?q?=EA=B8=B0=20=EB=B0=8F=20=ED=85=8C=EC=8A=A4=ED=8A=B8=EB=A1=9C?= =?UTF-8?q?=EA=B7=B8=EC=9D=B8=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ViewController/MyPageViewController.swift | 3 ++- .../MyPage/ViewModel/MyPageViewModel.swift | 15 +++++++++++ .../Login/VIewModel/LoginViewModel.swift | 25 ------------------- .../Onboarding/Login/View/LoginView.swift | 18 +------------ .../ViewController/LoginViewController.swift | 24 ------------------ 5 files changed, 18 insertions(+), 67 deletions(-) diff --git a/KkuMulKum/Source/MyPage/ViewController/MyPageViewController.swift b/KkuMulKum/Source/MyPage/ViewController/MyPageViewController.swift index b48ba48e..272c0f9c 100644 --- a/KkuMulKum/Source/MyPage/ViewController/MyPageViewController.swift +++ b/KkuMulKum/Source/MyPage/ViewController/MyPageViewController.swift @@ -128,9 +128,10 @@ class MyPageViewController: BaseViewController, CustomActionSheetDelegate { private func updateUI(with userInfo: LoginUserModel?) { guard let userInfo = userInfo else { return } + let levelText = viewModel.getLevelText(for: userInfo.level) rootView.contentView.nameLabel.text = userInfo.name ?? "꾸물리안 님" - rootView.contentView.levelLabel.setText("Lv. \(userInfo.level) 지각대장 꾸물이", style: .body05, color: .white) + rootView.contentView.levelLabel.setText("Lv. \(userInfo.level) \(levelText)", style: .body05, color: .white) rootView.contentView.levelLabel.setHighlightText("Lv. \(userInfo.level)", style: .body05, color: .lightGreen) updateProfileImage(with: userInfo.profileImageURL) diff --git a/KkuMulKum/Source/MyPage/ViewModel/MyPageViewModel.swift b/KkuMulKum/Source/MyPage/ViewModel/MyPageViewModel.swift index 71692518..a1ba61a5 100644 --- a/KkuMulKum/Source/MyPage/ViewModel/MyPageViewModel.swift +++ b/KkuMulKum/Source/MyPage/ViewModel/MyPageViewModel.swift @@ -53,6 +53,21 @@ class MyPageViewModel: NSObject { .asSignal(onErrorJustReturn: ()) } + func getLevelText(for level: Int) -> String { + switch level { + case 1: + return "빼꼼 꾸물이" + case 2: + return "망기적 꾸물이" + case 3: + return "기적 꾸물이" + case 4: + return "꾸물꿈" + default: + return "꾸물리안 님" + } + } + func fetchUserInfo() { Task { do { diff --git a/KkuMulKum/Source/Onboarding/Login/VIewModel/LoginViewModel.swift b/KkuMulKum/Source/Onboarding/Login/VIewModel/LoginViewModel.swift index daff4861..8b0f824c 100644 --- a/KkuMulKum/Source/Onboarding/Login/VIewModel/LoginViewModel.swift +++ b/KkuMulKum/Source/Onboarding/Login/VIewModel/LoginViewModel.swift @@ -260,31 +260,6 @@ class LoginViewModel: NSObject { print("Failed to save tokens") } } - - // TODO: 자동로그인 구현 후 삭제예정 - func fetchValueFromPrivacyInfo(forKey key: String) -> String? { - guard let path = Bundle.main.path(forResource: "PrivacyInfo", ofType: "plist"), - let dict = NSDictionary(contentsOfFile: path) as? [String: AnyObject], - let value = dict[key] as? String else { - return nil - } - return value - } - - // TODO: 자동로그인 구현 후 삭제예정 - func performTestLogin() { - guard let testAccessToken = fetchValueFromPrivacyInfo(forKey: "TEST_ACCESS_TOKEN") else { - print("Failed to retrieve test access token") - error.value = "Test access token not found" - return - } - - saveTokens(accessToken: testAccessToken, refreshToken: "") - userName.value = "" - loginState.value = .login - } - - } extension LoginViewModel: ASAuthorizationControllerDelegate, ASAuthorizationControllerPresentationContextProviding { diff --git a/KkuMulKum/Source/Onboarding/Login/View/LoginView.swift b/KkuMulKum/Source/Onboarding/Login/View/LoginView.swift index ad63d541..148765ac 100644 --- a/KkuMulKum/Source/Onboarding/Login/View/LoginView.swift +++ b/KkuMulKum/Source/Onboarding/Login/View/LoginView.swift @@ -29,16 +29,8 @@ class LoginView: BaseView { $0.isUserInteractionEnabled = true } - // TODO: 자동로그인 구현 후 삭제예정 - let testLoginButton = UIButton().then { - $0.setTitle("Test Login", for: .normal) - $0.setTitleColor(.white, for: .normal) - $0.backgroundColor = .systemBlue - $0.layer.cornerRadius = 10 - } - override func setupView() { - addSubviews(backgroundImageView, appleLoginImageView, kakaoLoginImageView, testLoginButton) + addSubviews(backgroundImageView, appleLoginImageView, kakaoLoginImageView) } override func setupAutoLayout() { @@ -59,13 +51,5 @@ class LoginView: BaseView { $0.horizontalEdges.equalToSuperview().inset(14) $0.height.equalTo(Screen.height(54)) } - - // TODO: 자동로그인 구현 후 삭제예정 - testLoginButton.snp.makeConstraints { - $0.centerX.equalToSuperview() - $0.top.equalTo(appleLoginImageView.snp.bottom).offset(20) - $0.width.equalTo(200) - $0.height.equalTo(50) - } } } diff --git a/KkuMulKum/Source/Onboarding/Login/ViewController/LoginViewController.swift b/KkuMulKum/Source/Onboarding/Login/ViewController/LoginViewController.swift index 1729139e..360dbb3d 100644 --- a/KkuMulKum/Source/Onboarding/Login/ViewController/LoginViewController.swift +++ b/KkuMulKum/Source/Onboarding/Login/ViewController/LoginViewController.swift @@ -44,29 +44,9 @@ class LoginViewController: BaseViewController { action: #selector(kakaoLoginTapped) ) loginView.kakaoLoginImageView.addGestureRecognizer(kakaoTapGesture) - - // TODO: 자동로그인 구현 후 삭제예정 - loginView.testLoginButton.addTarget(self, action: #selector(testLoginTapped), for: .touchUpInside) - } private func bindViewModel() { -// loginViewModel.loginState.bind(with: self) { owner, state in -// -// Task { -// switch state { -// case .notLogin: -// print("Login State: Not logged in") -// case .login: -// print("Login State: Logged in") -// await owner.navigateToOnboardingScreen() -// case .needOnboarding: -// print("Login State: Need onboarding") -// await owner.navigateToOnboardingScreen() -// } -// } -// } - loginViewModel.userName.bind(with: self) { owner, name in Task { if name != nil { @@ -139,8 +119,4 @@ class LoginViewController: BaseViewController { present(alert, animated: true) } } - - @objc private func testLoginTapped() { - loginViewModel.performTestLogin() - } } From 40fb08d23033da566407a77a1218a07f47eb538e Mon Sep 17 00:00:00 2001 From: hooni Date: Mon, 2 Sep 2024 16:50:25 +0900 Subject: [PATCH 6/8] =?UTF-8?q?feat/#352=20=EA=B6=8C=ED=95=9C=20=EC=97=85?= =?UTF-8?q?=EB=8D=B0=EC=9D=B4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- KkuMulKum/Resource/Info.plist | 2 ++ 1 file changed, 2 insertions(+) diff --git a/KkuMulKum/Resource/Info.plist b/KkuMulKum/Resource/Info.plist index 8cc36857..d11ad3c0 100644 --- a/KkuMulKum/Resource/Info.plist +++ b/KkuMulKum/Resource/Info.plist @@ -2,6 +2,8 @@ + NSPhotoLibraryUsageDescription + 꾸물꿈은 카메라 권한을 필요로 합니다. 카메라를 통해 자신의 프로필을 즉시 찍어 업로드할 수 있습니다. 허용 안함 시 일부 기능이 동작하지 않을 수 있습니다. CFBundleURLTypes From ebdb48ab5c2d237fd1c118062e1b7335e26be286 Mon Sep 17 00:00:00 2001 From: hooni Date: Mon, 2 Sep 2024 17:16:38 +0900 Subject: [PATCH 7/8] =?UTF-8?q?fix/#352=20000=20=EB=8B=98=20=ED=86=B5?= =?UTF-8?q?=EC=9D=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Source/MyPage/ViewController/MyPageViewController.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/KkuMulKum/Source/MyPage/ViewController/MyPageViewController.swift b/KkuMulKum/Source/MyPage/ViewController/MyPageViewController.swift index 272c0f9c..9bf42298 100644 --- a/KkuMulKum/Source/MyPage/ViewController/MyPageViewController.swift +++ b/KkuMulKum/Source/MyPage/ViewController/MyPageViewController.swift @@ -130,7 +130,7 @@ class MyPageViewController: BaseViewController, CustomActionSheetDelegate { guard let userInfo = userInfo else { return } let levelText = viewModel.getLevelText(for: userInfo.level) - rootView.contentView.nameLabel.text = userInfo.name ?? "꾸물리안 님" + rootView.contentView.nameLabel.text = (userInfo.name.map { $0 + " 님" }) ?? "꾸물리안 님" rootView.contentView.levelLabel.setText("Lv. \(userInfo.level) \(levelText)", style: .body05, color: .white) rootView.contentView.levelLabel.setHighlightText("Lv. \(userInfo.level)", style: .body05, color: .lightGreen) From a50ee7838ca82dbdf6d403e93137317cb18bb25f Mon Sep 17 00:00:00 2001 From: hooni Date: Mon, 2 Sep 2024 17:46:24 +0900 Subject: [PATCH 8/8] =?UTF-8?q?fix/#352=20=EB=A1=9C=EC=BB=AC=EC=95=8C?= =?UTF-8?q?=EB=9E=8C=2010=EB=B6=84=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../SetReadyInfo/ViewModel/SetReadyInfoViewModel.swift | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/KkuMulKum/Source/SetReadyInfo/ViewModel/SetReadyInfoViewModel.swift b/KkuMulKum/Source/SetReadyInfo/ViewModel/SetReadyInfoViewModel.swift index 10dd03de..1717dbc9 100644 --- a/KkuMulKum/Source/SetReadyInfo/ViewModel/SetReadyInfoViewModel.swift +++ b/KkuMulKum/Source/SetReadyInfo/ViewModel/SetReadyInfoViewModel.swift @@ -22,6 +22,8 @@ final class SetReadyInfoViewModel { let moveMinute = ObservablePattern("") let isSucceedToSave = ObservablePattern(false) + let bufferTime: TimeInterval = 10 * 60 + var readyTime: Int = 0 var moveTime: Int = 0 @@ -142,8 +144,8 @@ final class SetReadyInfoViewModel { print("이동 시간: \(self.moveTime) 분") print("총 준비 시간: \(totalPrepTime / 60) 분") - let readyStartTime = promiseDate.addingTimeInterval(-TimeInterval(self.readyTime + self.moveTime) * 60) - let moveStartTime = promiseDate.addingTimeInterval(-TimeInterval(self.moveTime) * 60) + let readyStartTime = promiseDate.addingTimeInterval(-(totalPrepTime + bufferTime)) + let moveStartTime = promiseDate.addingTimeInterval(-(TimeInterval(self.moveTime * 60) + bufferTime)) print("준비 시작 시간: \(timeFormatter.string(from: readyStartTime))") print("이동 시작 시간: \(timeFormatter.string(from: moveStartTime))")