在iOS 10 Swift 3中查看推送通知时遇到麻烦

时间:2017-01-11 05:30:24

标签: ios push-notification swift3 xcode8 remote-notifications

我的应用有两种初始状态。

  1. 登录
  2. 登录后,其中包含仪表板&其他的东西。
  3. 我的应用程序在从Appdelegate切换视图时工作正常

     func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
            let userDataExist = CommonUserFunction.isUserDataExist() as Bool
    
            if userDataExist == true {
    
                let homeViewController = self.window?.rootViewController?.storyboard?.instantiateViewController(withIdentifier: "HomeView") as? HomeViewController
                let navigationController = UINavigationController()
                navigationController.viewControllers = [homeViewController!]
    
                self.window!.rootViewController = navigationController
            }
            else{
    
                let loginController = self.window?.rootViewController?.storyboard?.instantiateViewController(withIdentifier: "LoginView") as? LoginController
                let navigationController = UINavigationController()
                navigationController.viewControllers = [loginController!]
    
                self.window!.rootViewController = navigationController
            }
    
            self.window?.makeKeyAndVisible()
    
            return true
     }
    

    我必须处理推送通知时遇到问题。我通过这些方法在iOS 10中收到推送通知

    @available(iOS 10.0, *)
    func userNotificationCenter(_ center: UNUserNotificationCenter,  willPresent notification: UNNotification, withCompletionHandler   completionHandler: @escaping (_ options:   UNNotificationPresentationOptions) -> Void) {
        print("Handle push from foreground")
        // custom code to handle push while app is in the foreground
    
        print(notification.request.content.userInfo)
    }
    
    @available(iOS 10.0, *)
    func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
    
       // custom code to handle push while app is in the foreground
        print(response.notification.request.content.userInfo)
    }
    

    当我从通知托盘中点击通知时,会触发这两种方法,而app则是前景或背景。点击通知后,我必须显示详细信息页面。我尝试设置详细信息页面,就像我之前在didFinishLaunchingWithOptions方法中所做的那样

    @available(iOS 10.0, *)
    func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
    
        let pushResponse = response.notification.request.content.userInfo as NSDictionary
    
        let rtype = pushResponse.object(forKey: "rtype") as? String
        let rid = pushResponse.object(forKey: "rid") as? String
    
        if rtype != nil {
    
            if rtype == "5" {
    
                if rid != nil {
                     let noticeDetailsViewController = self.storyboard?.instantiateViewController(withIdentifier: "NoticeDetailsView") as? NoticeDetailsController
                     noticeDetailsViewController!.id = rtype!
                     noticeDetailsViewController?.fromPush = true
                     let navigationController = UINavigationController()
                     navigationController.viewControllers = [noticeDetailsViewController!]
                     self.window!.rootViewController = navigationController
                }
            }
        }
    }
    

    每次我做那个应用程序崩溃。如何克服这一点。请帮忙。提前致谢。

1 个答案:

答案 0 :(得分:0)

最后使用Observer设计模式解决了这个问题。

当app处于背景&点击通知栏中的通知,然后从这里发布通知

@available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {

    let pushResponse = response.notification.request.content.userInfo as NSDictionary

    let rtype = pushResponse.object(forKey: "rtype") as? String
    let rid = pushResponse.object(forKey: "rid") as? String

    if rtype != nil {

        if rtype == "5" {

            if rid != nil {

                NotificationCenter.default.post(name: Notification.Name(rawValue: "getPush"), object: pushResponse)
            }
        }
    }
}

要在viewController

的代码下面接收此通知init
NotificationCenter.default.addObserver(self, selector: #selector(self.getPushResponse), name: NSNotification.Name(rawValue: "getPush"), object: nil)

从以下代码获取回复

func getPushResponse(_ notification: Notification){

    if let info = notification.object as? NSDictionary {
        let rid = info.object(forKey: "rid") as? String
        let noticeDetailsViewController = self.storyboard?.instantiateViewController(withIdentifier: "NoticeDetailsView") as? NoticeDetailsController
        noticeDetailsViewController?.id = rid!
        noticeDetailsViewController?.fromPush = true
        self.navigationController?.pushViewController(noticeDetailsViewController!, animated: true)
    }
}

不要忘记从viewController中删除Observer,就像那样

deinit {
    NotificationCenter.default.removeObserver(self)
}

如果app在后台没有实例,那么点击托盘中的通知然后如何显示没有实例的通知。这可以像AppDelegate中那样处理

let prefs: UserDefaults = UserDefaults.standard
    if let remoteNotification = launchOptions?[UIApplicationLaunchOptionsKey.remoteNotification] as? NSDictionary {
        prefs.set(remoteNotification as! [AnyHashable: Any], forKey: "startUpPush")
        prefs.synchronize()
    }

检查你的初始viewController是否存在这个键

let prefs:UserDefaults = UserDefaults.standard
    if prefs.value(forKey: "startUpPush") != nil {

        let pushResponse = prefs.object(forKey: "startUpPush") as! NSDictionary
        NotificationCenter.default.post(name: Notification.Name(rawValue: "getPush"), object: pushResponse)
    }

在显示像

这样的detailsController后,不要忘记删除此键
if fromPush == true {
        let prefs: UserDefaults = UserDefaults.standard
        if prefs.value(forKey: "startUpPush") != nil {
            prefs.removeObject(forKey: "startUpPush")
            prefs.synchronize()
        }
    }