[iOS] UserNotification을 사용하여 로컬 알림 만들기

2023. 10. 3. 02:19· iOS
목차
  1. 로컬 알림
  2. UNMutableNotificationContent
  3. UNTimeIntervalNotificationTrigger
  4. UNNotificationRequest
  5. UNUserNotificationCenter
  6. 예시

로컬 알림

 

로컬 알림(로컬 푸시)는 앱 내부에서 미리 만든 특정 메시지를 iOS의 알림 센터를 통해 전달하는 방법으로, 앱이 종료되어 있거나 백그라운드 상태일 때도 메세지를 전달할 수 있는 방법 중 하나입니다.

 

로컬 알림은 iOS 스케줄러에 의해 발송되는데, 앱 내부에서 미리 메세지를 구성한 후 발송될 시간을 iOS 스케줄러에 등록해 두면 해당 시각에 맞추어 자동으로 발송합니다. 따라서 특정 시각에 뭔가를 알려주도록 처리할 때에도 로컬 알림을 사용할 수 있습니다.

 

로컬 알림은 주로 앱 델리게이트 클래스에 생성하게 되면 앱이 백그라운드 상태에 있을 때에도 알림을 줄 수 있어,

사용자의 이목을 집중시킬 수 있는 효과를 가질 수 있습니다.

 

과거에 로컬 알림을 처리하는 객체는 UILocalNotification이었으나,

iOS 10부터 사용자 알림에 관한 UserNotification 프레임워크를 제공하기 시작하였습니다.

 

UserNotification 프레임워크에서 중요한 객체는 다음과 같습니다.

  • UNMutableNotificationContent
  • UNTimeIntervalNotificationTrigger
  • UNNotificationRequest
  • UNUserNotificationCenter

 

UNMutableNotificationContent

UNMutableNotificationContent는 기본적인 속성을 담는 역할을 합니다.

이 객체에서 로컬 알림 타이틀, 서브 타이틀, 알림 메세지나 앱 아이콘에 표시될 배지나 사운드 설정 등을 설정합니다.

 

비슷한 객체로는 UNNotificationContent가 있는데, 이 객체는 수정이 불가능하고

객체로부터 속성을 읽을 수만 있는 특성을 가지기 때문에, 속성을 설정하려면 UNMutableNotificationContent 객체를 사용해야 합니다.

 

설정할 속성은 여러 가지가 있는데, 이 중 대표적인 것들만 살펴보겠습니다.

 

.badge 속성은 사용자가 확인하지 않은 알림을 알려주는 표시로, 카카오톡을 읽지 않았을 때 읽지 않은 채팅의 수를 나타내주는 것이 예시입니다.

.badge 속성

.title, .subtitle , .body는 알림창에 표시될 메세지의 제목, 소제목과 내용을 나타내는 속성입니다.

.title, .subtitle, .body 속성

.sound는 알람이 도착했을 때 알려줄 사운드를 설정하는 속성으로, 직접 제작한 사운드 또한 설정할 수 있습니다.

 

.userInfo는 로컬 알림과 함께 전달하고 싶은 값이 있을 때 사용하는 속성입니다.

 

UNTimeIntervalNotificationTrigger

UNTimeIntervalNotificationTrigger는 알림 발송 조건을 관리합니다.

발생 시각과 반복 여부를 통해 관리할 수 있고, 시간 간격의 기준은 초입니다.

UNCalendarNotificationTrigger 객체를 통해 하루 중 특정 시각에 맞추어 알림 메세지를 전송할 수도 있습니다.

 

UNNotificationRequest

UNNotificationRequest는 알림 요청 객체로,

UNMutableNotificationContent와 UNTimeIntervalNotificationTrigger를 인자값으로 하여 알림 요청 객체를 생성합니다.

 

UNUserNotificationCenter

UNUserNotificationCenter는 실제 발송을 담당하여, 알림 내용을 확인하고 정해진 시각에 발송하는 역할을 합니다.

해당 객체는 싱글턴 방식으로 동작하기 때문에,

따로 인스턴스를 생성하는 것이 아닌 current() 메소드를 통해 참조 정보만 가져올 수 있습니다.

