首页 文章

Firebase iOS 11按下按钮后询问用户通知

提问于
浏览
2

我正在使用Firebase在iOS 11上启用推送通知 . 我只是在按下按钮后才尝试询问用户的通知权限 .

目前,应用程序会在加载时立即请求用户权限 . 按下按钮后,我想在 EnableNotificationViewController.swift 类中询问此权限 .

AppDelegate.swift

import UIKit
import Firebase
import FBSDKCoreKit
import UserNotifications
import FirebaseInstanceID
import FirebaseMessaging

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate, MessagingDelegate {

    var window: UIWindow?

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
        // Override point for customization after application launch.

        FirebaseApp.configure()

        // [START set_messaging_delegate]
        Messaging.messaging().delegate = self


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

        FBSDKApplicationDelegate.sharedInstance().application(application, didFinishLaunchingWithOptions: launchOptions)
        return true
    }

    func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool {
        return FBSDKApplicationDelegate.sharedInstance().application(application, open: url, sourceApplication: sourceApplication, annotation: annotation)
    }

    func applicationWillResignActive(_ application: UIApplication) {
        // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
        // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
    }

    func applicationDidEnterBackground(_ application: UIApplication) {
        // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
        // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
    }

    func applicationWillEnterForeground(_ application: UIApplication) {
        // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
    }

    func applicationDidBecomeActive(_ application: UIApplication) {
        // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
        FBSDKAppEvents.activateApp()
    }

    func applicationWillTerminate(_ application: UIApplication) {
        // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
    }

    // MARK: - Notifications

    // The callback to handle data message received via FCM for devices running iOS 10 or above.
    func application(received remoteMessage: MessagingRemoteMessage) {
        print(remoteMessage.appData)
    }


}

EnableLocationViewController.swift

import UIKit
import Spring
import Firebase

class EnableNotificationsViewController: UIViewController {

    // MARK: - Outlets
    @IBOutlet weak var textLabel: DesignableLabel!

    // MARK: - View Did Load
    override func viewDidLoad() {
        super.viewDidLoad()

    }

    // MARK: - Actions
    @IBAction func notificationButton(_ sender: UIButton) {

    }


}

1 回答

  • 3

    那么你需要将远程通知权限请求移动到AppDelegate中的方法中,然后从名为 EnableNotificationsViewController 的ViewController中调用此方法 .

    让我们从 AppDelegate 开始并添加 registerAPNSServicesForApplication 方法:

    ///- register with APNS
    func registerAPNSServicesForApplication(_ application: UIApplication,withBlock block: @escaping (_ granted:Bool) -> (Void)) {
    
        // [START register_for_notifications]
        if #available(iOS 10.0, *) {
            let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound]
            UNUserNotificationCenter.current().requestAuthorization(
                options: authOptions,
                completionHandler: {granted, error in
    
                    if granted == true{
    
                        DispatchQueue.main.async {
                            application.registerForRemoteNotifications()
                        }
    
                        // For iOS 10 display notification (sent via APNS)
                        UNUserNotificationCenter.current().delegate = self
    
                    }
    
                    block(granted)
            })
    
        } else {
    
            let settings: UIUserNotificationSettings =
                UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil)
            application.registerUserNotificationSettings(settings)
            application.registerForRemoteNotifications()
    
        }
    
    }
    

    然后从你的 EnableNotificationsViewController 调用AppDelegate中的方法来请求权限,只是你知道iOS 10及以上你将获得许可的完成块,如果它被授予和我没有,所以它将在完成块中返回进入你的视图控制器,但不适用于iOS 9及更低版本,你需要一个特殊的处理:

    // MARK: - Actions
    @IBAction func notificationButton(_ sender: UIButton) {
    
        let myApplication = UIApplication.shared.delegate as! AppDelegate
        myApplication.registerAPNSServicesForApplication(UIApplication.shared) { (granted) -> (Void) in
    
            if #available(iOS 10.0, *) {
    
                if granted {
    
                }else {
    
                }
    
            }else {
    
                // will not be returned because iOS 9 has no completion block for granting the permission it will require special way.
    
            }
    
        }
    
    }
    

    说实话,我没有iOS 9的设备来模拟完成块,但我认为iOS 9及以下的用户仅为10%,根据Apple Analytics for November 2017

    应该这样做:)

相关问题