iOS Firebase Push 사용하기

iOS 2019. 4. 26. 17:58

iOS 로 앱을 만들고, 푸쉬를 보내도 아무런 문제가 없습니다. 하지만, firebase와 통합을 하면, firebase를 통해 안드로이드 iOS까지 모두 문자를 보내 관리할 수 있습니다. 더구나, 유니티로 푸쉬를 보내려면, Firebase로 관리하면 깔끔 하므로, 그렇게 하는것이 좋습니다.

 

[선행작업]

프로비저닝 프로파일 만들기 (푸쉬 인증서 설명도 같이 있음) : https://nicgoon.tistory.com/202 .

 

[공식 문서]

iOS에서 Firebase 클라우드 메시징 클라이언트 앱 설정 : https://firebase.google.com/docs/cloud-messaging/ios/client?authuser=0 .
iOS 앱에서 메시지 수신 : https://firebase.google.com/docs/cloud-messaging/ios/receive?authuser=0 .

 

[주요링크]

파이어 베이스 : http://firebase.google.com/ .

 

 

 

1. xcode를 프로젝트 생성.

프로젝트를 생성하기전 푸쉬 관련 인증서 및 프로비저닝 파일을 모두 만들어 두시기 바랍니다.

먼저 싱글뷰 타입으로 프로젝트를 생성하기 바랍니다.

 

2. Firebase 프로젝트 생성.

파이어 베이스 첫 화면에서 콘솔로 이동 버튼을 눌러 콘솔로 이동합니다.

프로젝트 추가를 눌러 프로젝트를 생성합니다

프로젝트 추가 창이 뜨면, 적당한 값들을 입력하고, 프로젝트 만들기 버튼을 눌러 주도록 합니다.

그럼 프로젝트가 추가 되고 해당 프로젝트가 선택된 상태의 프로젝트 화면이 표시 됩니다.

 

3. 앱생성 및 Firebase SDK 추가.

아래의 프로젝트가 선택된 화면 상태에서, iOS 추가 버튼을 눌러 해당 프로젝트에 iOS앱을 추가하도록 합니다.

앱등록 항목이 뜨면, xcode를 만들때 입력한 iOS와 일치하는 번들 ID를 입력하도록 합니다. 그리고, 앱 등록 버튼을 눌러 주도록 합니다.

그럼 구성파일 다운로드 파일이 나오 데, 파일을 다운로드하고, 설명대로 파일을 추가하도록 합니다. 그리고, 다음 버튼을 누르면 됩니다.

Firebase SDK를 설치하기 위해서는 CocoaPods 파일이 설치되어 있어야 합니다. 코코아 Pods는 단 한줄의 명령으로 설치가 가능하며, Xcode가 설치되어 있어야 아래와 같이 설치할 수 있는 것으로 보입니다.

$ sudo gem install cocoapods

xcode로 만든 프로젝트 폴더로 이동합니다. 그리고, Podfile을 생성합니다. (이미 생성되어 있다면 할 필요 없습니다.) 주의할점은 앞에 sudo를 붙여 권한을 얻으려고 하면 오동작 합니다.

pod init

Podfile을 열고 다음 코드를 추가합니다. 

pod 'Firebase/Core'

그런데 처음 열면 어디에 넣어야할 지 모르실 수 있습니다. 하지만, 애플애들이 이런거 놔둘 애들이 아닙니다. 아래와 같이 코드가 되어 있을 것 입니다. #Pods for firebasepush 주석 아래 넣어 두시기 바랍니다.

파일을 저장하고 다음 명령어를 실행하세요. (권한을 얻기 위해 앞에 sudo를 붙이면 오동작합니다.) 정상적으로 동작을 한다면, 알아서, firebase sdk가 설치됩니다. 앞서 프레임 워크 포드가 설치되는데, 이게 시간을 좀 많이 잡아 먹습니다. (이미 설치되어 있다면 설치하지 않을 수도 있습니다.) 이후 파이어 베이스 SDK가 정상적으로 설치가 완료 됩니다.

pod install