앞에서 생성한 UNNotificationRequest 객체를 UNUserNotificationCenter::add(_:) 메소드를 이용하여 추가한다면

알림 등록 과정이 완료됩니다.

 

예시

다음은 예시 코드를 통해 속성과 메서드들에 대해 알아보겠습니다.

 

해당 예제 코드는 특정 시간에 로컬 알림이 가도록 하였고, ViewController에서는 알림 관련해서 아무런 처리를 하지 않았고(화면 색상만 바꿨습니다.), 알림 관련 기능은 모두 AppDelegate에서 구현하였습니다.

 

예제 코드는 깃허브에 올려두었으니, 필요하시면 확인해보셔도 좋을 것 같습니다.

 

다음은 AppDelegate 파일입니다.

 

//
//  AppDelegate.swift
//  Alert-Example

import UIKit
import UserNotifications    // 로컬 알림 관련 프레임워크

@main
class AppDelegate: UIResponder, UIApplicationDelegate {
    
    
    
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        
        if #available(iOS 10.0, *) {
            // 경고창, 배지, 사운드를 사용하는 알림 환경 정보를 생성하고, 사용자 동의 여부 창을 실행
            
            // UNUserNotificationCenter 객체는 싱글턴 패턴으로 동작하여 current()를 통해 참조 정보만 가져올 수 있음
            let notiCenter = UNUserNotificationCenter.current()
            notiCenter.requestAuthorization(options: [.alert, .badge, .sound]) { (didAllow, e) in }
            notiCenter.delegate = self
            
            scheduleDailyNotification()
            scheduleWeekdayNotifications()
            
        } else {    // UILocalNotification 객체를 이용한 로컬 알림 (iOS 9 이하)
            
        }
        
        return true
    }
    
    // MARK: UISceneSession Lifecycle
    
    func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
        // Called when a new scene session is being created.
        // Use this method to select a configuration to create the new scene with.
        return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
    }
    
    func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {
        // Called when the user discards a scene session.
        // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
        // Use this method to release any resources that were specific to the discarded scenes, as they will not return.
    }
    
    func scheduleDailyNotification() {
        // 로컬 알림 컨텐츠 설정
        let nContent = UNMutableNotificationContent()
        nContent.badge = 2
        nContent.title = "로컬 알림 메세지"
        nContent.subtitle = "서브 타이틀"
        nContent.body = "바디 부분입니다"
        nContent.sound = UNNotificationSound.default
        nContent.userInfo = ["name": "김태형"] //
        
        // Calendar 트리거 설정 (매일 특정 시간에 알림 설정)
        var dateComponents = DateComponents()
        dateComponents.hour = 12 // 예: 10시
        dateComponents.minute = 15 // 예: 00분
        
        // 알림 발송 조건 객체
        let trigger = UNCalendarNotificationTrigger(dateMatching: dateComponents, repeats: true)
//        let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 3, repeats: false)      // 시간 주기에 따라 알림 발송

        
        // 알림 요청 객체 생성
        let request = UNNotificationRequest(identifier: "dailyNotification", content: nContent, trigger: trigger)
        
        // 알림 등록
        UNUserNotificationCenter.current().add(request) { (error) in
            if let error = error {
                print("매일 푸시 알림 등록 실패: \(error.localizedDescription)")
            } else {
                print("매일 푸시 알림이 설정되었습니다.")
            }
        }
    }
    
    
    // 특정 요일에 알람을 보내고 싶을 때
    func scheduleWeekdayNotifications() {
        // 로컬 알림 컨텐츠 설정
        let nContent = UNMutableNotificationContent()
        nContent.badge = 2
        nContent.title = "로컬 알림 메세지"
        nContent.subtitle = "서브 타이틀"
        nContent.body = "바디 부분입니다"
        nContent.sound = UNNotificationSound.default
        nContent.userInfo = ["name": "김태형"]

        // 월요일(2)부터 금요일(6)까지 알람 발송
        for weekday in 2...6 {
            var dateComponents = DateComponents()
            dateComponents.weekday = weekday
            dateComponents.hour = 12 // 예: 12시
            dateComponents.minute = 15 // 예: 15분

            // 알림 발송 조건 객체
            let trigger = UNCalendarNotificationTrigger(dateMatching: dateComponents, repeats: true)

            // 알림 요청 객체 생성
            let request = UNNotificationRequest(identifier: "weekdayNotification\(weekday)", content: nContent, trigger: trigger)

            // 알림 등록
            UNUserNotificationCenter.current().add(request) { (error) in
                if let error = error {
                    print("평일 푸시 알림 등록 실패: \(error.localizedDescription)")
                } else {
                    print("평일 푸시 알림이 설정되었습니다.")
                }
            }
        }
    }

     
     // UNUserNotificationCenterDelegate 메서드 (알림이 표시될 때 호출됨)
     func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
         completionHandler([.alert, .badge, .sound]) // 알림 표시 옵션 설정 : .banner 옵션이 있는데, iOS 15버전 이후부터는 기본값으로 적용되어 입력하지 않아도 됨
     }

}

