【问题标题】:responding to push notification when app is TERMINATED应用程序终止时响应推送通知
【发布时间】:2017-08-10 14:58:54
【问题描述】:

由于我是推送通知的新手,我查看了几个教程,其中概述了在应用程序终止时处理远程推送通知的最佳方法,而且我的应用程序似乎仍然存在问题。我在点击推送通知时调用了 didFinishLaunchingWithOptions,但由于某种原因,该函数被跳过并且不执行代码以打开正确的视图控制器。

这是 AppDelegate 中的代码

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

//UserNotification
let center = UNUserNotificationCenter.current()

center.requestAuthorization(options: [.alert, .sound, .badge]) { (granted, error) in
    // Enable or disable features based on authorization.
    if granted {
        UIApplication.shared.registerForRemoteNotifications()

        if GlobalService.sharedInstance().g_userDeviceToken == nil {
            //  GlobalService.sharedInstance().g_userDeviceToken = ""


        }
    } else {
        print("Don't Allow")

    }

    if let notification = launchOptions?[UIApplicationLaunchOptionsKey.remoteNotification] as? [String: AnyObject] {

        self.getUserChatRooms()
        let aps = notification["aps"] as! [String: AnyObject]

        let mainNC = self.window?.rootViewController as! UINavigationController
        let storyboard = UIStoryboard.init(name: "Main", bundle: nil)

        let mainVC = storyboard.instantiateViewController(withIdentifier: String(describing: MainViewController.self)) as! MainViewController
        GlobalService.sharedInstance().g_homeVC = mainVC
        mainVC.didReceiveChat(aps)
        mainNC.pushViewController(mainVC, animated: false)

    }
    ...

//SVProgressHUD
SVProgressHUD.setDefaultStyle(.dark)

//Check UserObj
GlobalService.sharedInstance().g_appDelegate = self
if let userObj = GlobalService.sharedInstance().loadUserObj() {
    GlobalService.sharedInstance().g_userMe = userObj
    startApplication(animated: false)
...
return true
}

那么这是 MainVC 中调用的函数:

  func didReceiveChat (_ notificationDictionary: [String: AnyObject]){
let allChats = GlobalService.sharedInstance().g_aryChatRooms

if let noti_id = notificationDictionary["noti_id"] as? String{
        let pushID = Int(noti_id)
    if pushID != nil {
        for chat in allChats {

            if chat.chat_room_id! == pushID! {
            chtRoom = chat

                 NotificationCenter.default.post(name: Notification.Name(rawValue: Constants.Notifications.GET_MSG), object: self)
            break
            }
        }
    }
}
 }

然后在我的 viewDidLoad 方法中添加观察者:

    NotificationCenter.default.addObserver(self,selector: #selector(MainViewController.addChatScn(_:_:)), name: NSNotification.Name(rawValue: Constants.Notifications.GET_MSG), object: nil)

最后我调用 addChatScn 的方法:

  @objc func addChatScn(_ chatObj: ChatRoomObj, _ msgName: String) {
    let popvc = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "ChatContainerViewController") as! ChatContainerViewController

    iconContainer.isHidden = true
    add_Msg_Btn.isHidden = true
    popvc.vcA = self
    popvc.m_selectedChatRoom = chatObj
    popvc.msgName = msgName
    self.addChildViewController(popvc)
    popvc.view.center = self.view.center
    popvc.view.bounds.size = CGSize(width: 337, height: 503)

    self.view.addSubview(popvc.view)

    popvc.didMove(toParentViewController: self)
}

【问题讨论】:

    标签: ios swift3 push-notification appdelegate


    【解决方案1】:

    在您的 GlobalService.sharedInstance 中,添加一个名为“readyToReceivePush”的布尔值。在 viewDidLoad 的 MainVC 中,将“GlobalService.sharedInstance.readyToReceivePush”设置为 true。如果应用程序进入后台,则设置为 false,如果返回前台,则设置为 true。

    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.
        GlobalService.sharedInstance.readyToReceivePush = false
    }
    
    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.
        GlobalService.sharedInstance.readyToReceivePush = true
    }
    

    设置完成后,如果用户在通知上滑动,将调用“didReceiveRemoteNotification”。在该方法中,如果 GlobalService.sharedInstance.readyToReceivePush == false,则将 userInfo 保存到 GlobalService.sharedInstance.savedPushInfo。

    func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
        if GlobalService.sharedInstance.readyToReceivePush == false {
            GlobalService.sharedInstance.savedPushInfo = userInfo
        } else {
            // Handle notification while the user is in the foreground
        }
    }
    

    完成后,在 MainVC 中检查 GlobalService.sharedInstance.savedPushInfo 是否 != nil。如果它是 != nil,请调用您的“didReceiveChat”函数或您执行的任何操作来处理通知的 userInfo 数据。

    【讨论】:

    • 我认为这适用于应用程序在后台运行,但我的具体用例是应用程序完全终止时
    猜你喜欢
    • 2016-03-25
    • 1970-01-01
    • 2021-06-06
    • 2016-05-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-03
    相关资源
    最近更新 更多