User Notification
앱을 사용하다보면 아래와 같은 알림을 많이 찾아볼 수 있다. 이것을 앱에서 간단하게 어떻게 구현할 수 있을까?
Notification 권한 요청하기
우선 Notification 을 사용하려면 권한 요청이 필요하다. NotificationCenter 라는 파일을 만들어주고, 권한을 요청할 것이다.
NotificationCenter 클래스를 만들어주고, import UserNotifications 을 해준다. 그리고 NotificationCenter 의 경우 앱에는 반드시 하나의 클래스가 있어야 하기 때문에 싱글톤패턴을 사용하여 클래스를 만들어 줬다.
import UserNotifications
class NotificationCenter {
static let shared = NotificationCenter()
private init() { }
}
권한 요청을 하는 함수를 추가해준다. 나같은 경우 func requestAuthorization() 으로 함수명을 설정했다. 여기서 granted 의 경우 true 일 때 권한요청을 허용했을때, false 일 때 권한요청을 거부했을때 작업을 부여할 수 있다.
import UserNotifications
class NotificationCenter {
static let shared = NotificationCenter()
private init() { }
func requestAuthorization() {
let options: UNAuthorizationOptions = [.alert, .sound, .badge]
UNUserNotificationCenter.current().requestAuthorization(options: options) { granted, error in
if granted {
// 권한 허용했을 때
} else {
// 권한 거부했을 때
}
if let error = error {
// 에러 발생
}
}
}
}
아래와 같이 권한요청이 가능하다
import SwiftUI
struct ContentView: View {
private let notificationCenter = NotificationCenter.shared
var body: some View {
VStack {
Button("Notification 권한 요청") {
notificationCenter.requestAuthorization()
}
.buttonStyle(.bordered)
}
}
}
Notification 메세지 설정하기
이제 권한요청을 완료했다면 어떤 메세지를 보낼 것인가에 대한 문제인데, 예를들어 매일 오전 9시에 알림을 보낸다고 생각해보자. 아래의 함수를 추가해주면 된다. badge 의 경우 앱의 우측 상단에 있는 빨간원에 있는 숫자를 표현한다고 보면 된다.
func schedule() {
let content = UNMutableNotificationContent()
content.title = "title"
content.subtitle = "subtitle"
content.sound = .default
content.badge = 0
var dateComponents = DateComponents()
dateComponents.hour = 09
dateComponents.minute = 00
let trigger = UNCalendarNotificationTrigger(dateMatching: dateComponents, repeats: true)
let request = UNNotificationRequest(
identifier: UUID().uuidString,
content: content,
trigger: trigger
)
UNUserNotificationCenter.current().add(request)
}
나는 5시 5분으로 설정 해 보았는데 아래와 같이 나온다.
Notification 취소하기
만약 설정했는데 Notification 을 받고싶지 않다면? 아래의 함수를 추가해주면 된다.
func cancel() {
let center = UNUserNotificationCenter.current()
center.removeAllPendingNotificationRequests()
}
Notification 권한상태 확인하기
권한상태를 확인하려면 아래와 같은 함수를 통해 확인할 수 있다. 공식문서에서는 authorized, provisional 일 경우 권한이 허용된 경우로 생각하는 듯 하다.
func checkAuthorization() {
let center = UNUserNotificationCenter.current()
center.getNotificationSettings { settings in
let status = settings.authorizationStatus
if status == .notDetermined {
// 권한을 물어보지 않았을 때
} else if status == .denied {
// 권한이 거부되었을 때
} else if status == .authorized && status == .provisional {
// 권한이 있을때
}
}
}
권한상태의 종류를 살펴보면 아래와 같이 5가지의 경우의 수가 있는데 설명에 자세하게 나와있다.
@available(iOS 10.0, *)
public enum UNAuthorizationStatus : Int, @unchecked Sendable {
// The user has not yet made a choice regarding whether the application may post user notifications.
case notDetermined = 0
// The application is not authorized to post user notifications.
case denied = 1
// The application is authorized to post user notifications.
case authorized = 2
// The application is authorized to post non-interruptive user notifications.
@available(iOS 12.0, *)
case provisional = 3
// The application is temporarily authorized to post notifications. Only available to app clips.
@available(iOS 14.0, *)
case ephemeral = 4
}
전체 코드
import UserNotifications
class NotificationCenter {
static let shared = NotificationCenter()
private init() { }
func checkAuthorization() {
let center = UNUserNotificationCenter.current()
center.getNotificationSettings { settings in
let status = settings.authorizationStatus
if status == .notDetermined {
// 권한을 물어보지 않았을 때
} else if status == .denied {
// 권한이 거부되었을 때
} else if status == .authorized && status == .provisional {
// 권한이 있을때
}
}
}
func requestAuthorization() {
let options: UNAuthorizationOptions = [.alert, .sound, .badge]
UNUserNotificationCenter.current().requestAuthorization(options: options) { granted, error in
if granted {
// 권한 허용했을 때
} else {
// 권한 거부했을 때
}
if let error = error {
// 에러 발생
}
}
}
func schedule() {
let content = UNMutableNotificationContent()
content.title = "title"
content.subtitle = "subtitle"
content.sound = .default
content.badge = 0
var dateComponents = DateComponents()
dateComponents.hour = 09
dateComponents.minute = 00
let trigger = UNCalendarNotificationTrigger(dateMatching: dateComponents, repeats: true)
let request = UNNotificationRequest(
identifier: UUID().uuidString,
content: content,
trigger: trigger
)
UNUserNotificationCenter.current().add(request)
}
func cancel() {
let center = UNUserNotificationCenter.current()
center.removeAllPendingNotificationRequests()
}
}