설치가 완료되면, 프레임 워크 라이브러리가 자동으로 설정됩니다. 저는 pod를 처음 사용해 보아, 프레임워크를 추가하려고 갔는데, 자동으로 떡 들어와 있었습니다.

여기서 가장 중요한 것은, 아래 페이지에서, [앱에 사용할 .xcworkspace 파일이 생성됩니다. 향후 애플리케이션의 모든 개발 작업에 이 파일을 사용하세요] 라는 문구 입니다. 그대로 하지 않으면 초기화 코드를 추가할 때, import Firebase 구문을 추가하면, Could not build Objective-C module 'Firebase' 라는 오류를 만납니다. xcode를 종료하고, 프로젝트 폴더에서 새로 생긴 [프로젝트명.xcworkspace] 파일을 더블클릭해 프로젝트를 다시 열여 줍니다. 그리고 아래 이미지 처럼 다음 버튼을 눌러 주도록 합니다.

그럼 파이어 베이스 초기화 코드를 추가하는 코드가 표시 되는데, 추가할 것은 프레임워크 추가 구문과 초기화 메소드 추가 호출 부분뿐입니다. 단, 2줄. 그대로 추가하고, 다음 버튼을 눌러 주도록 합니다. (여기서 오류가 난다면, xcode를 xcworkspace 확장자를 가진 파일을 더블클릭해 실행하지 않아서 일 경우가 많습니다.)

다음을 누르면, 앱이 통신을 했는지 확인하려고 계속 대기 화면이 호출됩니다. 기기와 맥북을 연결후 한 번 실행해 줍니다.

이 화면에서 오래 동안 확인을 못하면, 이전을 눌러 준뒤 다시 다음을 눌러 5번 항목으로와 빌드를 하면, 아래와 같은 화면을 볼 수 있습니다. (몇 번 앱을 빌드하고, 실행하고를 반복하면됩니다. - 한 두번 정도 입니다.). 콘솔로 이동 버튼을 눌러 콘솔로 이동하도록 합니다.

 

4. firebase messaging SDK 추가하기

여기서 부터는 iOS에서 Firebse 클라우드 메시징 클라이언트 앱 설정 ( 링크 ) 이라는 공식 문서를 보고 작성하였습니다. 앞으로 공식문서라 함은 iOS에서 Firebase 클라우드 메시징 클라이언트 앱 설정 문서를 가리킵니다.

지금까지 우리는 Firebase 의 기본을 추가했습니다. 이제는 Cloud Messaging 관련 SDK를 추가하도록 하겠습니다. 공식 문서의 앞 페이지 부분은 이미 구현을 하였고, firebase messaging SDK 추가합니다. 문서 내용을 보시면 알겠지만 앞서 파이어 베이스 SDK를 구성할 때 함께 했어도 문제는 없었을 것이지만, 문서가 나눠져 있으므로, 문서대로 하도록 하겠습니다.

앞서 수정했던, podfile 파일을 열어 다음과 같이 Messaging 을 추가하면됩니다. Core에 Messaging 파일을 추가하도록 합니다.

pod 'Firebase/Core'
pod 'Firebase/Messaging'

그리고, 콘솔을 열어 프로젝트 폴더로 이동한 뒤 다음과 같이 입력해 줍니다. ( 앞에서도 이야기 했지만, sudo 를 통해 권한을 획득하려 하면 오류가 납니다.)

$ pod install

그리고, 파인더에서, 프로젝트명.scworkspace 파일을 더블 클릭해, xcode를 실행하도록 합니다.

 

5. PushKit.framework 등록.

iOS자체 푸쉬는 PushKit 프레임워크를 사용합니다. 이 것만으로 모두, 푸쉬가 구현 가능하며, 많은 분들이 관리상의 이유로 파이어 베이스만 으로, android iOS를 구성합니다. 파이어 베이스 또한 단독으로 푸쉬를 구성한 것은 아니며, PushKit. 프레임 워크를 이용해 푸쉬 기능을 구현했습니다.

그래서 우리 프로젝트에도 Pushkit을 넣어 주어야 정상적으로 푸쉬 기능을 사용할 수 있습니다. 

프로젝트를 선택하고, Capabilities 탭에서, Push를 활성화 합니다.

