Language/iOS,AOS

Xcode Firebase 푸시 설정

건담아빠 2023. 2. 1. 21:22

Swift 기반에 FCM(Firebase Cloud Messaging) 푸시 알림을 설정해 보자!

 

 

1. Capability 설정

Background Modes 추가

Capability -> `+` 추가 -> Background Modes 추가

Capability -> `+` 추가 -> Background Modes 추가

 

Background Modes 추가 누르면 아래와 같이 뜬다.

필자는 CHnage All 해버렸다..!

The Background Modes capability should not be varied by configuration.

Make changes to Background Modes by changing all configurations.

 

추가 후 Remote notifications를 체크해 준다.

 

Push Notification

Capability -> `+` 추가 -> Push Notification 추가

Capability -> `+` 추가 -> Push Notification 추가

 

 

아래 에러가 발생하면 Product > Clean Build Folder.

Entitlements file "Storyboard1Debug.entitlements" was modified during the build, which is not supported. You can disable this error by setting 'CODE_SIGN_ALLOW_ENTITLEMENTS_MODIFICATION' to 'YES', however this may cause the built product's code signature or provisioning profile to contain incorrect entitlements.

 

 

2. 코드 적용

코코아팟 적용

아래 포스팅 참조해서 Podfile 에 Firebase/Analytics, Firebase/Messaging 만 추가하고 설치해주면 끝이다.

https://dchkang83.tistory.com/104

 

iOS/Xcode 14X - 2. CocoaPods 추가

CocoaPods란? dependacy management & 많은 xcode 프로젝트 라이브러리 들을 관리한다. (gradle?, maven? 등의 역할!!) Xcode에서 라이브러리 관리(Dependency Management)해주는 방법에는 대표적으로 3가지가 있다 CocoaPod

dchkang83.tistory.com

Podfile

# Uncomment the next line to define a global platform for your project
# platform :ios, '9.0'

target 'Storyboard1' do
  # Comment the next line if you don't want to use dynamic frameworks
  use_frameworks!

  # Pods for Storyboard1
  pod 'Firebase/Analytics'
  pod 'Firebase/Messaging'

end

 

AppDelegate 설정

구글링 해보면 레퍼런스 엄청 많으니 그것들 참고하시고 필자는 대충 이렇게 짜서 성공했다.

아직 갈길이 멀었으니 일단 대충 궈궈!!

import UIKit
import Firebase
import FirebaseMessaging
import AVFoundation

@main
class AppDelegate: UIResponder, UIApplicationDelegate {
    
    var mainVC: MainViewController?
    
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        FirebaseApp.configure()
        
        registerForPushNotifications()
        application.registerForRemoteNotifications()
        
        return true
    }
    
    ...
}

extension AppDelegate {
    private func registerForPushNotifications() {
        UNUserNotificationCenter.current()        
            .requestAuthorization(options: [.alert, .sound, .badge]) { granted, _ in
                print("##### Permission granted: \(granted)")
                // 추가
                guard granted else { return }
                self.getNotificationSettings()
            }
        
    }
    
    private func getNotificationSettings() {
        UNUserNotificationCenter.current().getNotificationSettings { settings in
            print("##### Notification settings: \(settings)")
        }
    }
    
}

// MARK: UNUserNotificationCenterDelegate
extension AppDelegate: UNUserNotificationCenterDelegate {
    func application(application: UIApplication,
                     didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
        Utils.Log("didRegisterForRemoteNotificationsWithDeviceToken deviceToken : \(deviceToken)")
    }
    public func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {

        let userInfo = notification.request.content.userInfo;
        Utils.Log("userNotificationCenter willPresent : \(userInfo)")
        UIApplication.shared.applicationIconBadgeNumber = 0;

        completionHandler([.alert, .badge, .sound]);
    }
    /*
      Function that the app is called while background or not running
     */
    public func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
        UIApplication.shared.applicationIconBadgeNumber = 0;
        let userInfo = response.notification.request.content.userInfo;
        
        Utils.Log("userNotificationCenter didReceive : \(userInfo)")
        
        completionHandler()
    }
}

// MARK: MessagingDelegate
extension AppDelegate: MessagingDelegate {
    func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String?) {
        Utils.Log("Firebase registration token: \(String(describing: fcmToken))")

        if let token = fcmToken {
            Utils.Log("FCM Token : \(token)")
            UserDefaults.standard.set(token, forKey: "fcmToken")
            UserDefaults.standard.synchronize()
        }
        // 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 messaging(_ messaging: Messaging, didReceive remoteMessage: MessagingDelegate) {
        Utils.Log("Received data message: \(remoteMessage.description)")
    }
}

푸시메세지 요청 권한 팝업

 

3. 푸시 발송

파이어 베이스 사이트에서 푸시 발송 메시지 작성

 

기기에서 테스트 하려면 Xcode 실행시에 나오는 번호 입력해서 추가하면 해당기기만 발송된다.

저거 입력 안하면 앱 깔린 전체단말기에 발송되니깐 필요따라서 쓰면될듯하다.

 

발송 및 수신 성공