Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[feat] 온보딩 프로세스 구현완료 #156

Merged
merged 15 commits into from
Jul 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
202 changes: 164 additions & 38 deletions KkuMulKum.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions KkuMulKum/Application/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {

// sleep(1)
// KakaoSDK 초기화 과정에서 앱 키를 동적으로 불러오기
if let kakaoAppKey = fetchKakaoAppKeyFromPrivacyInfo() {
KakaoSDK.initSDK(appKey: kakaoAppKey)
Expand Down
2 changes: 1 addition & 1 deletion KkuMulKum/Application/SceneDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
) {
guard let windowScene = (scene as? UIWindowScene) else { return }
self.window = UIWindow(windowScene: windowScene)
self.window?.rootViewController = MainTabBarController()
self.window?.rootViewController = NicknameViewController()
self.window?.makeKeyAndVisible()
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,8 @@
{
"images" : [
{
"filename" : "ic_profilebasic.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "[email protected]",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "[email protected]",
"idiom" : "universal",
"scale" : "3x"
"filename" : "Mask group.svg",
"idiom" : "universal"
}
],
"info" : {
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
23 changes: 23 additions & 0 deletions KkuMulKum/Resource/Assets.xcassets/Splash.imageset/Contents.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"images" : [
{
"filename" : "Splash.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "Splash 1.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "Splash 2.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
32 changes: 26 additions & 6 deletions KkuMulKum/Resource/Base.lproj/LaunchScreen.storyboard
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="13122.16" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="22505" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
<device id="retina6_12" orientation="portrait" appearance="light"/>
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13104.12"/>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="22504"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="System colors in document resources" minToolsVersion="11.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
Expand All @@ -11,15 +14,32 @@
<objects>
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<rect key="frame" x="0.0" y="0.0" width="393" height="852"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" xcode11CocoaTouchSystemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
<subviews>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="Splash" translatesAutoresizingMaskIntoConstraints="NO" id="jM3-k4-ltG">
<rect key="frame" x="0.0" y="0.0" width="393" height="852"/>
</imageView>
</subviews>
<viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<constraints>
<constraint firstItem="6Tk-OE-BBY" firstAttribute="trailing" secondItem="jM3-k4-ltG" secondAttribute="trailing" id="9Ol-QN-Vio"/>
<constraint firstItem="6Tk-OE-BBY" firstAttribute="bottom" secondItem="jM3-k4-ltG" secondAttribute="bottom" constant="-34" id="DOx-Gi-miq"/>
<constraint firstItem="jM3-k4-ltG" firstAttribute="leading" secondItem="6Tk-OE-BBY" secondAttribute="leading" id="h7v-dB-NQw"/>
<constraint firstItem="jM3-k4-ltG" firstAttribute="top" secondItem="6Tk-OE-BBY" secondAttribute="top" constant="-59" id="isO-fU-3Vp"/>
</constraints>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="53" y="375"/>
<point key="canvasLocation" x="52.671755725190835" y="374.64788732394368"/>
</scene>
</scenes>
<resources>
<image name="Splash" width="375" height="812"/>
<systemColor name="systemBackgroundColor">
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</systemColor>
</resources>
</document>
4 changes: 4 additions & 0 deletions KkuMulKum/Resource/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>NSPhotoLibraryAddUsageDescription</key>
<string>정혜진!정혜진!정혜진!정혜진!정혜진!정혜진!정혜진!정혜진!정혜진!정혜진!정혜진!정혜진!정혜진!정혜진!정혜진!정혜진!정혜진!정혜진!정혜진!정혜진!정혜진!정혜진!정혜진!정혜진!정혜진!정혜진!정혜진!정혜진!정혜진!정혜진!정혜진!정혜진!정혜진!정혜진!정혜진!정혜진!정혜진!정혜진!정혜진!정혜진!정혜진!정혜진!정혜진!정혜진!정혜진!정혜진!정혜진!정혜진!정혜진!정혜진!정혜진!정혜진!정혜진!정혜진!정혜진!정혜진!</string>
<key>NSCameraUsageDescription</key>
<string>정혜진!정혜진!정혜진!정혜진!정혜진!정혜진!정혜진!정혜진!정혜진!정혜진!정혜진!정혜진!정혜진!정혜진!정혜진!정혜진!정혜진!정혜진!정혜진!정혜진!정혜진!정혜진!정혜진!정혜진!정혜진!정혜진!정혜진!정혜진!정혜진!정혜진!정혜진!정혜진!정혜진!정혜진!정혜진!정혜진!정혜진!정혜진!정혜진!정혜진!정혜진!정혜진!정혜진!정혜진!정혜진!정혜진!정혜진!정혜진!정혜진!정혜진!정혜진!정혜진!정혜진!정혜진!정혜진!정혜진!</string>
Comment on lines +5 to +8
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👀

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

아 이부분 기획자 선생님들꼐 말을 해서 정확한 정보로 수정 예정입니다! 다음 스크럼때 말하겟습니다!

<key>UIUserInterfaceStyle</key>
<string>Light</string>
<key>CFBundleURLTypes</key>
Expand Down
2 changes: 1 addition & 1 deletion KkuMulKum/Source/MyPage/View/MyPageContentView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ class MyPageContentView: BaseView {

override func setupView() {
backgroundColor = .clear
addSubview(profileStackView,levelView,separatorView)
addSubviews(profileStackView,levelView,separatorView)
profileStackView.addArrangedSubviews(profileImageView, nameLabel)
levelView.addSubview(levelLabel)
}
Expand Down
11 changes: 9 additions & 2 deletions KkuMulKum/Source/Onboarding/Login/VIewModel/LoginViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -70,12 +70,19 @@ class LoginViewModel: NSObject {

extension LoginViewModel: ASAuthorizationControllerDelegate, ASAuthorizationControllerPresentationContextProviding {
func authorizationController(controller: ASAuthorizationController, didCompleteWithAuthorization authorization: ASAuthorization) {
guard let credential = authorization.credential as? ASAuthorizationAppleIDCredential else {
guard let appleIDCredential = authorization.credential as? ASAuthorizationAppleIDCredential else {
print("Authorization failed: Credential is not of type ASAuthorizationAppleIDCredential")
return
}
let userName = credential.fullName?.givenName ?? "Apple user"

let userName = appleIDCredential.fullName?.givenName ?? "Apple user"
loginState.value = .loggedIn(userInfo: "Apple user: \(userName)")

// 액세스 토큰 출력
if let identityToken = appleIDCredential.identityToken,
let tokenString = String(data: identityToken, encoding: .utf8) {
print("Apple Login Access Token: \(tokenString)")
}
}

func authorizationController(controller: ASAuthorizationController, didCompleteWithError error: Error) {
Expand Down
107 changes: 107 additions & 0 deletions KkuMulKum/Source/Onboarding/Nickname/NicknameView/NicknameView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
//
// NicknameView.swift
// KkuMulKum
//
// Created by 이지훈 on 7/10/24.
//

import UIKit

import SnapKit
import Then

class NicknameView: BaseView {

let navigationBar = UIView().then {
$0.backgroundColor = .white
}

let titleLabel = UILabel().then {
$0.setText("프로필 설정", style: .body03, color: .black)
}

let separatorLine = UIView().then {
$0.backgroundColor = .gray2
}
Comment on lines +15 to +25
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

시스템이 기본 제공하는 navigationItem을 사용하지 않으시고, 직접 view를 이용하여 구현하셨네요!
혹시 하단의 경계선 때문일까요?

그리고 UIView(backgroundColor: .white)로 생성도 가능하답니다.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

시스템이 기본 제공하는 navigationItem을 사용하지 않으시고, 직접 view를 이용하여 구현하셨네요!
혹시 하단의 경계선 때문일까요?
-> 넵 맞습니다! 온보딩 프로세스에는 네비게이션이 들어가있지 않아서 해당 프로세스에는 커스텀으로 구현해서 넣었습니다


let subtitleLabel = UILabel().then {
$0.setText("이름을 설정해 주세요", style: .head01, color: .gray8)
}

let nicknameTextField = CustomTextField(placeHolder: "이름을 입력해 주세요").then {
$0.layer.cornerRadius = 8
$0.layer.borderWidth = 1
$0.layer.borderColor = UIColor.gray3.cgColor
}

let characterCountLabel = UILabel().then {
$0.setText("0/5", style: .body06, color: .gray)
$0.textAlignment = .right
}

let errorLabel = UILabel().then {
$0.setText("한글, 영문, 숫자만을 사용해 총 5자 이내로 입력해주세요.", style: .caption02, color: .red)
$0.isHidden = true
}

let nextButton = UIButton().then {
$0.setTitle("다음", style: .body01, color: .white)
$0.backgroundColor = .gray2
$0.setLayer(borderWidth: 0, borderColor: .clear, cornerRadius: 8)
$0.isEnabled = false
}

override func setupView() {
backgroundColor = .white

[navigationBar, separatorLine, subtitleLabel, nicknameTextField, errorLabel, nextButton].forEach { addSubview($0) }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

addSubviews(_ views: UIView...)라는 메서드를 만들어 두긴 했습니다..ㅎ

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

코딩 습관이 무섭네요 바로 코드 수정하겟습니다!

navigationBar.addSubview(titleLabel)
nicknameTextField.addSubview(characterCountLabel)
}

override func setupAutoLayout() {
navigationBar.snp.makeConstraints {
$0.top.leading.trailing.equalToSuperview()
$0.height.equalTo(92)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👀

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Screen!

}

titleLabel.snp.makeConstraints {
$0.centerX.equalTo(navigationBar.snp.centerX)
$0.bottom.equalTo(navigationBar.snp.bottom).offset(-12)
}

separatorLine.snp.makeConstraints {
$0.top.equalTo(navigationBar.snp.bottom)
$0.leading.trailing.equalToSuperview()
$0.height.equalTo(1)
}

subtitleLabel.snp.makeConstraints {
$0.top.equalTo(separatorLine.snp.bottom).offset(24)
$0.leading.trailing.equalToSuperview().inset(20)
}

nicknameTextField.snp.makeConstraints {
$0.top.equalTo(subtitleLabel.snp.bottom).offset(22)
$0.leading.trailing.equalToSuperview().inset(20)
$0.height.equalTo(CustomTextField.defaultHeight)
}

characterCountLabel.snp.makeConstraints {
$0.centerY.equalToSuperview()
$0.trailing.equalToSuperview().inset(12)
$0.width.equalTo(30)
}

errorLabel.snp.makeConstraints {
$0.top.equalTo(nicknameTextField.snp.bottom).offset(8)
$0.leading.trailing.equalToSuperview().inset(20)
}

nextButton.snp.makeConstraints {
$0.leading.trailing.equalToSuperview().inset(20)
$0.bottom.equalTo(safeAreaLayoutGuide).offset(-20)
$0.height.equalTo(52)
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
//
// NicknameViewController.swift
// KkuMulKum
//
// Created by 이지훈 on 7/10/24.
//

import UIKit

class NicknameViewController: BaseViewController {

private let nicknameView = NicknameView()
private let viewModel = NicknameViewModel()

override func loadView() {
view = nicknameView
}

override func viewDidLoad() {
super.viewDidLoad()
setupBindings()
setupActions()
setupTextField()
setupTapGesture()
}

private func setupBindings() {
viewModel.nicknameState.bind { [weak self] state in
switch state {
case .empty:
self?.nicknameView.nicknameTextField.layer.borderColor = UIColor.gray3.cgColor
self?.nicknameView.errorLabel.isHidden = true
case .valid:
self?.nicknameView.nicknameTextField.layer.borderColor = UIColor.maincolor.cgColor
self?.nicknameView.errorLabel.isHidden = true
case .invalid:
self?.nicknameView.nicknameTextField.layer.borderColor = UIColor.red.cgColor
self?.nicknameView.errorLabel.isHidden = false
}
}

viewModel.errorMessage.bind { [weak self] errorMessage in
self?.nicknameView.errorLabel.text = errorMessage
}

viewModel.isNextButtonEnabled.bind { [weak self] isEnabled in
self?.nicknameView.nextButton.isEnabled = isEnabled
self?.nicknameView.nextButton.backgroundColor = isEnabled ? .maincolor : .gray2
}

viewModel.characterCount.bind { [weak self] count in
self?.nicknameView.characterCountLabel.text = count
}
}

private func setupActions() {
nicknameView.nicknameTextField.addTarget(self, action: #selector(textFieldDidChange(_:)), for: .editingChanged)
nicknameView.nextButton.addTarget(self, action: #selector(nextButtonTapped), for: .touchUpInside)
}
Comment on lines +56 to +59
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BaseViewController로부터 오버라이딩이 가능한 setupAction메서드가 있으니 해당 메서드로 작성해도 괜찮을 것 같아요!

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

코딩 습관이 무섭네요 바로 코드 수정하겟습니다!


private func setupTextField() {
nicknameView.nicknameTextField.delegate = self
nicknameView.nicknameTextField.returnKeyType = .done
}

private func setupTapGesture() {
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(dismissKeyboard))
view.addGestureRecognizer(tapGesture)
}

@objc private func textFieldDidChange(_ textField: UITextField) {
viewModel.validateNickname(textField.text ?? "")
}

@objc private func nextButtonTapped() {
let profileSetupVC = ProfileSetupViewController(viewModel: ProfileSetupViewModel(nickname: viewModel.nickname.value))
profileSetupVC.modalPresentationStyle = .fullScreen
present(profileSetupVC, animated: true, completion: nil)
}

@objc private func dismissKeyboard() {
view.endEditing(true)
nicknameView.nicknameTextField.layer.borderColor = UIColor.gray3.cgColor
}
}

extension NicknameViewController: UITextFieldDelegate {
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
textField.resignFirstResponder()
nicknameView.nicknameTextField.layer.borderColor = UIColor.gray3.cgColor
return true
}
}
Loading