LocalNotificaltion(물마시기앱)

물마시기 알람 앱 만들기

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 를 생성하고 알람을 허용할지 요청한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
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 를 보내는 코드를 추가한다.
1
2
3
4
5
6
7
8
9
10
11
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 를 설정한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
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 를 추가한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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를 호출한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
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)
}
//... 생략
}

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

1
2
3
4
5
6
7
8
9
10
11
12
13
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 : 모든 변수 이름 바꾸기