Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
import UIKit
import Flutter
import Firebase
import FirebaseMessaging
import MSAL
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
var deviceToken = ""
var fcmToken = ""
var isKilled = false
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
Messaging.messaging().delegate = self
FirebaseApp.configure()
registerForPushNotifications(application: application)
let controller : FlutterViewController = window?.rootViewController as! FlutterViewController
let handler = PlatformMethodHandler(controller: controller)
let loginChannel = FlutterMethodChannel(name: "global.raiser/msal/methods", binaryMessenger: controller.binaryMessenger)
loginChannel.setMethodCallHandler({
(call: FlutterMethodCall, result: @escaping FlutterResult) -> Void in
guard call.method == "login" else {
result(FlutterMethodNotImplemented)
return
}
handler.msLogin(result: result)
})
let notificationChannel = FlutterMethodChannel(name: "global.raiser/notifications/methods", binaryMessenger: controller.binaryMessenger)
notificationChannel.setMethodCallHandler({
(call: FlutterMethodCall, result: @escaping FlutterResult) -> Void in
guard call.method == "getPendingNotificationActionData" || call.method == "getFirebaseData" else {
result(FlutterMethodNotImplemented)
return
}
if call.method == "getPendingNotificationActionData" {
handler.getNotificationData(result: result)
}
else {
handler.getFirebaseData(result: result,deviceToken: self.deviceToken, fcmToken: self.fcmToken)
}
})
if let remoteNotification = launchOptions?[UIApplication.LaunchOptionsKey.remoteNotification] as? [AnyHashable : Any] {
handler.notificationData = remoteNotification
isKilled = true
}
return true
}
override func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
return MSALPublicClientApplication.handleMSALResponse(url, sourceApplication: options[.sourceApplication] as? String)
}
// Receive displayed notifications for iOS 10 devices.
override func userNotificationCenter(_ center: UNUserNotificationCenter,
willPresent notification: UNNotification,
withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
// Change this to your preferred presentation option
let userInfo = notification.request.content.userInfo
print(userInfo)
handleNotificationData(userInfo, method: "notificationReceived")
completionHandler([.badge,.sound,.alert])
}
override func userNotificationCenter(_ center: UNUserNotificationCenter,
didReceive response: UNNotificationResponse,
withCompletionHandler completionHandler: @escaping () -> Void) {
let userInfo = response.notification.request.content.userInfo
print(userInfo)
if !isKilled {
handleNotificationData(userInfo, method: "notificationPressed")
}
completionHandler()
}
override func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
print("Unable to register for remote notifications: \(error.localizedDescription)")
}
override func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
Messaging.messaging().apnsToken = deviceToken
let tokenParts = deviceToken.map { data in String(format: "%02.2hhx", data) }
self.deviceToken = tokenParts.joined()
print("Device Token: \(self.deviceToken)")
}
override 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)
completionHandler(UIBackgroundFetchResult.newData)
}
private func registerForPushNotifications(application:UIApplication){
// [END set_messaging_delegate]
// 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 #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()
Messaging.messaging().delegate = self
GeneratedPluginRegistrant.register(with: self)
}
func handleNotificationData(_ notificationData: [AnyHashable : Any], method: String) {
let controller : FlutterViewController = window?.rootViewController as! FlutterViewController
var data = notificationData["data"]
if data == nil {
data = ["title" : notificationData["title"], "body" : notificationData["body"], "isSilent" : notificationData["isSilent"], "type" : notificationData["type"], "id" : notificationData["id"], "badgeCount" : notificationData["badgeCount"]]
}
let notificationChannel = FlutterMethodChannel(name: "global.raiser/notifications/methods", binaryMessenger: controller.binaryMessenger)
notificationChannel.invokeMethod(method, arguments: data)
}
}
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)
self.fcmToken = fcmToken
// 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) {
handleNotificationData(remoteMessage.appData, method: "notificationPressed")
}
// [END ios_10_data_message]
func application(received remoteMessage: MessagingRemoteMessage) {
print("MessageReceived messaging")
handleNotificationData(remoteMessage.appData, method: "notificationPressed")
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment