# Receive Push Messages

The iOS SDK can receive push messages through FCM (which uses APNs). To set up a Firebase Project to user FCM, refer to the [FCM iOS documentation](https://firebase.google.com/docs/cloud-messaging/ios/client) and follow it completely. Make sure to also [configure APNs with FCM](https://firebase.google.com/docs/cloud-messaging/ios/certs).

Once you have done that, add your `GoogleService-Info.plist` to the root of your xcode project.

To register your FCM token with Mitter, do the following:

```
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
    print("APNs token retrieved: \(deviceToken.base64EncodedString())")

    InstanceID.instanceID().instanceID { (result, error) in
        if let error = error {
            print("Error fetching remote instange ID: \(error)")
        } else if let result = result {
            print("Remote instance ID token: \(result.token)")

            self.mitter.registerFcmToken(token: result.token) {
                result in
                switch result {
                case .success(let deliveryEndpoint):
                    print("Endpoint is: \(deliveryEndpoint.serializedEndpoint)")
                case .error:
                    print("Unable to register endpoint!")
                }
            }
        }
    }

    // With swizzling disabled you must set the APNs token here.
    // Messaging.messaging().apnsToken = deviceToken
}
```

To receive Messages when the app is in the background and then add it into the Channel view, do the following:

```
@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

        let messageString = userInfo["data"] as! String
        let messagingPipelinePayload = mitter.parseFcmMessage(data: messageString)

        processFcmMessage(pipelinePayload: messagingPipelinePayload)

        // Change this to your preferred presentation option
        completionHandler([])
    }
}
```

To receive messages directly from FCM (and not via APNs push), do the following:

```
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)")
        let messagingPipelinePayload = mitter.parseFcmMessage(data: remoteMessage.appData["data"] as! String)
        processFcmMessage(pipelinePayload: messagingPipelinePayload)
    }
    // [END ios_10_data_message]
}
```

Here is the function (used in the above snippets) that will add the parsed FCM message into the Channel View. Add it to your `AppDelegate`. Refer to the upcoming sections on the structure of the storyboard and `ChannelWindowViewController`:

```
func processFcmMessage(pipelinePayload: MessagingPipelinePayload?) {
    if mitter.isMitterMessage(pipelinePayload) {
        let payload = mitter.processPushMessage(pipelinePayload!)

        switch payload {
            // Handle the new message payload: Add it to the Channel Window View Controller
            case .NewMessagePayload(let message, let channelId):
                if let navController = window?.rootViewController as? UINavigationController {
                    // Get the second controller, which is the ChannelWindowViewController according to the storyboard
                    if let channelWindowViewController = navController.viewControllers[1] as? ChannelWindowViewController {
                        channelWindowViewController.newMessage(channelId: channelId.domainId, message: message)
                    }
                }
            // Ignore all other payloads
            default:
                print("Nothing to print!")
        }
    }
}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.mitter.io/getting-started/build-your-first-ios-app/receive-push-messages.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