그리고 Genral 탭을 눌러 프레임 워크를 포함해 주도록 합니다.

 

6. APN 인증키 업로드.

메시지를 보내려면,  APN 인증키와 메시지등을 함께 구글 Apple Push Notification Server로 요청을 해야 합니다. 이 때 메시지와 함께 키를 보내야 하는 데, 이 때사용하는 것이 APN 키 입니다. APN키외에도 인증서를 이용해 메시지를 요청하는 방법이 있지만, Firebase에서는 APN 인증키를 통해 하는 것을 권장하고 있습니다. 저는 2가지 방식을 다 사용해 봤는데, 여러모로 APN 인증키를 사용하는 방법이 편합니다. 

개발자 사이트로 이동해 Certificates, Identifiers & Profile 페이지로 가 Keys All 메뉴를 선택합니다. 해당 페이지가 나오면, + 버튼을 눌러 APN 키 만들기를 시작합니다.

아래의 예시를 참고해 페이지를 작성하고, Continue 버튼을 눌러 주도록 합니다.

다음 페이지는 APNs 관련 설명 이며 키가 만들어 진다는 내용 입니다. Confirm 을 눌러 생성하도록 합니다.

생성하면, 아래와 같은 화면이 나옵니다. Download를 눌러 키를 다운로드 하고, Done 키를 눌러 종료 하도록 합니다.

여기서 다운로드한 파일을 그대로, 파이어 베이스 프로젝트에 셋팅해 주면됩니다. 파이어 베이스 프로젝트 콘솔로가 프로젝트 페이지의 톱니바퀴 버튼을 눌러 뜬 메뉴에서 프로젝트 설정을 선택합니다.

여기서 클라우드 메시징 탭을 선택하고, APN 인증키 업로드 버튼을 눌러 주도록 합니다.

여기서 인증키 업로드창이 뜨는 데, 앞서 내용을 확인해 적절한 값들을 넣어 주고 업로드 버튼을 눌러 키를 업로드합니다.

 

7. 원격 알림등록.

공식 문서에서는 적절한 시점에 원격 알림을 등록하라고 되어 있습니다. 예제에서는 AkppDelegate.swift 파일의 func application 속에 등록하고 있습니다. 소스를 그대로 복사해 해당 위치에 추가합니다.

        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()

그리고 파이어 베이스 메시징을 프레임워크를 사용할 것임을 코드에 선언합니다. (파이어 베이스 문서에는 잘못되어 있을 수 있습니다. 저는 이 내용이 빠져 있더군요)

import FirebaseMessaging

여기까지 했다면, UNUserNotificationCenter.current().delegate = self 이 부분에 오류가 났을 것 입니다. 해당 델리게이트를 포함해 필요메소드를 정의해 주면 오류가 사라집니다. AppDelegate.swift 파일 끝에, ( AppDelegate 클래스 밖 )에 아래 소스를 복사합니다.

// [START ios_10_message_handling]
@available(iOS 10, *)
extension AppDelegate : UNUserNotificationCenterDelegate {
    
    // Receive displayed notifications for iOS 10 devices.
    func userNotificationCenter(_ center: UNUserNotificationCenter,
                                willPresent notification: UNNotification,
                                withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
        let userInfo = notification.request.content.userInfo
        
        // With swizzling disabled you must let Messaging know about the message, for Analytics
        // Messaging.messaging().appDidReceiveMessage(userInfo)
        // Print message ID.
        if let messageID = userInfo[gcmMessageIDKey] {
            print("Message ID: \(messageID)")
        }
        
        // Print full message.
        print(userInfo)
        
        // Change this to your preferred presentation option
        completionHandler([])
    }
    
    func userNotificationCenter(_ center: UNUserNotificationCenter,
                                didReceive response: UNNotificationResponse,
                                withCompletionHandler completionHandler: @escaping () -> Void) {
        let userInfo = response.notification.request.content.userInfo
        // Print message ID.
        if let messageID = userInfo[gcmMessageIDKey] {
            print("Message ID: \(messageID)")
        }
        
        // Print full message.
        print(userInfo)
        
        completionHandler()
    }
}
// [END ios_10_message_handling]

 

