SLP(회원가입 프로세스) 리팩토링 소감(회고)

2023. 3. 23. 18:48프로젝트/SLP(스터디 메이트 매칭)-SeSAC

한 줄 소개 전화번호 인증과 개인정보 입력절차를 거치는 회원가입 절차 구현
진행기간 2023-03-10 ~ 2023-03-23

 

1. 중점 진행 사항

기존 SLP를 완성하지 못했기 때문에 리팩토링은 꼭 제대로 하고 싶었다. 그 동안 부족한 부분을 공부하면서 리팩토링 부분을 회원가입 단계만 한정하기로 했고 진행했다. 회원가입 프로세스 구현에서 핵심은 크게 3가지였다.

 

-. MVVM패턴 적용

-. RxSwift를 사용한 반응형 프로그래밍 구현

-. 공통 객체 묶어서 화면 파일 갯수 최소화

 

결론부터 말하면 MVVM, RxSwift는 적용했지만 공통 객체를 묶어서 화면 파일 갯수를 최소화하는 것은 구현하지 못했다. 회원가입 절차는 UI가 많이 바뀌지 않기 때문에 큰 틀에서 UI를 잡아놓고 바뀌는 부분만 객체를 갈아끼우는 형식으로 코드를 짰다. 그런데 어떤 이유에서 인지 바꿔 끼워야 할 UIView를 교체할 수 없었다. 타입도 바꿔가면서 시도했지만 다른 객체는 다 바뀌는데 UIView만 교체가 되지 않았다. 원인을 파악하려고 노력했으나 결국 찾을 수 가 없었다. 결국 화면을 분할해서 구현하는 걸로 결정하고 진행했다. 화면 통합은 다음에 다시 한 번 시도해 보려고 한다... 

 

2. 주요 개발 내용

• Firebase

구조를 이해하는데 시간이 좀 걸렸다. 결론부터 말하면 Firebase는 인증대행 역할을 한다고 보면 된다. 인증요청 사용자가 맞는지 아닌지까지만 확인해주면 Firebase의 역할은 끝이다. 인증절차는 크게 보면 3단계로 진행된다. 그림으로 설명하는게 전달력이 높을 것 같아서 그림자료를 준비했다.

처음에 헷갈렸던 부분은 어떻게 서버에서 인증코드를 확인한 사람인지 아닌지를 알 수 있는지였다. 그런데 내가 놓친 부분은 애초에 인증코드 확인된 사람에게만 주어진 토큰으로 API를 호출한다는 점이었다. 즉, 토큰으로 API를 호출하는 사람 = 인증코드 확인된 사람  이라는 뜻이라는 말이다. 애초에 Firebase는 출입증을 발급하는 문지기였을 뿐...


• 
화면전환 스타일 적용

회원가입 요청을 했을 때 금지된 닉네임인 경우 닉네임 화면으로 되돌아가는 화면전환이 필요했다. 그런데 fullScreen 스타일로 닉네임 화면 전환을 했기 때문에 네비게이션 컨트롤러가 끊기는 문제가 있었다. 이 부분은 전환할 닉네임 화면에  UINavigationController를 달아서 fullScreen전환 이후에도 푸시가 이어질 수 있도록 만들어서 해결했다.

 

• Firebase 인증요청시 로딩 프로그레스 구현

로딩프로그레스를 통해 전화번호 입력 후 인증코드 응답까지 아무런 반응이 없는 것을 채워넣을수 있었다. 딜레이 시간이 고정되지 않고 인증이 완료되어 이벤트를 전달한 시점에 dismiss처리하는 것이 핵심이었다. 

 

• 생년월일 텍스트필드 비활성화 처리

데이트피커 선택값으로 텍스트필드가 채워지게 만들어 놓았다보니 텍스트필드에 수동으로 숫자를 입력해도 실제 저장되는 데이터는 데이트 피커 선택값이었다. 이 부분은 생각보다 간단하게 해결했다. 처음에는 어떻게 해결할까... 데이터를 어떻게 만져야 하나 고민하다가 문득 '그냥 값을 못바꾸게 하면 되는거 아냐?' 같은 유레카 타임을 경험했다. 덕분에 텍스트필드를 비활성화 처리하는 걸로 간단하게 해결했다. 

 

