iOS/Swift

[iOS] 로컬 푸쉬 알림 (Local Notification)

유훈 | Yuhun 2022. 2. 15. 03:30
반응형

앱에서 푸쉬 알림을 보내는 방법은

1. local에서 보내는 방법

2. apns를 통해 외부에서 보내는 방법이 있습니다.

 

이중 로컬에서 푸쉬 알림을 보내는 방법을 정리해 보겠습니다.

일단 로컬에서는 푸쉬를 보낼때 세가지 조건에 맞춰 보낼수 있습니다.

1. 특정 시간에

2. 일정 시간마다

3. 지정한 위치에 따라

 

"첫번째인 특정 시간" 을 기준으로 로컬에서 푸쉬 알림을 보내보도록 하겠습니다.

먼저 푸쉬 알림을 보내기 위해서는 내장 라이브러리인 UserNotifications를 사용합니다.

 

iOS 에서는 유저에게 권한을 받아와야 합니다. 앱을 켜면 권한을 받아오도록 작성해 보겠습니다.

//AppDelegate.swift

// 클래스 안의 함수 
// 앱이 실행되면 실행되는 함수
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        
        // 알림 센터 가져오기
        let center = UNUserNotificationCenter.current()
        center.delegate = self // delegate 패턴을 이용한 처리 (extension으로 구현)
        
        // 권한 종류 만들기 (뱃지와 소리)
        let options = UNAuthorizationOptions(arrayLiteral: [.badge, .sound])
        
		// 권한 요청 메서드(꼭 이곳이 아니어도 원할때 권한을 받을 수 있다.)
        center.requestAuthorization(options: options) { success, error in
            // 권한에 따라 success가 허용->true, 거부->error
            
            if let error = error {
                print("에러 발생: \(error.localizedDescription)")
            }
        }
        
    
    // center.delegate = self에 대한 설정
    
    // User 알림에 대한 delegate 설정
extension AppDelegate: UNUserNotificationCenterDelegate {
    
    // 앱이 foreground에 있을때 알림이 오면 이 메서드 호출
    func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
        // 푸쉬가 오면 다음을 표시하라는 뜻
        // 배너는 배너, 뱃지는 앱 아이콘에 숫자 뜨는것, 사운드는 알림 소리, list는 알림센터에 뜨는거
        completionHandler([.banner, .badge, .sound, .list])
    }
    
    // 사용자가 알림을 터치하면 이 메서드 호출
    func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
        
        // apns에 simulator Target Bundle 아래에 추가로 전달될 값(여기선 다루지 않음)
        // let value = response.notification.request.content.userInfo["key값"]
    }
}

이제 앱을 처음 실행하면 유저에게 권한을 물어보는 창이 뜨게 됩니다.

delegate로 구현한 extensioni에서는 willPresent만 사용할 예정입니다. 위와 같이 설정해 주어야 앱이 실행중일 때도 푸쉬 알림이 옵니다. (원래는 백그라운드 상태에서만 알림이 옵니다.)

 

기본적으로 권한을 부여 받았으니 이제 푸쉬를 등록하고 삭제하는 방법을 알아보겠습니다.

 

푸쉬 알림 등록 방법

notificationCenter에 푸쉬 알림을 등록하는 과정은 다음과 같습니다.

 

1. request 생성 - identifier: 고유값, content: 내용, trigger: 트리거를 설정해 주어야 합니다.

2. request 등록

 

예시 : 일정 시간:분 일때 알림이 가도록 설정

// 리퀘스트 정보
let content = UNMutableNotificationContent()
content.title = "제목"
content.body = "알림 내용"
content.sound = .default // 사운드 설정
content.badge = 1 // 뱃지(앱 아이콘에 표시될 뱃지)

// 트리거 만들기1
var date = DateComponents()
let formmater = DateFormatter()
formmater.dateFormat = "K" // k는 hour를 24시간제로 보여줍니다.
date.hour = Int(formmater.string(from: "Date객체"))
formmater.dateFormat = "mm"
date.minute = Int(formmater.string(from: "Date객체"))
let trigger = UNCalendarNotificationTrigger(dateMatching: date, repeats: true)

// 트리거 만들기2 -> 이렇게도 된다.
let component = Calendar.current.dateComponents([.hour, .minute], from: "Date객체")
let trigger = UNCalendarNotificationTrigger(dateMatching: component, repeats: "Bool 값에 따라 반복 설정")

// 리퀘스트 생성
let request = UNNotificationRequest(identifier: "고유값을 넣어 푸쉬 종류 구분", content: content, trigger: trigger)

// 알림 센터에 등록
UNUserNotificationCenter.current().add(request, withCompletionHandler: nil)

 

이제 date 객체의 시간에 따라 푸쉬 알림이 옵니다.

추가로 제가 본 강의에서는 위의 로직을 extension을 이용해 UNUserNotificationCenter에 함수로 추가해 알림을 사용했습니다.

예제 코드는 다음과 같습니다.

import Foundation
import UserNotifications

extension UNUserNotificationCenter {
    
    // request 추가인듯(json 형식의 apns를 대신하는 내부적 요청이 아닐까?)
    func addNotificationRequest(_ 파라미터) {
		// 위의 로직
    }
}

// 다른 곳에서 다음 처럼 부를수 있다.
UNUserNotificationCenter.current().addNotificationRequest(파라미터)

 

알림 센터에서 삭제하는 방법은 다음과 같습니다.

// 미결 알림 해제
UNUserNotificationCenter.current().removePendingNotificationRequests(withIdentifiers: "등록할 때의 고유값")

 

위에서 알림을 보낼때 뱃지에 1을 주어 어플에 뱃지가 뜨게 되는데 앱이 화면에 나타날때 이를 조절해주는 방법은 다음과 같습니다. (뱃지에 관한 부분은 서버에서 보내는 알림 관련해서 보충 필)

SceneDelegate로 가서 sceneDidBecomeActive 함수에 다음을 입력하시면 됩니다.

UIApplication.shared.applicationIconBadgeNumber = "뱃지 숫자"

 

이런 방식으로 로컬에서 알림을 등록해서 사용하실 수 있습니다.

 

반응형