티스토리 뷰

Remote Notification은 JSON payload 형태로 사용자에게 데이터를 전달한다.

 

여기서 payload(페이로드)란 간단히 전송되는 데이터를 의미한다고 보면 된다.

 

이번 글에서는 FCM을 이용해 Remote Notification을 띄우는 방법을 정리해보겠다.

 

 

 

Remote Notification의 동작 구조

 

 

먼저 디바이스에서 APNs로 토큰을 요청하고 받아오면, 디바이스는 이 토큰을 서버로 보낸다.

(*APNs: Apple Push Notification service의 약자로, 서버에서 알림을 보낼때 반드시 APNs를 통해서 보내야한다.)

 

서버(provider)가 푸시 토큰을 전달받았다면, 추후에 푸시를 전송할 때 APNs에 디바이스 토큰과 함께 보내고 싶은 데이터를 APNs로 보낸다.

 

마지막으로 APNs가 디바이스로 데이터를 보내면 알림이 뜨게 될 것이다.

 

 

 

Remote Notification 띄우기

 

 

앱에서 remote notification을 사용하기 위해서는 애플 개발자 계정이 등록되어 있어야한다(유료). 

 

또한, 시뮬레이터에서는 테스트를 하기 어려우므로 실기기에서 테스트하는 것을 추천한다.

 

위의 두 가지 조건이 만족되었다면, 본격적으로 remote notification을 보내보자.

 

 

인증서 발급받기

 

우선, 애플 푸시 알림 인증 키를 발급받아야한다. 

 

인증 키는 유료 애플 개발자 계정이 등록되어 있어야 발급가능한데, 하나의 키를 여러 앱에서 사용할 수 있다. 

(즉, 돈을 내야만 remote notification 사용 가능)

 

Apple Developer 사이트의 계정 탭에서 인증서 관련 페이지로 들어간 뒤, Key탭에서 +버튼을 눌러준다.

 

Key이름과 함께 APNs를 체크하여 등록하고 다운받으면 된다.

 

p8 인증서 파일이 다운받아질텐데, 다시 다운로드 할 수 없으므로 따로 보관하는 것을 추천한다.

 

* p8 vs p12

p8은 public key로 여러 앱에서 사용이 가능하고 만료기간도 없다.

하지만 한 번 다운로드를 하면 다시 다운로드 받을 수 없기때문에 따로 관리를 해줘야한다.

p12는 private key로, 각 앱 당 인증서(개발용 푸시 인증서, 배포용 푸시 인증서)가 필요하며, 만료기간은 1년이기때문에 매번 인증서를 갱신해주어야한다.

p8을 이용하자.

 

 

 

Xcode에서 푸시 알림 사용 설정

 

애플 개발자 계정, 실기기와 같이 기본적인 세팅이라고 생각하면된다.

 

프로젝트 - TARGETS - 상단의 Signing & Capabilities에서 표시한 버튼을 눌러 Background Modes와 Push Notifications를 추가해준다.

 

Background Modes에서 Remote notifications를 체크해준다.

 

 

Firebase Cloud System 연동

 

이제 FCM을 사용하기 위한 설정을 진행해보자.

 

 

인증 키 업로드

 

프로젝트 설정에 들어가서 상단의 클라우드 메시징 탭에서 아래의 화면을 볼 수 있을 것이다.

 

APN 인증 키에 다운받은 키를 업로드하면된다.

 

키 ID는 인증서 파일 가운데 부분을 적어주면되고, 팀ID는 개발자 계정에서 멤버십 탭에서 확인할 수 있다.

물음표 눌러서 이동하면 바로 확인 가능.

 

 

코드 구현

 

로컬 알림과 마찬가지로 원격 알림 권한을 등록해야하며, 푸시 메시지를 파이어베이스에서 대신 보내줄 수 있도록 대리자도 설정해줘야한다.

 

파이어베이스의 문서를 하나씩 따라가면 쉽게 작성 가능하다.

 

프로젝트에 Firebase가 추가되어있고, 메시징을 위해서는 FirebaseMessaging이 import되어있어야함.

현재 애널리틱스와 크래시리틱스를 사용중이었기때문에 Firebase, FirebaseCore, FirebaseMessaging이 import된 상태임

 

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.

        FirebaseApp.configure()
        
        //원격 알림 시스템에 앱 등록
        if #available(iOS 10.0, *) {
            // For iOS 10 display notification (sent via APNS)
            UNUserNotificationCenter.current().delegate = self
            
            let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound]
            UNUserNotificationCenter.current().requestAuthorization(
                options: authOptions,
                completionHandler: { _, _ in }
            )
        } else {
            let settings: UIUserNotificationSettings =
            UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil)
            application.registerUserNotificationSettings(settings)
        }
        
        application.registerForRemoteNotifications()
        
        //메세지 대리자 설정
        Messaging.messaging().delegate = self
        
        //등록된 토큰 가져오기
        Messaging.messaging().token { token, error in
            if let error = error {
                print("Error fetching FCM registration token: \(error)")
            } else if let token = token {
                print("FCM registration token: \(token)")
            }
        }
        
        return true
    }

 