• 이메일 유효성 검사

전화번호 때는 쉽게 했는데 이메일 정규식에서 시간을 잡아먹었던건 온점 표시방식이었다. 온점을 정규식으로 만들려면 앞에 백슬래시 두개를 붙여야 했는데 그걸 몰랐다보니 계속해도 유효성 검사 통과를 못했다. "+\\."이렇게 해야하는데 "+."이렇게 한 것이다. 잘못 알고 접근했던 걸 반성하면서 정규식 개념글을 하나 쓰면서 공부하는 걸로 결론을 냈다.

"^([a-zA-Z0-9._-])+@[a-zA-Z0-9.-]+.[a-zA-Z]{2,20}$" 이게 아니라

"^([a-zA-Z0-9._-])+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,20}$" 이거다.

 

• 의존성 주입

저장할 필요 없는 데이터를 UserDefaults에 저장하는 대신에 의존성 주입을 사용해서 화면간 데이터를 전달했다. 여기서 핵심은 두가지였는데 첫째는 데이터를 담을 모델을 만드는 것이었다. 데이터를 담을 모델은 구조체를 사용해서 처리했다. 구조체 사용에서 의미 있었던 부분은 초기값을 설정하니까 멤버와이즈를 생략해서 코드가 좀 더 깔끔해진 것이다. 둘째는 화면마다 넘길 데이터, 받을 데이터를 누락하지 않는 것이었다. 이 부분은 뷰컨트롤러 초기화구문, 콘솔프린트를 통해 해결했다.

 

• 텍스트필드 메서드(shouldChangeCharactersIn)

가장 시간을 많이 잡아먹었던 부분이다. 메서드 기능자체를 제대로 이해하지 못해서 공식문서를 몇 번이고 읽었지만 헷갈렸던 부분이 있었다. 이 메서드는 텍스트필드값이 변경될 때 변경된 값을 텍스트필드 상에 표시할지 말지를 정하는 메서드이다. 여기서 헷갈렸던 부분은 텍스트필드값이 변경될 때 였다. 변경은 1->2라고만 생각했는데 값이 없다가 생기는 것도 변경이라는 것을 알게 된 것이다. 폭넓게 사고하는게 얼마나 중요한지 깨달았던 순간이었다ㅠㅠ. 그리고는 모든 문제가 쉽게 풀렸다.

 

3. 소감

• MVVM, Rx가 어떻게 동작하는지 이해하는데 매우 큰 도움이 되었다. 물론 굳이 이벤트를 전달하고 다시 받아서 UI를 변경해야하나 하는 생각도 종종 들었지만 그 자체가 유용한 과정이었다. 단순히 코드만 작동한다고 OK하는게 아니라, MVVM 패턴에 맞춰진 코드가 무엇인지 왜 비즈니스 로직과 UI를 철저하게 분리하는지를 배웠다.

• 폴더 정리를 어떻게 해야할지 몰랐는데 이제 좀 체계가 잡힌 것 같다. 앞으로 폴더 정리는 1 Scene-1 Folder를 기본으로 하고 시스템파일(AppDelegate 등), 일반파일(Enum 등)을 분류하는 식으로 진행하려고 한다.

• UserDefaults 대신 DI(Dependency Injection: 의존성 주입)을 사용하면서 개인정보 데이터를 전달했다. 이 과정에서 불필요한 데이터 저장 대신 UserDefaults를 용도에 맞게 사용한 것 같아서 뿌듯했다.

 

4. 마무리

완성도를 높일 수 있는 부분이 아직 몇 가지 더 있다. 꾸준히 공부하면서 하나씩 개선해나가면 실력상승에 도움이 될 것 같다는 생각이다.

 

• 텍스트필드 선택 시 테두리 검정색 활성화

• 커스텀에러 생성해서 authError, tokenError 이벤트 하나로 처리

• snapkit constraints message 없애기

• 메모리 관리(weak self, disposedBag 적용)