특정 날짜 및 시간에 사용자에게 알림을 보내는 기능을 구현하려면, UserNotifications 프레임워크를 사용하면 된다. 단순히 코드 몇 줄 추가하는 과정이 아니라 아래에 정리해 보았다.
알림 권한 요청
기본적인 알림 권한 요청: 앱이 실행될 때마다 권한 요청
import UserNotifications func requestNotificationPermission() { UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) }
최초 한 번만 권한 요청:
UserDefaults
를 통해 요청 기록 저장import UserNotifications class NotificationManager { static let shared = NotificationManager() func checkNotificationPermission() { let hasRequestedNotification = UserDefaults.standard.bool(forKey: "hasRequestedNotification") if !hasRequestedNotification { requestNotificationPermission() UserDefaults.standard.set(true, forKey: "hasRequestedNotification") // 최초 요청 기록 저장 } } private func requestNotificationPermission() { UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) { granted, _ in if !granted { DispatchQueue.main.async { self.showSettingsAlert() } } } } private func showSettingsAlert() { let alert = UIAlertController( title: "알림이 비활성화되었습니다", message: "알림을 받으려면 설정에서 권한을 허용해주세요.", preferredStyle: .alert ) alert.addAction(UIAlertAction(title: "설정으로 이동", style: .default) { _ in if let url = URL(string: UIApplication.openSettingsURLString) { UIApplication.shared.open(url) } }) alert.addAction(UIAlertAction(title: "취소", style: .cancel)) UIApplication.shared.windows.first?.rootViewController?.present(alert, animated: true) } }
설정한 시간에 알림 예약
func scheduleNotification(title: String, message: String, date: Date) { let content = UNMutableNotificationContent() content.title = title content.body = message content.sound = .default let triggerDate = Calendar.current.dateComponents([.year, .month, .day, .hour, .minute], from: date) let trigger = UNCalendarNotificationTrigger(dateMatching: triggerDate, repeats: false) let request = UNNotificationRequest(identifier: UUID().uuidString, content: content, trigger: trigger) UNUserNotificationCenter.current().add(request) }
Foreground 상태에서도 알림 표시 설정
// AppDelegate.swift import UIKit import UserNotifications @main class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate { func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { UNUserNotificationCenter.current().delegate = self return true } func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) { completionHandler([.banner, .badge, .sound]) } }