AppDelegate에서 UNUserNotificationCenterDelegate와 MessagingDelegate를 채택한 상태.

    //포그라운드 알림 수신, 화면마다 푸시마다 설정할 수도 있음(카카오톡처럼)
    func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
        completionHandler([.sound, .list, .banner])
    }
    //푸시 클릭: 화면 전환같은 것도 가능
    //유저가 푸시를 클릭했을때에만 수신 확인 가능
    func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
        print("사용자가 푸시를 클릭함")
        
        print(response.notification.request.content.body) // 바디는 알림메세지의 내용
        print(response.notification.request.content.userInfo)// 파이어베이스에서 등록했던 키 밸류
        
        let userInfo = response.notification.request.content.userInfo
        
        if userInfo[AnyHashable("메인화면")] as? String == "메인" {
            print("성공")
        } else {
            print("실패")
        }
    }
    
    
    //토큰 갱신 모니터링
    func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String?) {
        print("Firebase registration token: \(String(describing: fcmToken))")
        
        let dataDict: [String: String] = ["token": fcmToken ?? ""]
        NotificationCenter.default.post(
            name: Notification.Name("FCMToken"),
            object: nil,
            userInfo: dataDict
        )
        // TODO: If necessary send token to application server.
        // Note: This callback is fired at each app startup and whenever a new token is generated.
    }
    
    func application(application: UIApplication,didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
        Messaging.messaging().apnsToken = deviceToken
    }

 

 

위와 같이 작성하고 빌드를 하게되면(실기기) FCM register token을 확인할 수 있을 것이다.

 

이제 정상적으로 알림이 오는지 파이어베이스에서 알림을 등록해보자.

 

 

알림 보내기

 

참여 탭에서 Messaging을 들어가서 새 캠페인을 누르고, 알림을 눌러준다.


이제 작성하는 부분이 나올텐데, 우선 테스트부터 진행해보자.

 

제목과 텍스트를 작성하고 테스트 메시지 전송을 누르면 이전에 콘솔창에서 보았던 FCM 토큰을 입력하는 창이 뜰 것이다.

 

 

토큰을 입력하고 + 버튼을 눌러 체크한 뒤, 메시지를 보내면 푸시 알림을 받을 수 있다.

테스트 메시지는 보내고 거의 30초 안에는 오는 것 같다.

 

테스트를 통해 확인해봤으니, 진짜 remote notification을 등록해보자.

 

미리 봤겠지만, 알림 - 타겟 - 예약 - 전환 이벤트 - 추가 옵션을 차례대로 작성해주면 된다.

 

우선 알림 단계에서 제목과 텍스트를 입력해준다.

알림 이미지 넣을라면 돈내야됨.

 

다음으로, 타겟 단계인데 말그대로 타겟을 설정하면된다. 

 

나는 펫모리 앱 프로젝트를 설정해주었다.

 

타겟을 정했다면 메시지를 언제 보낼지 예약 단계에서 설정하면된다.

 

나는 바로 보내기위해 지금을 선택할건데, 지금을 선택하더라도 오는데 몇 분정도 시간이 걸렸었다.

 

전환 이벤트는 선택사항이므로 넘기고 추가 옵션 단계로 가보자.

대충봐도 어떤 것을 설정하는지 알 수 있다.

 

이 중에서 맞춤 데이터 부분을 보면 키와 값이 보일 것이다.

 

이 부분은 사용자에게는 보이지않지만 개발 단계에서 처리할 수 있는 값을 정해주는 것이다.

 

알림별로 처리해줄 코드가 다를때 사용하면 될 것 같다.

 

일단, 키에 Petmory를 적고 값에는 heecheol을 적어서 알림을 보내보자.

 

 

검토를 누르고 게시를 누르면 아래와 같이 보일텐데, 시간이 지나면 상태가 활성에서 완료로 변할 것이고, 변한 뒤에 시간이 조금 지나면 알림을 받을 수 있을 것이다.

 

 

알림 받기

 

 

알림을 눌렀을 때, 위에서 설정한 키, 값 쌍을 확인해보기 위해 작성했던 didReceice 메서드를 바꿔주었다.

 

오는데 5분은 걸린 것 같다.

 

아무튼 알림이 왔으니 알림을 눌러서 확인해보자.

 

didReceive 메서드의 response에는 많은 데이터가 담겨있다.

 

위에서 볼 수 있듯이 body로 알림을 보낼때 작성했던 값도 확인할 수 있고, userInfo를 이용하여 작성했던 키 값 쌍도 확인할 수 있다.

 

이때 알야할 점들이 있따.

 

푸시 알림이 수신되었는지는 확인할 수 없고, 사용자가 푸시를 탭했을 경우에만 확인할 수 있다.

 

또한, 따로 로직을 구현하지 않고 푸시를 탭한다면 앱을 Active 상태로 올려주기만 한다.

 

이를 잘 이용한다면, 푸시의 종류에 따라 특정 화면으로 이동시킬 수도 있을 것이다.

 

 

댓글
최근에 올라온 글
Total
Today
Yesterday