/* * Copyright 2017 Google * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import UIKit import UserNotifications import FirebaseDev enum NotificationsControllerAllowedNotificationType: String { case none = "None" case silent = "Silent Updates" case alert = "Alerts" case badge = "Badges" case sound = "Sounds" } let APNSTokenReceivedNotification: Notification.Name = Notification.Name(rawValue: "APNSTokenReceivedNotification") let UserNotificationsChangedNotification: Notification.Name = Notification.Name(rawValue: "UserNotificationsChangedNotification") class NotificationsController: NSObject { static let shared: NotificationsController = { let instance = NotificationsController() return instance }() class func configure() { let sharedController = NotificationsController.shared // Always become the delegate of UNUserNotificationCenter, even before we've requested user // permissions if #available(iOS 10.0, *) { UNUserNotificationCenter.current().delegate = sharedController } } func registerForUserFacingNotificationsFor(_ application: UIApplication) { if #available(iOS 10.0, *) { UNUserNotificationCenter.current() .requestAuthorization(options: [.alert, .badge, .sound], completionHandler: { (granted, error) in NotificationCenter.default.post(name: UserNotificationsChangedNotification, object: nil) }) } else if #available(iOS 8.0, *) { let userNotificationSettings = UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: []) application.registerUserNotificationSettings(userNotificationSettings) } else { application.registerForRemoteNotifications(matching: [.alert, .badge, .sound]) } } func getAllowedNotificationTypes(_ completion: @escaping (_ allowedTypes: [NotificationsControllerAllowedNotificationType]) -> Void) { guard Messaging.messaging().apnsToken != nil else { completion([.none]) return } var types: [NotificationsControllerAllowedNotificationType] = [.silent] if #available(iOS 10.0, *) { UNUserNotificationCenter.current().getNotificationSettings(completionHandler: { (settings) in if settings.alertSetting == .enabled { types.append(.alert) } if settings.badgeSetting == .enabled { types.append(.badge) } if settings.soundSetting == .enabled { types.append(.sound) } DispatchQueue.main.async { completion(types) } }) } else if #available(iOS 8.0, *) { if let userNotificationSettings = UIApplication.shared.currentUserNotificationSettings { if userNotificationSettings.types.contains(.alert) { types.append(.alert) } if userNotificationSettings.types.contains(.badge) { types.append(.badge) } if userNotificationSettings.types.contains(.sound) { types.append(.sound) } } completion(types) } else { let enabledTypes = UIApplication.shared.enabledRemoteNotificationTypes() if enabledTypes.contains(.alert) { types.append(.alert) } if enabledTypes.contains(.badge) { types.append(.badge) } if enabledTypes.contains(.sound) { types.append(.sound) } completion(types) } } } // MARK: - UNUserNotificationCenterDelegate @available(iOS 10.0, *) extension NotificationsController: UNUserNotificationCenterDelegate { func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) { // Always show the incoming notification, even if the app is in foreground completionHandler([.alert, .badge, .sound]) } }