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] 회원가입 UI + API 수정 (+ 로그인 UI) #462

Merged
merged 28 commits into from
Sep 20, 2022
Merged
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
fe08bf6
✨ Feat: 학교 추가 (#459)
dev-jungbin Sep 12, 2022
e015293
✨ Feat: 학교 선택 여부에 따라 제1/제2전공 상태를 결정하는 함수 작성 (#459)
dev-jungbin Sep 12, 2022
a48266e
✅ Chore: 선택된 학교를 변경할 경우, 선택되었던 전공을 초기화 (#459)
dev-jungbin Sep 12, 2022
6fcc0c5
🔨 Fix: 동일한 학교를 선택할 경우, textField를 다시 업데이트하지 않도록 수정 (#459)
dev-jungbin Sep 12, 2022
af1f7aa
♻️ Refactor: "선택"/"변경" 타이틀 설정하는 함수 rx로 리팩토링 (#459)
dev-jungbin Sep 12, 2022
af35c3b
➕ Add: HalfModalVC를 상속받아 회원가입 modal에서 사용하는 SignUpModalVC 생성 (#459)
dev-jungbin Sep 13, 2022
969d3f7
✅ Chore: HalfModalVC BaseVC에서 상속 설정, 상속받아 사용하기 위해 프로퍼티/메서드 접근제어 수정 (#…
dev-jungbin Sep 13, 2022
99db28b
♻️ Refactor: 기존 SelectMajorModalVC에서 SignModalVC로 변경 (#459)
dev-jungbin Sep 13, 2022
8ed5ac0
✅ Chore: 회원가입 post 데이터에 univ ID 제대로 들어가도록 수정 (#459)
dev-jungbin Sep 13, 2022
eaa469f
✅ Chore: 프로필 수정 뷰 기존 코드 주석처리, TODO 작성 (#459)
dev-jungbin Sep 13, 2022
9b1f8bb
⚰️ Remove: 기존 SelectMajorModal 관련 파일 삭제 (#459)
dev-jungbin Sep 13, 2022
5f7d4f6
✅ Chore: 학교 선택 action 코드 수정 (#459)
dev-jungbin Sep 13, 2022
cf412a6
⚰️ Remove: 주석 처리한 코드 삭제 (#459)
dev-jungbin Sep 13, 2022
19ecca1
✨ Feat: SignUp 바텀시트 완료 부분 데이터 넘기는 함수 추가 (#459)
dev-jungbin Sep 13, 2022
5791f2a
⚰️ Remove: debug print 제거 (#459)
dev-jungbin Sep 13, 2022
d04a899
🔨 Fix: 전공정보 기입 뷰 SE 레이아웃 수정 (#459)
dev-jungbin Sep 13, 2022
5377286
✨ Feat: 학교 이메일 조회 관련 네트워크 코드 추가 (#459)
dev-jungbin Sep 13, 2022
c2fb7d5
✨ Feat: 학교 이메일 조회하여 placeholder 변경하는 기능 추가 (#459)
dev-jungbin Sep 13, 2022
8f994fe
✅ Chore: 로그인 뷰 이메일 placeholder 텍스트 변경 (#459)
dev-jungbin Sep 13, 2022
30a17c8
♻️ Refactor: SignInAPI 리팩토링 (#459)
dev-jungbin Sep 13, 2022
cbae63d
✅ Chore: HalfModalVC 접근제어자 수정 (#459)
dev-jungbin Sep 20, 2022
116fd76
✅ Chore: 버튼 액션 연결 (#459)
dev-jungbin Sep 20, 2022
509df32
➕ Add: SignUpMajorInfoEnterType Enum 추가 (#459)
dev-jungbin Sep 20, 2022
080efbb
♻️ Refactor: enter type 사용하여 분기처리 부분 수정 (#459)
dev-jungbin Sep 20, 2022
0049341
Merge remote-tracking branch 'origin' into feature/#459-SIgnUp-UI-API
dev-jungbin Sep 20, 2022
1be60b8
✅ Chore: MajorTVC에 String data로 major name label 설정하는 함수 추가 (#459)
dev-jungbin Sep 20, 2022
8392b46
⚰️ Remove: 구조 변경에 따른 코드 삭제 (#459)
dev-jungbin Sep 20, 2022
38e5c2b
♻️ Refactor: 상속 제거 및 SignUpModalVC 구현 방식 변경 (#459)
dev-jungbin Sep 20, 2022
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
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ enum ModalType {
case search
}

class HalfModalVC: UIViewController {
class HalfModalVC: BaseVC {

// MARK: Components
private let titleLabel = UILabel().then {
let titleLabel = UILabel().then {
$0.font = .PretendardM(size: 16)
$0.textColor = .black
$0.text = "학과선택"
Expand All @@ -32,19 +32,19 @@ class HalfModalVC: UIViewController {
$0.backgroundColor = .mainDefault
}

private let majorTV = UITableView()
let majorTV = UITableView()

private let completeBtn = NadoSunbaeBtn().then {
let completeBtn = NadoSunbaeBtn().then {
$0.isActivated = false
$0.setTitle("선택 완료", for: .normal)
}

private let searchTextField = NadoTextField().then {
let searchTextField = NadoTextField().then {
$0.setSearchStyle()
}

// MARK: Properties
private var majorList: [MajorInfoModel] = []
var majorList: [MajorInfoModel] = []
var selectMajorDelegate: SendUpdateModalDelegate?
var selectFilterDelegate: SendUpdateStatusDelegate?
var vcType: ModalType = .basic
Expand All @@ -64,7 +64,7 @@ class HalfModalVC: UIViewController {

// MARK: - UI
extension HalfModalVC {
private func configureUI(type: ModalType) {
func configureUI(type: ModalType) {
view.backgroundColor = .white
view.addSubviews([titleLabel, cancelBtn, lineView, majorTV, completeBtn, searchTextField])

Expand Down
166 changes: 34 additions & 132 deletions NadoSunbae-iOS/NadoSunbae-iOS/Network/APIManagers/SignAPI.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@
import Foundation
import Moya

class SignAPI {
class SignAPI: BaseAPI {
static let shared = SignAPI()
private var provider = MoyaProvider<SignService>()

private init() {}
override private init() {}
}

// MARK: - API
Expand Down Expand Up @@ -42,7 +42,8 @@ extension SignAPI {
let statusCode = response.statusCode
let data = response.data

completion(self.signUpJudgeData(status: statusCode, data: data))
let networkResult = self.judgeStatus(by: statusCode, data, SignUpDataModel.self)
completion(networkResult)

case .failure(let err):
print(err.localizedDescription)
Expand All @@ -58,7 +59,8 @@ extension SignAPI {
let statusCode = response.statusCode
let data = response.data

completion(self.checkNickNameDuplicateJudgeData(status: statusCode, data: data))
let networkResult = self.judgeStatus(by: statusCode, data, String.self)
completion(networkResult)

case .failure(let err):
print(err.localizedDescription)
Expand All @@ -74,7 +76,8 @@ extension SignAPI {
let statusCode = response.statusCode
let data = response.data

completion(self.checkEmailDuplicateJudgeData(status: statusCode, data: data))
let networkResult = self.judgeStatus(by: statusCode, data, String.self)
completion(networkResult)

case .failure(let err):
print(err.localizedDescription)
Expand All @@ -90,7 +93,8 @@ extension SignAPI {
let statusCode = response.statusCode
let data = response.data

completion(self.signOutJudgeData(status: statusCode, data: data))
let networkResult = self.judgeStatus(by: statusCode, data, SignOutResponseModel.self)
completion(networkResult)

case .failure(let err):
print(err.localizedDescription)
Expand All @@ -106,23 +110,25 @@ extension SignAPI {
let statusCode = response.statusCode
let data = response.data

completion(self.withDrawJudgeData(status: statusCode, data: data))
let networkResult = self.judgeStatus(by: statusCode, data, WithDrawResponseModel.self)
completion(networkResult)

case .failure(let err):
print(err.localizedDescription)
}
}
}

/// [POST] 로그인 요청
/// [POST] 회원가입 이메일 재전송 요청
func resendSignUpMail(email: String, PW: String, completion: @escaping (NetworkResult<Any>) -> (Void)) {
provider.request(.resendSignUpMail(email: email, PW: PW)) { result in
switch result {
case .success(let response):
let statusCode = response.statusCode
let data = response.data

completion(self.resendSignUpMailJudgeData(status: statusCode, data: data))
let networkResult = self.judgeStatus(by: statusCode, data, ResendSignUpMailResponseModel.self)
completion(networkResult)

case .failure(let err):
print(err.localizedDescription)
Expand All @@ -138,7 +144,25 @@ extension SignAPI {
let statusCode = response.statusCode
let data = response.data

completion(self.updateTokenJudgeData(status: statusCode, data: data))
let networkResult = self.judgeStatus(by: statusCode, data, SignInDataModel.self)
completion(networkResult)

case .failure(let err):
print(err.localizedDescription)
}
}
}

/// [GET] 학교 이메일 도메인 조회
func getUnivEmailDomain(univID: Int, completion: @escaping (NetworkResult<Any>) -> (Void)) {
provider.request(.getUnivEmailDomain(univID: univID)) { result in
switch result {
case .success(let response):
let statusCode = response.statusCode
let data = response.data

let networkResult = self.judgeStatus(by: statusCode, data, UnivEmailDomainDataModel.self)
completion(networkResult)

case .failure(let err):
print(err.localizedDescription)
Expand Down Expand Up @@ -168,126 +192,4 @@ extension SignAPI {
return .networkFail
}
}

private func signUpJudgeData(status: Int, data: Data) -> NetworkResult<Any> {
let decoder = JSONDecoder()

guard let decodedData = try? decoder.decode(GenericResponse<SignUpDataModel>.self, from: data) else { return .pathErr }

switch status {
case 200...204:
return .success(decodedData.data ?? "None-Data")
case 400...409:
return .requestErr(decodedData.message)
case 500:
return .serverErr
default:
return .networkFail
}
}

private func checkNickNameDuplicateJudgeData(status: Int, data: Data) -> NetworkResult<Any> {
let decoder = JSONDecoder()

guard let decodedData = try? decoder.decode(GenericResponse<String>.self, from: data) else { return .pathErr }

switch status {
case 200...204:
return .success(decodedData.data ?? "None-Data")
case 400...408:
return .requestErr(decodedData.message)
case 409:
return .requestErr(false)
case 500:
return .serverErr
default:
return .networkFail
}
}

private func checkEmailDuplicateJudgeData(status: Int, data: Data) -> NetworkResult<Any> {
let decoder = JSONDecoder()

guard let decodedData = try? decoder.decode(GenericResponse<String>.self, from: data) else { return .pathErr }

switch status {
case 200...204:
return .success(decodedData.data ?? "None-Data")
case 400...408:
return .requestErr(decodedData.message)
case 409:
return .requestErr(false)
case 500:
return .serverErr
default:
return .networkFail
}
}

private func signOutJudgeData(status: Int, data: Data) -> NetworkResult<Any> {
let decoder = JSONDecoder()

guard let decodedData = try? decoder.decode(SignOutResponseModel.self, from: data) else { return .pathErr }

switch status {
case 200...204:
return .success(decodedData.message)
case 401:
return .requestErr(false)
case 400, 402...409:
return .requestErr(decodedData.message)
case 500:
return .serverErr
default:
return .networkFail
}
}

private func withDrawJudgeData(status: Int, data: Data) -> NetworkResult<Any> {
let decoder = JSONDecoder()

guard let decodedData = try? decoder.decode(GenericResponse<WithDrawResponseModel>.self, from: data) else { return .pathErr }
switch status {
case 200...204:
return .success(decodedData.message)
case 400...409:
return .requestErr(decodedData.message)
case 500:
return .serverErr
default:
return .networkFail
}
}

private func resendSignUpMailJudgeData(status: Int, data: Data) -> NetworkResult<Any> {
let decoder = JSONDecoder()

guard let decodedData = try? decoder.decode(GenericResponse<ResendSignUpMailResponseModel>.self, from: data) else { return .pathErr }
switch status {
case 200...204:
return .success(decodedData.message)
case 400...409:
return .requestErr(decodedData.message)
case 500:
return .serverErr
default:
return .networkFail
}
}

private func updateTokenJudgeData(status: Int, data: Data) -> NetworkResult<Any> {
let decoder = JSONDecoder()

guard let decodedData = try? decoder.decode(GenericResponse<SignInDataModel>.self, from: data) else { return .pathErr }
switch status {
case 200...204:
return .success(decodedData.data ?? "None-Data")
case 400...409:
return .requestErr(decodedData.message)
case 500:
return .serverErr
default:
return .networkFail
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
//
// UnivEmailDomainDataModel.swift
// NadoSunbae
//
// Created by madilyn on 2022/09/13.
//

import Foundation

struct UnivEmailDomainDataModel: Codable {
let email: String
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ enum SignService {
case requestWithDraw(PW: String)
case resendSignUpMail(email: String, PW: String)
case updateToken(refreshToken: String)
case getUnivEmailDomain(univID: Int)
}

extension SignService: TargetType {
Expand All @@ -42,13 +43,17 @@ extension SignService: TargetType {
return "/auth/certification/email"
case .updateToken:
return "/auth/renewal/token"
case .getUnivEmailDomain(let univID):
return "auth/university/\(univID)"
}
}

var method: Moya.Method {
switch self {
case .requestSignIn, .requestSignUp, .checkNickNameDuplicate, .checkEmailDuplicate, .requestSignOut, .resendSignUpMail, .requestWithDraw, .updateToken:
return .post
case .getUnivEmailDomain:
return .get
}
}

Expand All @@ -71,7 +76,7 @@ extension SignService: TargetType {
return .requestParameters(parameters: ["nickname": nickName], encoding: JSONEncoding.default)
case .checkEmailDuplicate(let email):
return .requestParameters(parameters: ["email": email], encoding: JSONEncoding.default)
case .requestSignOut, .updateToken:
case .requestSignOut, .updateToken, .getUnivEmailDomain:
return .requestPlain
case .requestWithDraw(let PW):
return .requestParameters(parameters: ["password": PW], encoding: JSONEncoding.default)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,19 +94,20 @@ class EditProfileVC: BaseVC {
}

@IBAction func tapSelectMajorORStartBtn(_ sender: UIButton) {
guard let slideVC = UIStoryboard.init(name: SelectMajorModalVC.className, bundle: nil).instantiateViewController(withIdentifier: SelectMajorModalVC.className) as? SelectMajorModalVC else { return }

/// 제2전공 진입시기 선택 버튼을 탭했는데, 제2전공이 선택되어있지 않을 경우
if !(sender.tag == 3 && secondMajorTextField.text == "미진입") {
slideVC.enterdBtnTag = sender.tag
self.enterBtnTag = sender.tag

slideVC.modalPresentationStyle = .custom
slideVC.transitioningDelegate = self
slideVC.selectMajorDelegate = self

self.present(slideVC, animated: true, completion: nil)
}
// TODO: SignUpModalVC로 변경
// guard let slideVC = UIStoryboard.init(name: SelectMajorModalVC.className, bundle: nil).instantiateViewController(withIdentifier: SelectMajorModalVC.className) as? SelectMajorModalVC else { return }
//
// /// 제2전공 진입시기 선택 버튼을 탭했는데, 제2전공이 선택되어있지 않을 경우
// if !(sender.tag == 3 && secondMajorTextField.text == "미진입") {
// slideVC.enterdBtnTag = sender.tag
// self.enterBtnTag = sender.tag
//
// slideVC.modalPresentationStyle = .custom
// slideVC.transitioningDelegate = self
// slideVC.selectMajorDelegate = self
//
// self.present(slideVC, animated: true, completion: nil)
// }
}

// MARK: Custom Methods
Expand Down
Loading