그러면, gcmMessageIDKey 값이 없어 오류가 날 것 입니다. AppDelegate 클래스의 멤버로, let gcmMessageIDKey = "gcm.message_id" 을 추가하면됩니다.

 

8. 메시지 대리자 설정.

앱이 시작되는 부분에 추가하면되며, 예제에는 AppDelegate.swift 파일에 application 메소드 속, FirebaseApp.configure() 메소드 아래에 포함되어 있습니다.

Messaging.messaging().delegate = self

이렇게 추가하면 MessagingDelegate 델리게이트를 상속하고 정의 해 주면됩니다. AppDelegate.swift 파일 속 AppDelegate 클래스 밖(문서 끝)에 아래의 코드를 추가해 주도록 합니다. 이 부분은 토큰을 받고 메시지를 받는 부분 입니다.

extension AppDelegate : MessagingDelegate {
  // [START refresh_token]
  func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String) {
    print("Firebase registration token: \(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.
  }
  // [END refresh_token]
  // [START ios_10_data_message]
  // Receive data messages on iOS 10+ directly from FCM (bypassing APNs) when the app is in the foreground.
  // To enable direct data messages, you can set Messaging.messaging().shouldEstablishDirectChannel to true.
  func messaging(_ messaging: Messaging, didReceive remoteMessage: MessagingRemoteMessage) {
    print("Received data message: \(remoteMessage.appData)")
  }
  // [END ios_10_data_message]
}

 

9. 메시지 받는 부분 추가.

여기서 부터는 iOS 앱에서 메시지 수신 이라는 문서 ( 링크 ) 를 참고 합니다. 

소스는 AppDelegate.swift에 메소드 2개를 추가하는 것 뿐 입니다.

func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any]) {
  // If you are receiving a notification message while your app is in the background,
  // this callback will not be fired till the user taps on the notification launching the application.
  // TODO: Handle data of notification

  // With swizzling disabled you must let Messaging know about the message, for Analytics
  // Messaging.messaging().appDidReceiveMessage(userInfo)

  // Print message ID.
  if let messageID = userInfo[gcmMessageIDKey] {
    print("Message ID: \(messageID)")
  }

  // Print full message.
  print(userInfo)
}

func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any],
                 fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
  // If you are receiving a notification message while your app is in the background,
  // this callback will not be fired till the user taps on the notification launching the application.
  // TODO: Handle data of notification

  // With swizzling disabled you must let Messaging know about the message, for Analytics
  // Messaging.messaging().appDidReceiveMessage(userInfo)

  // Print message ID.
  if let messageID = userInfo[gcmMessageIDKey] {
    print("Message ID: \(messageID)")
  }

  // Print full message.
  print(userInfo)

  completionHandler(UIBackgroundFetchResult.newData)
}

 

10. 메시지 보내기.

앱이 꺼져 있을 때는 아이폰의 헤드업 알림으로 표시가 되고, 켜저 있을 때는 내부 메시지 받는 부분에서 처리가됩니다.

파이어 베이스 콘솔에서, Cloud Messaging 버튼을 눌러, 클라우드 메시지 페이지를 열어 주도록 합니다.

그리고, 뜬 알림작성 페이지에, 적당한 문구를 입력하고 다음을 눌러 줍니다.

2번째 페이지가 뜨면, 우리가 만든 앱을 선택해 주고, 검토 버튼을 눌러 줍니다.

검토 화면이 나오면, 게시 버튼을 눌러 메시지를 보냅니다.

 

메시지가 잘 도착했나요? 저는 잘 도착했습니다. 아이폰은 안드로이드와 달리, 푸쉬를 받지 않도록 해 두면, 앱이 켜진 상태에서도 푸쉬 메시지를 받지 못합니다.

'iOS' 카테고리의 다른 글

iOS in-app purchase  (7) 2019.04.14
Push Notification (iOS, client)  (0) 2019.04.13
애플 앱을 기기에서, 실행하기 위한 방법  (0) 2019.04.12
웹 뷰 추가 및 웹통신 (UIWebView 이용)  (1) 2019.04.05
Posted by 창업닉군
,