LocalNotification(물마시기 앱)

2022. 1. 21. 14:56IOS/App만들기

물마시기 알람 앱 만들기

Local Notification : 푸시 알림?

앱 내부에서 자체적으로 만든 특정 메세지를 전달하는 것

LocalNotification

UNNotificationRequest

3가지 필수 내용

  1. identifier
  2. UNMutableNotificationContent (Content.title, Contetn.body)
  3. Trigger
    1. UNCalendarNotificationTrigger
    2. UNTimerIntervalNotificationTrigger 시간 간격당 알림 ( 타이머에 가까움)
    3. UNLocationNotificationTrigger

UNNotificationCenter 에 보내면 Trigger 타이밍에 알려줌.

Content 설정

  1. AppDelegate 에 UNUserNotificationCenterDelegate 를 확장하도록 한다.
  2. UNUserNotificationCenter 를 생성하고 알람을 허용할지 요청한다.
import NotificationCenter
import UserNotifications

class AppDelegate: UIResponder, UIApplicationDelegate {
    var userNotificationCenter: UNUserNotificationCenter?

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.
        UNUserNotificationCenter.current().delegate = self

        let authrizationOptions = UNAuthorizationOptions(arrayLiteral: [.alert, .badge, .sound])

        userNotificationCenter?.requestAuthorization(options: authrizationOptions, completionHandler: { _, error in
            if let error = error {
                print("Error: \(error.localizedDescription)")
            }
        })

        return true
    }
// 생략 
}

extension AppDelegate: UNUserNotificationCenterDelegate {
    func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
        completionHandler([.banner, .list, .badge, .sound])
    }

    func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
        completionHandler()
    }
}
  1. UserNotficationCenter 에 request 를 보내는 코드를 추가한다.
import UserNotifications

extension UNUserNotificationCenter {
    func addNotificationRequest(by alert: Alert) {
        let content = UNMutableNotificationContent()
        content.title = "물 마실 시간이에요.💧"
        content.body = "세계보건기구가 권장하는 하루 물 섭취량은 1.5~2리터 입니다."
        content.sound = .default
        content.badge = 1
    }
}

Trigger

trigger 를 설정한다.

extension UNUserNotificationCenter {
    func addNotificationRequest(by alert: Alert) {
        let content = UNMutableNotificationContent()
        content.title = "물 마실 시간이에요.💧"
        content.body = "세계보건기구가 권장하는 하루 물 섭취량은 1.5~2리터 입니다."
        content.sound = .default
        content.badge = 1

                // 추가 부분
        let component = Calendar.current.dateComponents([.hour, .minute], from: alert.date)
        let trigger = UNCalendarNotificationTrigger(dateMatching: component, repeats: alert.isOn)
    }
}

request

request 를 추가한다.

extension UNUserNotificationCenter {
    func addNotificationRequest(by alert: Alert) {
        let content = UNMutableNotificationContent()
        content.title = "물 마실 시간이에요.💧"
        content.body = "세계보건기구가 권장하는 하루 물 섭취량은 1.5~2리터 입니다."
        content.sound = .default
        content.badge = 1

        let component = Calendar.current.dateComponents([.hour, .minute], from: alert.date)
        let trigger = UNCalendarNotificationTrigger(dateMatching: component, repeats: alert.isOn)

                // 추가 부분
        let request = UNNotificationRequest(identifier: alert.id, content: content, trigger: trigger)

        self.add(request, withCompletionHandler: nil)
    }
}

이제 알람이 추가되어야 할 부분에 request를 추가하고, 삭제 되어야 할 부분에 remove를 호출한다.

import UserNotifications

class AlertListViewController: UITableViewController {
    var alerts: [Alert] = []
        // userNotificationCenter 추가
    let userNotificationCenter = UNUserNotificationCenter.current()
        // 생략
        @IBAction func addAlertButtonAction(_ sender: UIBarButtonItem) {
        guard let addAlertVc = storyboard?.instantiateViewController(withIdentifier: "AddAlerViewController")
                as? AddAlerViewController else {return}
        addAlertVc.pickedDate = {[weak self] date in
            guard let self = self else {return}

            var alertList = self.alertList()
            let newAlert = Alert(date: date, isOn: true)

            alertList.append(newAlert)
            alertList.sort { $0.date < $1.date}

            self.alerts = alertList
            UserDefaults.standard.set(try? PropertyListEncoder().encode(self.alerts), forKey: "alerts")
                        // 알람 추가
            self.userNotificationCenter.addNotificationRequest(by: newAlert)

            self.tableView.reloadData()
        }

        self.present(addAlertVc, animated: true, completion: nil)
    }
    //... 생략
}

알람이 필요 없는 곳에서는 삭제 한다.

override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
        switch editingStyle {
        case .delete:
            self.alerts.remove(at: indexPath.row)
            UserDefaults.standard.set(try? PropertyListEncoder().encode(self.alerts), forKey: "alerts")
            // 아직 시작되지 않은 알람을 삭제하는 것이므로 removePendingNotificationRequest 호출
            userNotificationCenter.removePendingNotificationRequests(withIdentifiers: [alerts[indexPath.row].id])
            self.tableView.reloadData()
            return
        default:
            break
        }
    }

기타

cmd + cntl + e : 모든 변수 이름 바꾸기