[SwiftUI] CloudKit: Push Notifications

Junyoung Park·2022년 8월 24일
0

SwiftUI

목록 보기
52/136
post-thumbnail

Send Push Notifications using CloudKit in SwiftUI | Advanced Learning #24

CloudKit: Push Notifications

구현 목표

  • 클라우드 데이터베이스 레코드 추가 시 데이터 변동 사항에 대해서 구독 추가 가능
  • 푸시 노티피케이션 → 옵저버 및 특정 함수를 호출
  • 푸시 노티피케이션 구독

구현 태스크

  1. 푸시 노티피케이션 허락 요청
  2. 푸시 노티피케이션 구성(옵션, 구독 이름 등)
  3. 푸시 노티피케이션 추가

핵심 코드

    func subscribeToNotifications() {
        let recordType = CKRecord(recordType: "Fruits")
        let predicate = NSPredicate(value: true)
        let options: CKQuerySubscription.Options = [.firesOnRecordCreation]
        let subscription = CKQuerySubscription(recordType: recordType.recordType, predicate: predicate, subscriptionID: subscriptionID, options: options)
        let notification = CKSubscription.NotificationInfo()
        notification.title = "There's a new fruit!"
        notification.alertBody = "Open the app to check your fruit!"
        notification.soundName = "default"
        subscription.notificationInfo = notification
        CKContainer.default().publicCloudDatabase.save(subscription) { returnedSubscription, returnedError in
            if let returnedError = returnedError {
                print(returnedError.localizedDescription)
            } else {
                print("SUCCESSFULLY SUBSCRIBE NOTIFICATION")
            }
        }
    }
  • CKSubscription에 노티피케이션 정보를 등록
  • 어떤 레코드를 어떤 식으로 접근할 것인지, 어떤 시점에 푸시 노티피케이션을 사용할 것인지 커스텀 가능
  • 구독 아이디는 유니크해야 함

소스 코드

struct CloudKitPushNotificationBootCamp: View {
    @StateObject private var viewModel = CloudKitPushNotificationBootCampViewModel()
    var body: some View {
        VStack(spacing: 40) {
            Button {
                viewModel.requestNotificationPermission()
            } label: {
                Text("Request Notification Permission")
                    .font(.headline)
                    .fontWeight(.semibold)
                    .withDefaultButtonFormmating(Color.orange.opacity(0.8))
            }
            .withPressableStyle(0.8)
            Button {
                viewModel.subscribeToNotifications()
            } label: {
                Text("Subscribe to Notification")
                    .font(.headline)
                    .fontWeight(.semibold)
                    .withDefaultButtonFormmating(Color.blue.opacity(0.8))
            }
            .withPressableStyle(0.8)
            Button {
                viewModel.unsubscribeToNotification()
            } label: {
                Text("Unsubscribe to Notification")
                    .font(.headline)
                    .fontWeight(.semibold)
                    .withDefaultButtonFormmating(Color.pink.opacity(0.8))
            }
            .withPressableStyle(0.8)
        }
        .padding(.horizontal, 40)
    }
}
  • 푸시 노티피케이션 허용 알람 및 구독/구독 해제 버튼 UI 뷰
import SwiftUI
import CloudKit

class CloudKitPushNotificationBootCampViewModel: ObservableObject {
    let subscriptionID = "fruit_added_to_database"

    func requestNotificationPermission() {
        let options: UNAuthorizationOptions = [.alert, .sound, .badge]
        UNUserNotificationCenter.current().requestAuthorization(options: options) { success, error in
            if let error = error {
                print(error.localizedDescription)
            } else if success {
                print("NOTIFICATION PERMISSION SUCCESS")
                DispatchQueue.main.async {
                    UIApplication.shared.registerForRemoteNotifications()
                }
            } else {
                print("NOTIFICATION PERMISSION FAILURE")
            }
        }
    }
    
    func subscribeToNotifications() {
        let recordType = CKRecord(recordType: "Fruits")
        let predicate = NSPredicate(value: true)
        let options: CKQuerySubscription.Options = [.firesOnRecordCreation]
        let subscription = CKQuerySubscription(recordType: recordType.recordType, predicate: predicate, subscriptionID: subscriptionID, options: options)
        let notification = CKSubscription.NotificationInfo()
        notification.title = "There's a new fruit!"
        notification.alertBody = "Open the app to check your fruit!"
        notification.soundName = "default"
        subscription.notificationInfo = notification
        CKContainer.default().publicCloudDatabase.save(subscription) { returnedSubscription, returnedError in
            if let returnedError = returnedError {
                print(returnedError.localizedDescription)
            } else {
                print("SUCCESSFULLY SUBSCRIBE NOTIFICATION")
            }
        }
    }
    
    func unsubscribeToNotification() {
        CKContainer.default().publicCloudDatabase.delete(withSubscriptionID: subscriptionID) { returnedID, returnedError in
            if let returnedError = returnedError {
                print(returnedError.localizedDescription)
            } else {
                print("SUCCESSFULLY UNSUBSCRIBE NOTIFICATION")
            }
        }
    }
}
  • 구독과 달리 구독 해제는 클라우드 데이터베이스에 등록된 구독 아이디를 삭제하는 함수만 구현하면 됨
  • 노티피케이션의 제목, 알림 내용, 사운드 정보 등 커스텀 활용

구현 화면

  • 푸시 노티피케이션 허용 및 구독
  • 구독 이후 시뮬레이터 상 데이터 입력 시 푸시 노티피케이션 확인 가능
profile
JUST DO IT

0개의 댓글