[iOS]FCMによるプッシュ-Xcodeの実装


1.Xcode>target>Push Notificationsとバックグラウンドモードの追加


バックグラウンド・モードでのリモート通知項目の確認

2.GoogleService-Infoからプロジェクトへ。plistファイルの追加



3.AppDelegateにソースを追加


AppDelegate.h
//1.UserNotifications 라이브러리 임포트
#import <UserNotifications/UserNotifications.h>

//2.파이어 베이스 메시징 라이브러리 임포트
@import Firebase;
@import FirebaseMessaging;
AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    
    [FIRApp configure];
    [FIRMessaging messaging].delegate = self;
       
    // Register for remote notifications. This shows a permission dialog on first run, to
    // show the dialog at a more appropriate time move this registration accordingly.
    // [START register_for_notifications]
	if ([UNUserNotificationCenter class] != nil) {
		// iOS 10 or later
		// For iOS 10 display notification (sent via APNS)
		[UNUserNotificationCenter currentNotificationCenter].delegate = self;
		UNAuthorizationOptions authOptions
        = UNAuthorizationOptionAlert | UNAuthorizationOptionSound | UNAuthorizationOptionBadge;
		[[UNUserNotificationCenter currentNotificationCenter]
          requestAuthorizationWithOptions:authOptions
          completionHandler:^(BOOL granted, NSError * _Nullable error) {
			// ...
		}];
    }

    [application registerForRemoteNotifications];
    return [super application:application didFinishLaunchingWithOptions:launchOptions];
}
/*  애플 푸시 셋팅 관련 델리게이트 메소드 */
//APNS 등록이 성공하고 DeviceToken을 전달받으면 아래 메서드가 실행된다.
//NSData 형식의 deviceToken 인자가 전달된다.
- (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)devToken {

    //토큰형식 변경
    NSString *str = [self stringFromDeviceToken:devToken];
    NSLog(@"애플 APNS에서 받은 token: %@", str);
    
    //실제 서비스라면 이 토큰을 사용자 정보와 함께 프로바이더에게 전달하여 관리를 할 필요가 있음.
    //Provider에게 DeviceToken을 전송한다.
	//예) [self sendProviderTokenString:[deviceToken bytes]];
}
//APNS 서버에 등록 실패
- (void)application:(UIApplication *)app didFailToRegisterForRemoteNotificationsWithError:(NSError *)err {
    NSLog(@"APNS에 등록 실패 error: %@", err);
}
/*  파이어 베이스  푸시 셋팅 */
//앱이 최초 실행되면 이 메소드까지 실행되고 토큰을 받는다.
- (void)messaging:(FIRMessaging *)messaging didReceiveRegistrationToken:(NSString *)fcmToken {
    NSLog(@"### didReceiveRegistrationToken 호출 - 토큰 받기");
    NSLog(@"FCM registration token: %@", fcmToken);

    // TODO : 필요한 경우 토큰을 응용 프로그램 서버로 보냅니다.
    // 참고 :이 콜백은 앱이 시작될 때마다 그리고 새 토큰이 생성 될 때마다 시작됩니다.
    self.fcmToken = fcmToken;
}
//포그라운드에서 푸쉬 받기
- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler {
    NSDictionary *userInfo = notification.request.content.userInfo;
	NSLog(@"### willPresentNotification 호출 - 푸시 도착");

    // 파이어베이스 푸시서버 키
   if (userInfo[kGCMMessageIDKey]) {
        NSLog(@"Message ID: %@", userInfo[kGCMMessageIDKey]);
    }

     //메시지 전체 내용 출력
     NSLog(@"## 메시지 전체 내용 : %@", userInfo);

    // 선호하는 프리젠 테이션 옵션으로 변경
    completionHandler(UNNotificationPresentationOptionBadge | UNNotificationPresentationOptionAlert);
}
//포그라운드든 백그라운드든 유저가 푸쉬를 눌렀을때 발생
//사용자가 표시 알림을 누른 후 알림 메시지를 처리.
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void(^)(void))completionHandler {

    NSLog(@"### didReceiveNotificationResponse 호출 - 유저 푸시 클릭");
    NSDictionary *userInfo = response.notification.request.content.userInfo;
    
	// 파이어베이스 푸시서버 키
    if (userInfo[kGCMMessageIDKey]) {
        NSLog(@"Message ID: %@", userInfo[kGCMMessageIDKey]);
      }

    //메시지 전체 내용 출력
    NSLog(@"## 메시지 전체 내용 : %@", userInfo);

    completionHandler();
}
//ios 13에서 푸쉬 토큰 받는 형식 변경됨.
- (NSString *)stringFromDeviceToken:(NSData *)deviceToken {

    NSUInteger length = deviceToken.length;
    if (length == 0) {
        return nil;
    }
    const unsigned char *buffer = deviceToken.bytes;
    NSMutableString *hexString  = [NSMutableString stringWithCapacity:(length * 2)];

    for (int i = 0; i < length; ++i) {
        [hexString appendFormat:@"%02x", buffer[i]];
    }

    return [hexString copy];

}