extension AppDelegate: UNUserNotificationCenterDelegate {
    
}

 

import UserNotifications
  • 우선 로컬 알림을 받기 위해 해당 프레임워크를 import 해줘야합니다.
  • 앱이 처음 실행될 때 알림에 대한 동의를 받는 것이 가장 자연스럽기 때문에 application(_:didFinishLaunchingWithOptions:) 메서드 내에서 구현하였습니다.
  • UNUserNotificationCenter 객체는 싱글톤 패턴이기 때문에 current()를 통해 인스턴스(정확히 말하자면 참조 정보)를 받아옵니다.
  • 인스턴스를 받아왔다면, requestAuthorization() 메서드를 호출하여 사용자에게 알림 설정에 대한 동의를 받습니다. 해당 메서드는 알림 메세지에 포함될 항목(사운드, 배지 등)들을 설정합니다.
  • 만약 백그라운드로 돌아갔을 때에만 로컬 알림을 실행하고 싶다면, applcationWillResignActive(_:) 메서드에 속성을 정의하면 됩니다.
  • notiCenter.delegate = self 를 통해 알림 센터에 관련된 일들을 해당 앱에게 위임합니다. 이를 통해 알림 메세지를 클릭 했을 때 해당 앱으로 들어가는 이벤트를 감지할 수 있습니다.

 

    func scheduleDailyNotification() {
        // 로컬 알림 컨텐츠 설정
        let nContent = UNMutableNotificationContent()
        nContent.badge = 2
        nContent.title = "로컬 알림 메세지"
        nContent.subtitle = "서브 타이틀"
        nContent.body = "바디 부분입니다"
        nContent.sound = UNNotificationSound.default
        nContent.userInfo = ["name": "김태형"] //
        
        // Calendar 트리거 설정 (매일 특정 시간에 알림 설정)
        var dateComponents = DateComponents()
        dateComponents.hour = 12 // 예: 10시
        dateComponents.minute = 15 // 예: 00분
        
        // 알림 발송 조건 객체
        let trigger = UNCalendarNotificationTrigger(dateMatching: dateComponents, repeats: true)
//        let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 3, repeats: false)      // 시간 주기에 따라 알림 발송

        
        // 알림 요청 객체 생성
        let request = UNNotificationRequest(identifier: "dailyNotification", content: nContent, trigger: trigger)
        
        // 알림 등록
        UNUserNotificationCenter.current().add(request) { (error) in
            if let error = error {
                print("매일 푸시 알림 등록 실패: \(error.localizedDescription)")
            } else {
                print("매일 푸시 알림이 설정되었습니다.")
            }
        }
    }

해당 부분은 메서드를 보면 이해가 될 것이기 때문에 보면서 이해하시면 될 것 같습니다.

 

그나마 눈여겨 볼 점은 알림 발송을 시간을 주기로 설정할 것인지, 매일 특정 시간에 대해 나타낼 것인지에 따라 사용되는 메서드가 다르기 때문에(UNTimeIntervalNotificationTrigger, UNCalendarNotificationTrigger) 이를 알고 계시면 좋을 것 같습니다.

 

