Push Notification


애플리케이션의 푸시 알림을 보내는 방법은 크게 로컬과 서버로 나뉜다. 서버에서 푸시 알림을 보내는 방법은 APNS, Firebase Messaging, One Signal 등등 다양한 방법이 있다.
APNS의 경우 애플에서 공식적으로 지원하는 Notification Center이지만, 이를 이용하기 위해서는 Apple Developer Program에 가입해야 하는 것으로 알고 있다. 간단히 서버를 통해 푸시 알림을 보내기 위해서는 Firebase MessagingOne Signal을 이용하는 것이 좋지만 특정 시간에 알림을 주는 것만으로 충분하기 떄문에 굳이 서버까지는 활용하지 않았다.


Local Push Notification Test


Local Push Notification을 구현하기 위해서는 사용자에게 푸시 알림에 관한 권한을 받아온 후, Content, Trigger, Request의 세가지 요소를 활용해야 한다.
Content는 푸시 알림에 들어갈 내용을, Trigger는 푸시 알림이 나타나기 위한 조건을, RequestContentTrigger를 활용해 푸시 알림을 등록 또는 취소하는 역할을 한다.

푸시 알림에 관한 권한 설정과 알림 내용에 관한 설정은 앱의 화면이 로드 되기 전에 미리 끝나있어야 하는 것으로 AppDelegateapplication(_:willFinishLaunchingWithOptions:) 또는 application(_:didFinishLaunchingWithOptions:)에 작성되어 있어야 한다. 따라서 다음과 같이 작성할 수 있다.

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    UNUserNotificationCenter.current().delegate = self
    requestNotificationAuthorization()
    sendNotification(hour: 21, minute: 40)
    return true
}




UNUserNotificationCenter.current().delegate를 지정해줌으로써, UNUserNotificationCenterDelegate를 통해 앱이 foreground에 있을 때의 푸시 알림 처리 등을 프로그래머가 직접 지정할 수 있다. 굳이 지정하지 않아도 푸시 알림을 띄우는 데에는 문제가 없다.

func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
    completionHandler([.alert, .badge, .sound])
    // 앱이 foreground 상태일 때 푸시 알림 처리
}
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
    if response.actionIdentifier == UNNotificationDismissActionIdentifier {

    }
    else if response.actionIdentifier == UNNotificationDefaultActionIdentifier {

    }
    // 시스템 표준 액션에 대해 다룰 때
}

액션에 관해서는 이 글을 통해 자세히 확인할 수 있다.


그 다음으로 권한 요청 및 푸시 알림 등록을 구현한다.

func requestNotificationAuthorization() {
    let authOptions = UNAuthorizationOptions(arrayLiteral: .alert, .badge, .sound)
    
    UNUserNotificationCenter.current().requestAuthorization(options: authOptions) { (success, error) in
        if let error = error {
            print(error.localizedDescription)
        }
    }
    // 권한 요청
}
func sendNotification(hour: Int, minute: Int) {
    let notificationContent = UNMutableNotificationContent()
    notificationContent.title = "알림 테스트입니다."
    notificationContent.body = "알림 테스트"
    
    var date = DateComponents()
    date.hour = hour
    date.minute = minute
    let trigger = UNCalendarNotificationTrigger(dateMatching: date, repeats: true)
    let request = UNNotificationRequest(identifier: "testNotification", content: notificationContent, trigger: trigger)
    
    UNUserNotificationCenter.current().add(request, withCompletionHandler: nil)
    // 푸시 알림 등록
}

trigger의 경우 Calendar, TimeInterval, Location의 세 종류가 있다. 여기서는 매일 특정 시간마다 알림을 주어야 해서 Calendar를 사용했다.

2020.12.08 추가) 전체 소스코드는 이 곳에서 확인할 수 있다.



원래대로라면 AVCam 코드를 뜯어보며 실습하는 내용을 포스팅했어야 했지만 어쩌다보니 개인 프로젝트에 푸시 알림을 써보고 싶다는 생각에 미뤄져서 결국 관련 포스팅까지 하게 되버렸다.(..) 개인 프로젝트가 마무리되어 가고 있는 만큼, 얼른 끝내고 AppStore에 출시까지 해 본 후에 AVCam에 관해 진행하려 한다.
그런데 요새는 SwiftUI도 건드리고 있어서… 훨씬 뒤로 밀려날지도 모르겠다. 으악!


참고: https://developer.apple.com/library/archive/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/SchedulingandHandlingLocalNotifications.html
https://onelife2live.tistory.com/33