버그 잡이

iOS/Swift FCM 환경 구축하기(Firebase Cloud Message) 본문

기타

iOS/Swift FCM 환경 구축하기(Firebase Cloud Message)

버그잡이 2021. 3. 1. 18:37

 

1.  FCM 구축하기

 

FCM 환경 구축 관련해서는 Firebase 공식 홈페이지에 잘 설명되어 있습니다.

공식 홈페이지가 잘 이해 안 되시는 분은 아래 Client님의 블로그를 참고하시면 되겠습니다.

 

https://firebase.google.com/docs/cloud-messaging/ios/client?hl=k

 

iOS에서 Firebase 클라우드 메시징 클라이언트 앱 설정

iOS 클라이언트 앱의 경우 Firebase 클라우드 메시징 APN 인터페이스를 통해 최대 4KB의 알림 및 데이터 페이로드를 수신할 수 있습니다. Objective-C 또는 Swift로 클라이언트 코드를 작성하려면 FI

firebase.google.com

https://medium.com/@jang.wangsu/ios-swift-fcm-firebase-cloud-messaging-push-메시지-설정해보기-852a9af23b9

 

 

 

2. FCM 구현 코드 살펴보기

 

이번 글에서 다루고 싶은 것은 FCM과 관련된 구현 코드에 대해서 이해하는 것 입니다.

 

//MARK:- FCM
extension AppDelegate: MessagingDelegate {
    
    // 1) APN 등록 및 사용자 권한 받기
    private func setUserNotification() {
        UNUserNotificationCenter.current().delegate = self

        let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound]
        UNUserNotificationCenter.current().requestAuthorization(
        options: authOptions,
        completionHandler: {_, _ in })

        application.registerForRemoteNotifications()
    }
    
    // 2) 토큰 받기
    func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String) {
        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.
    }
    
    // 3) 받은 메시지 처리
    func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any],
                     fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
        // TODO: Handle data of notification
        completionHandler(UIBackgroundFetchResult.newData)
    }
}

 

그냥 복붙해서 쓰면 알림이 잘 오기는 하는데, 코드 한줄 한줄의 의미에 대해서는 이해하지 않고 쓰는 제 자신을 발견했습니다. 코드 한줄한줄 이해하기 위해서 이렇게 블로그에 정리합니다.

 

 

 

 

1) 알림 권한 신청 (setUserNotification())

 

fcm 을 활용해서 알림을 보내려면 먼저 사용자의 동의가 필요하겠죠?

 

 

UNUserNotificationCenter.current().requestAuthorization()

 

이 코드로 인하여 알림 권한 팝업이 노출 됩니다.

completionHandler도 있는데 이를 활용하여 알림 팝업 dismiss 후 동작을 지정할 수 있습니다.

 

 

application.registerForRemoteNotifications() 

 

FCM도 결국 APN을 기반으로 수행되기 때문에 APN에 디바이스를 등록하는 작업을 해줘야합니다.

위 코드로 인하여 APN에 디바이스를 등록합니다.

 

 

 

 

2) 토큰 확인

 

application.registerForRemoteNotifications()

위 코드로 디바이스가 APN에 등록되면

 

application(_:didRegisterForRemoteNotificationsWithDeviceToken:)

메서드에서 token을 확인할 수 있다고 합니다.

하지만 FCM 공식 문서에서는 위 메서드가 아닌 FCM의 MessagingDelegate 안에 있는

messaging(_: didReceiveRegistationToken) 을 통해서 토큰을 받습니다.

이는 APN 토큰 셋팅까지 함께 해주기 때문에 그런 것 같습니다.

 

공식 문서를 보면 토큰 관련해서 아래와 같은 내용이 있는데요.

 

"재구성 사용 중지"라는 번역 때문에 헷갈릴 수 있는데

"Swizzling disabled" 를 말하는 것 입니다.

Swizzling이란 runtime때 어떤 메서드를 다른 메서드로 바꾸는 것을 말합니다. firabase에서 알림 토큰 등록 관련 method를 swizzling 해서 처리해주는 것 같은데, swizzling을 막으면 이것이 안 되니 수동으로 설정하라는 것입니다,

(swizzling 대한 구체적인 설명은 아래 zedd님의 블로그를 참고... zeddios.tistory.com/554)

 

아무튼 그래서 Swizzling이 disabled 되어 있는지 확인해야 하는데 어떻게 확인하냐?


medium.com/@LOG_TAG/method-swizzling-in-firebase-cloud-messaging-8de07ae4b226
위 글에서 info.plist에 있는 "FirebaseAppDelegateProxyEnabled" 를 no로 설정하면 swizzling이 disabled 된다고 하네요. 관련 설정을 검색해보니 기본적으로는 YES 설정인 것 같습니다. 

 

(아래 코드는 FirebasDiagonstic.m 파일에 있는 코드인데 기본 YES 로 되어 있네요.)

 

 

NotificationCenter.default.post(name: Notification.Name("FCMToken"), object: nil, userInfo: dataDict)

 

FCM 토큰 받는 코드에 위 코드가 있는데, 정확하지는 않지만 위 코드가 실행됨으로써 내부적으로 APN Token을 set 해주는 것이 아닐까 싶습니다.

 

 

 

 

3) 받은 메시지 처리

 

AppDelegate application:didReceiveRemoteNotification:

위 메서드를 통해서 FCM에서 받은 메시지를 custom하게 처리할 수 있는 것 같습니다.

 

(이 부분은 아직 커스텀 해보지 않았는데 이후 커스텀 하게 되면 내용 업데이트 하겠습니다)

 

 

 

 

 

 

*참고

 

developer.apple.com/documentation/usernotifications/registering_your_app_with_apns

firebase.google.com/docs/cloud-messaging/ios/client?hl=ko

 

 

 

반응형
Comments