// 특정 요일에 알람을 보내고 싶을 때
    func scheduleWeekdayNotifications() {
        // 로컬 알림 컨텐츠 설정
        let nContent = UNMutableNotificationContent()
        nContent.badge = 2
        nContent.title = "로컬 알림 메세지"
        nContent.subtitle = "서브 타이틀"
        nContent.body = "바디 부분입니다"
        nContent.sound = UNNotificationSound.default
        nContent.userInfo = ["name": "김태형"]

        // 월요일(2)부터 금요일(6)까지 알람 발송
        for weekday in 2...6 {
            var dateComponents = DateComponents()
            dateComponents.weekday = weekday
            dateComponents.hour = 12 // 예: 12시
            dateComponents.minute = 15 // 예: 15분

            // 알림 발송 조건 객체
            let trigger = UNCalendarNotificationTrigger(dateMatching: dateComponents, repeats: true)

            // 알림 요청 객체 생성
            let request = UNNotificationRequest(identifier: "weekdayNotification\(weekday)", content: nContent, trigger: trigger)

            // 알림 등록
            UNUserNotificationCenter.current().add(request) { (error) in
                if let error = error {
                    print("평일 푸시 알림 등록 실패: \(error.localizedDescription)")
                } else {
                    print("평일 푸시 알림이 설정되었습니다.")
                }
            }
        }
    }
  • 또한 특정 요일에 알람을 발송하고 싶을 때에는 .weekday를 통해 지정할 수 있습니다.

 

 

 

이렇게 로컬 알림에 대해 알아보았습니다. 다음에는 서버 알림에 대해 알아보도록 하겠습니다.

728x90

'iOS' 카테고리의 다른 글

[iOS] SwiftLint 설치 및 적용하기  (0) 2023.12.23
[iOS] 협업 시 하나의 Bundle Identifier로 설정하기 (Provisioning Profile, Certificate 공유)  (0) 2023.11.21
[iOS] Firebase FCM을 이용한 서버 푸시 구현  (4) 2023.11.15
[iOS] 앱스토어 배포하기 및 배포 과정  (2) 2023.09.09
코코아팟(cocoapod) 설치 및 사용 방법  (0) 2023.08.17
  1. 로컬 알림
  2. UNMutableNotificationContent
  3. UNTimeIntervalNotificationTrigger
  4. UNNotificationRequest
  5. UNUserNotificationCenter
  6. 예시
'iOS' 카테고리의 다른 글
  • [iOS] 협업 시 하나의 Bundle Identifier로 설정하기 (Provisioning Profile, Certificate 공유)
  • [iOS] Firebase FCM을 이용한 서버 푸시 구현
  • [iOS] 앱스토어 배포하기 및 배포 과정
  • 코코아팟(cocoapod) 설치 및 사용 방법
Dev_Ted
Dev_Ted
250x250
Dev_Ted
프로그래밍 성장기
Dev_Ted
전체
오늘
어제
  • 분류 전체보기 (123) N
    • CS (10)
      • 자료구조 (Data Structure) (1)
      • 알고리즘 (Algorithm) (5)
      • 데이터베이스 (Database) (0)
      • 네트워크 (Network) (0)
      • 컴퓨터 구조 (Computer Architecture) (0)
      • 운영체제 (Operating System) (0)
      • 프로그래밍 언어 (Programming Language) (2)
    • PS (78)
      • BOJ (78)
      • LeetCode (0)
    • Swift (6)
      • 문법 (0)
    • iOS (21) N
      • UIKit (5)
      • SwiftUI (4)
      • 디자인 패턴 (2)
      • NumberterKit (2) N
    • 인프라 (Infrastructure) (1)
      • 도커 (Docker) (1)
      • NGINX (0)
    • 책 (1)
    • 기타 (6)
      • Error (3)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • 그리디 알고리즘
  • 자료 구조
  • 문제해결
  • PS
  • SWIFT
  • 스위프트
  • ios
  • apple
  • DP
  • 큐
  • 알고리즘
  • Data Structure
  • 자료구조
  • 정렬
  • 백준
  • 투 포인터
  • 이분 탐색
  • 스택
  • 그리디
  • BOJ

최근 댓글

최근 글

hELLO · Designed By 정상우.v4.2.0
Dev_Ted
[iOS] UserNotification을 사용하여 로컬 알림 만들기
상단으로

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.