Mobile/iOS
iOS FCM 푸시 알림 #3 - 코드작성 및 테스트
WonYoungJae
2023. 1. 30. 15:41
코드 작성
Objective-c
// AppDelegate.h
#import <UIKit/UIKit.h>
// 추가
@protocol FIRMessagingDelegate;
@interface AppDelegate : UIResponder <UIApplicationDelegate, FIRMessagingDelegate /*추가*/>
@end
// AppDelegate.m
#import "AppDelegate.h"
@import FirebaseCore;
// 추가
@import FirebaseMessaging;
@import UserNotifications;
@interface AppDelegate ()
@end
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[FIRApp configure];
[FIRMessaging messaging].delegate = self;
[UNUserNotificationCenter currentNotificationCenter].delegate = self;
// 푸시 알림 권한 (알림, 뱃지, 사운드)
UNAuthorizationOptions authOptions = UNAuthorizationOptionAlert |
UNAuthorizationOptionSound | UNAuthorizationOptionBadge;
[[UNUserNotificationCenter currentNotificationCenter]
requestAuthorizationWithOptions:authOptions
completionHandler:^(BOOL granted, NSError * _Nullable error) {
// ...
}];
[application registerForRemoteNotifications];
return YES;
}
// APNs에 기기정보 등록
-(void)application:(UIApplication *)application
didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
NSLog(@"deviceToken : %@", deviceToken);
[FIRMessaging messaging].APNSToken = deviceToken;
}
// 푸시 알림이 도착했을 때
- (void)application:(UIApplication *)application
didReceiveRemoteNotification:(NSDictionary *)userInfo
fetchCompletionHandler:(void
(^)(UIBackgroundFetchResult))completionHandler {
[[FIRMessaging messaging] appDidReceiveMessage:userInfo];
// 알림이 오면 뱃지 갯수를 1 증가 시켜준다.
application.applicationIconBadgeNumber = application.applicationIconBadgeNumber + 1;
completionHandler(UIBackgroundFetchResultNewData);
}
// 사용자가 앱에 들어왔을때
- (void)applicationDidBecomeActive:(UIApplication *)application {
// 뱃지 갯수를 0으로 바꿔준다.
UIApplication.sharedApplication.applicationIconBadgeNumber = 0;
}
// 여기서 받은 FCM 토큰으로 푸시 알림 전송할 수 있다.
- (void)messaging:(FIRMessaging *)messaging
didReceiveRegistrationToken:(NSString *)fcmToken {
NSLog(@"FCM registration token: %@", fcmToken);
[[NSNotificationCenter defaultCenter] postNotificationName:
@"FCMToken" object:nil userInfo:dataDict];
}
// 앱이 포그라운드 상태일 때 푸시 알림이 왔을 경우 푸시 알림을 노출 방식 설정
- (void)userNotificationCenter:(UNUserNotificationCenter *)center
willPresentNotification:(UNNotification *)notification
withCompletionHandler:(void
(^)(UNNotificationPresentationOptions))completionHandler {
// completionHandler에 아무것도 주지 않으면 사용자에겐 아무것도 보이지 않은다.
completionHandler(UNNotificationPresentationOptionBadge /* 알림 벳지 */
| UNNotificationPresentationOptionAlert /* 알림창 생성 */
| UNNotificationPresentationOptionSound /* 사운드 재생 */);
}
// 앱이 실행중이 아니거나 백그라운드 상태일 때
- (void)userNotificationCenter:(UNUserNotificationCenter *)center
didReceiveNotificationResponse:(UNNotificationResponse *)response
withCompletionHandler:(void(^)(void))completionHandler {
NSDictionary *userInfo = response.notification.request.content.userInfo;
[[FIRMessaging messaging] appDidReceiveMessage:userInfo];
// 포그라운드 상태일 때와 다르게 보내는 푸시 알림의 노출 방식 설정에 따라 움직인다.
completionHandler();
}
// 에러 났을 때
- (void)application:(UIApplication *)application
didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
NSLog(@"Unable to register for remote notifications: %@", error);
}
@end
Swift
// AppDelegate.swift
import UIKit
import UserNotifications
import FirebaseCore
import FirebaseMessaging
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication
.LaunchOptionsKey: Any]?) -> Bool {
FirebaseApp.configure()
Messaging.messaging().delegate = self
UNUserNotificationCenter.current().delegate = self
let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound]
UNUserNotificationCenter.current().requestAuthorization(
options: authOptions,
completionHandler: { _, _ in }
)
application.registerForRemoteNotifications()
return true
}
func application(_ application: UIApplication,
didReceiveRemoteNotification userInfo: [AnyHashable: Any]) {
print(userInfo)
}
func application(_ application: UIApplication,
didReceiveRemoteNotification userInfo: [AnyHashable: Any]) async
-> UIBackgroundFetchResult {
print(userInfo)
return UIBackgroundFetchResult.newData
}
func application(_ application: UIApplication,
didFailToRegisterForRemoteNotificationsWithError error: Error) {
print("Unable to register for remote notifications: \(error.localizedDescription)")
}
func application(_ application: UIApplication,
didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
print("APNs token retrieved: \(deviceToken)")
}
}
extension AppDelegate: UNUserNotificationCenterDelegate {
func userNotificationCenter(_ center: UNUserNotificationCenter,
willPresent notification: UNNotification) async
-> UNNotificationPresentationOptions {
let userInfo = notification.request.content.userInfo
print(userInfo)
return [[.alert, .sound, .badge]]
}
func userNotificationCenter(_ center: UNUserNotificationCenter,
didReceive response: UNNotificationResponse) async {
let userInfo = response.notification.request.content.userInfo
print(userInfo)
}
}
extension AppDelegate: MessagingDelegate {
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
)
}
}
테스트
- FCM 콘솔에서 첫 번째 캠페인 만들기 클릭
- Firebase 알림 메시지 선택 후 만들기 클릭
- 제목, 알림 텍스트 입력 후 테스트 메시지 전송 클릭
- FCM 등록 토큰 클릭 후 앱 실행해서 로그에 찍힌 FCM 토큰 입력
- 플러스 버튼 클릭 후 테스트 클릭
- 앱에 푸시 알림이 오면 푸시 알림 구현 성공
728x90