물 마시기 프로젝트

?? 사용자가 마신 물의 양을 저장하고, 지금까지 마신 물의 양을 보여주는 앱 ???

DrinkWaterVC ProfileVC

사용 요소 및 개념

  • NavigationController , Scene Life Cycle, Singletone, UserDefaults
  • NotificationCenter, ? No-StoryBoard? , SwiftPM

의존성

  • SnapKit
    • 이 프로젝트는 스토리보드를 사용하지않고 100% 코드로 UI 를 구성하였습니다.
    • AutoLayout 관련 코드를 줄이기 위해 SnapKit 을 사용하였습니다.

화면 구조

  • MainNavigationController : 최상단 컨테이너 뷰 컨트롤러
  • DrinkWaterViewController : 메인 화면 컨트롤러
  • ProfileViewController : 프로필 화면 컨트롤러

해결 과정 ??‍♀️??

☑️ <객체>.shared.init() 에서 self 가 반환되기 전에 다시 shared 에 접근해서 BAD ACCESS 오류

디버깅 인스펙터의 콜스택을 천천히 살펴보니….

  • init 이 완료되어 self 를 반환받기 전에 self 에 접근을 시도하는 코드가 있었다.
  • 어떻게 init 아직 완료된지 알 수 있을까?….. 호출 스택에 아직 남아있잖아여
  • 반환된 코드는 스택에서 사라지겠죠?????

→ One-time Set up 코드이기 때문에 SceneDelegate 에서 호출해주었다.

☑️ UITextField 숫자만 받게 하기

최초 시도

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool
  • 여기서 replacementString 을 캐릭터로 변형하고, .isNumber 로 숫자인지 확인했다.
    • 발생하는 이슈 1: 백스페이스가 무시된다.
      • (잘못 입력해도 수정하려면 다른 곳을 탭한 후 다시 입력을 처음부터 시작해야한다.)
    • 발생하는 이슈 2: paste 로 문자를 입력하면 막지 못한다.
      • 확인 결과 내 코드만으로 paste 를 막을 수 있다.

해결

  • iOS iPhone 용 앱인 점을 사용하여 , textFiled 의 입력 키보드를 NumberPad 로 설정해준다.
    • 최초 시도는 백스페이스 입력이 불가능한 점을 제외하고는 필요한 모든 기능이 구현되지만,
    • UX 상 사용자가 잘못 입력했을 때 수정 기회를 주는 것이 옳다고 생각하기 때문에 변경하였다.

☑️ UITextField Action 막기

  • Paste Action 을 막아서 숫자 외의 문자를 붙여넣기 하는 것을 막고 싶었다.
  • 아래 메서드는 소위 Action 메뉴를 열려고 할 때 수 차례 호출된다. (select, paste, selectAll 등등을 전달하며)

override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool {
    
    if action == #selector(UIResponderStandardEditActions.paste(_:)) {
        return false
    }
    
    return super.canPerformAction(action, withSender: sender)
  }

☑️ 화면에서 홈으로 이동했다가 다시 돌아오면 viewWillAppear(_:) 가 호출되지 않는다.

이 경우 animation 을 어떻게 다시 Trigger 해줄수 있을까?

  • 응 노티 써~ ?
  • UIScene.willEnterForegroundNotification

☑️ 네비게이션 바 컬러 적용 안됨

  • barTintColor
    • navigationBar.backgroundColor 로 시도했었다. 이거 계속 반복하는 실수 같음

☑️ Fatal Error: Float 이 NaN 이거나 Infinite 일 때 Int 로 타입 컨버젼 시도

  • .isNaN, isInfinite 으로 분기 처리해주세요

(해결 중) UIAlertController 중복 코드좀 없애고 싶다 !!!?

UIAlertController with Function Builders

(해결 중) 앱과 거의 같은 생명주기를 가지는 객체의 deinit 추적

어떻게 하지..? 브레이크 포인트에 안걸린다

deinit {
    print(#function)
    saveUserInfo()
}

GitHub

https://github.com/Woozzang/ios-project-hydrate_me