EveryDiary - Push Notification (3)

ulls12·2024년 3월 26일
0

Swift TIL

목록 보기
58/60

알람 기능을 구현한 후, View의 알림 데이터가 반영이 안되고 있음을 깨달았다. UserNotification의 프레임워크에서는 알람 데이터를 자체적으로 저장하고 로드하지만, View에 그 데이터를 반영시키려면 따로 CRUD를 구현해야 했다. 알람의 구성 요소들이 간단하고, 데이터량이 크지 않기에 Userdefaults로 구현하기로 했다.

CRUD 구성

우선, 코드를 작성하기 전에 내가 짠 알람이 생성되고 삭제되는 로직을 살펴봐야한다. 스위치를 켜서 알람이 활성화 되고, 시간과 반복된 요일을 설정하면 알람이 생성된다. 이 때가 Create를 의미한다. 그렇다면, 시간과 반복된 요일을 조정한다면 Update에 해당되는 건가?
내가 만든 코드에서 수정은 삭제 (Delete) 와 생성 (Create)을 의미한다. 그리고 스위치를 Off 하면, 모든 알람이 삭제된다. (Delete)

  1. 생성 Create
    private func scheduleNotification() {
        guard let selectedTime = selectedTime else { return }
        
        UserDefaults.standard.set(selectedTime, forKey: "selectedTime")
        UserDefaults.standard.set(selectedDays, forKey: "selectedDays")
        UserDefaults.standard.set(selectedDaysString, forKey: "selectedDaysString")
        
	// 기존의 알람 생성 메서드 구성
    }

3가지 형태의 값을 저장한다.
a. selectedTime Date값
b. selectedDays 일요일부터 토요일까지의 Bool값을 저장한 배열 값
c. selectedDaysString TableView cell에 표현될 값

  1. 수정 - Delete & Create
    추가적인 코드작성이 필요하지 않다. UserDefaults는 키값으로 데이터를 저장하기 때문에 같은 키값에 대해서는 새로운 데이터가 저장되는게 아니라 덮어쓰기가 된다. 그렇기에 구현이 필요없다.

  2. 삭제 - Delete
    TableView의 스위치가 Off 될 때, 모든 저장 값이 지워지게 로직을 짜면 된다.

        switch self.dataSource[indexPath.row] {
            
        case let .switchItem(title, image, isSwitchOn):
            let cell = tableView.dequeueReusableCell(withIdentifier: NotificationCell.id, for: indexPath) as! NotificationCell
            cell.alarmSwtich.addTarget(self, action: #selector(switchChanged), for: .valueChanged)
            cell.prepare(title: title, iconImage: image, switchStatus: isSwitchOn)
            self.switchValueChanged = { [weak self] isOn in
                self?.isSwitchOn = isOn
                UserDefaults.standard.set(isOn, forKey: "isSwitchOn")
                UserDefaults.standard.synchronize()
                if isOn == false {
                    UNUserNotificationCenter.current().removeAllPendingNotificationRequests()
                    UserDefaults.standard.removeObject(forKey: "isSwitchOn")
                    UserDefaults.standard.removeObject(forKey: "selectedTime")
                    UserDefaults.standard.removeObject(forKey: "selectedDays")
                    UserDefaults.standard.removeObject(forKey: "selectedDaysString")
                    self?.printAllPendingNotifications()
                    print("모든 알림 제거 완료!")
                }
                self?.refreshdata()
            }
            return cell

스위치가 꺼질 때, 모든 값을 삭제해주면 된다. 참고로, 스위치의 on/off 상태도 값으로 저장을 해줘야한다.

View 데이터 로드

CRUD에서 Read를 구현해야 할 차례이다. 처음 VC에 진입할 때, 데이터가 UserDefaults에 저장된 값을 바탕으로 로드되면 된다.

    private func fetchAlarmData() {
        isSwitchOn = UserDefaults.standard.bool(forKey: "isSwitchOn")
        if let storedTime = UserDefaults.standard.object(forKey: "selectedTime") as? Date {
            self.selectedTime = storedTime
        }
        if let storedDays = UserDefaults.standard.array(forKey: "selectedDays") as? [Bool] {
            self.selectedDays = storedDays
        }
        if let savedSelectedDaysString = UserDefaults.standard.string(forKey: "selectedDaysString") {
            selectedDaysString = savedSelectedDaysString
        }
    }

해당 메서드를 ViewDidLoad에 호출했고, 결과적으로 문제 없이 로드되었다.

알림이 생성되는 시점에 관한 고찰

처음 알림이 생성되는 타이밍은 timepicker로 시간을 고르고, 반복할 요일을 누른 뒤, 시간 셀과 반복 셀을 눌러 닫힐 경우에 생성되도록 로직을 구현했었다. 그러나, 배포가 된 후 실제 피드백이 들어온 것 중 하나가 알림이 어떤 경우에는 설정이 되고, 어떤 경우에는 설정이 안된다는 의견이였다. 실제로 날짜와 시간을 지정해놓고, cell을 닫는 사람은 그리 많지 않다. 그렇기에 매우 좋지 않은 사용자 환경이라고 생각을 하고 어디에 알림 생성 시점을 지정할 지 고민했었다.
처음엔 맨 아래에 완료 버튼을 누르면, 그 때 알림이 생성되자는 의견이 있었다. 근데 따지고 보면 스위치를 킨 순간부터 사용자는 이미 알림이 울린다고 생각한다. 그 의미는 완료 버튼이 오히려 알림 기능에 대한 혼란을 줄 수도 있다는 생각이 들었다.
그러던 와중 좋은 생각이 떠올랐다. 사용자가 알림 시간을 설정하고 다시 일기를 쓰러 돌아간다. 알림만 생성하고 바로 앱을 종료하지 않는다. 그 말은 알림을 지정하고 나가는 시점에 알림이 생성되도록 로직을 짜면 되는것이다.

그래서 ViewDidDisappear에 알림 생성 메서드를 호출했다. 확실히 이전 것보다는 사용하는데에 혼동이 없었다. 다만, 아직도 알림을 설정하고 앱을 바로 나가는 경우는 생성이 되지 않는다. 100퍼센트 알림이 생성되지는 않는 것이다. 그래서 완료버튼이 결국 답인가? 생각이 든다. 좀더 생각해보고 결정해야할 것 같다. 우선은 기본적인 알림 구성은 이렇게 끝이 났다.

profile
I am 개발해요

0개의 댓글