📱 iOS 플젝 개발일지

[iOS/Swift] 앱을 백그라운드에서 다시 돌아오면 캘린더에서 이전 날짜가 오늘 날짜로 표시되는 현상 (생명주기)

dev_zoe 2023. 4. 21. 22:20
반응형

Issue

- 3월 20일에 위 타이틀 23.03.19로 표시 되는 현상 + 홈 달력에서 19일이 오늘 날짜로 표시하는 파란색 원으로 표시되는 현상이 제보되었음.

- 앱을 종료하지 않고 백그라운드 상태로 두었다가 다시 진입했을 때 나타나는 현상인 것으로 보아 생명주기 관련 이슈인것으로 확인되어서, 뷰 컨트롤러/앱 생명주기 개념을 다시 되짚어보면서 원인을 찾아보기로 했다.

- 덕분에 이 포스트도 보완하면서 다시 뷰 컨트롤러 + 앱 생명주기에 대해 이해해보는 계기가 되었다.

 

Problem

- 날짜와 캘린더를 viewDidLoad에서 세팅하게 되면서, 앱이 백그라운드에 있다가 다시 돌아올 때에는 viewDidLoad가 이미 실행되어있고 그 이후에 초기화하는 코드가 실행되지 않으므로 이전 데이터로 남아있었음이 원인

 

Solution

- 앱이 백그라운드 -> 포그라운드로 다시 돌아오는 경우 / 다른 뷰컨트롤러에서 다시 돌아올 때 날짜가 바뀌었을 때 2가지를 해결해줄 필요가 있었음

- 뷰컨트롤러에서 앱의 생명주기를 어떻게 알까? 해서 알아보니 NotificationCenter 를 이용하게 되는것을 확인해서, 이 개념에 대해 공부해보았다. 공부한 포스팅은 요기

- Notification Center의 observer를 등록해서, 앱이 active 상태로 진입했을 때의 Notification을 관찰하게 되면 / 다른 화면에 있다가 다시 돌아올 때 상단 날짜 타이틀과 캘린더의 오늘 날짜를 바꿔주는 메소드를 실행하도록 했다.

    private var observer: NSObjectProtocol?
            
    override func viewDidLoad() {
        super.viewDidLoad()
        
        //앱이 active 상태로 진입했을 때의 Notification Observer 등록
        observer = NotificationCenter.default.addObserver(forName: UIApplication.didBecomeActiveNotification, object: nil, queue: .main) { [unowned self] _ in
            changeTitleAndCalendarDate()
        }
    }

    init(viewModel: HomeViewModel) {
        self.viewModel = viewModel
        self.userKeyChainService = BasicUserKeyChainService.shared
        super.init()
    }
    
    deinit { //옵저버 해지 -> 메모리 관리
        if let observer = observer {
            NotificationCenter.default.removeObserver(observer)
        }
    }
    
    override func viewWillAppear(_ animated: Bool) { //다른 화면에 갔다가 다시 돌아올 때에도 날짜를 바꿔줄 필요가 있으므로 viewWillAppear에서 함수 실행
        changeTitleAndCalendarDate()
    }
    func changeTitleAndCalendarDate(){
        if dateLabel.text != DateUtil.shared.formattedString(for: DateUtil.shared.now, format: .yyMMdd) { //날짜가 달라진 경우 바꿔주기
            dateLabel.text = DateUtil.shared.formattedString(for: DateUtil.shared.now, format: .yyMMdd)
            calendar.appearance.todayColor = .primaryBlue //오늘날짜로 파란 dot 재설정
            calendar.reloadData()
        }
    }
반응형