【问题标题】:Handle remote notification from within view controller处理来自视图控制器的远程通知
【发布时间】:2018-12-31 12:19:32
【问题描述】:

我正在尝试处理来自特定视图控制器的远程通知。我已经设置了我的应用程序,因此当我推送远程通知时,某个视图控制器会在 ImageView 中显示特定图像,但是如果不再次推送相同的控制器,我就无法更改图像。一旦呈现视图控制器,我正在尝试从另一个远程通知更改 ImageView 的图像。我实现这一点的想法是创建一种方法来从刚刚呈现的视图控制器的文件中处理远程通知,因此远程通知可以编辑 ImageView 的图像。这就是我在 AppDelegate 中呈现视图控制器的方式:

func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
    if let data = userInfo["showiMac"] as? [String: String], let iMacConfig = data["iMacConfig"] {
        let storyboard = UIStoryboard(name: "Main", bundle: nil)
        let rootTabBarController = self.window?.rootViewController as! UITabBarController
        let firstNavigationController = storyboard.instantiateViewController(withIdentifier: "initialVC1") as! UINavigationController
        rootTabBarController.viewControllers![0] = firstNavigationController

        //the viewController to present
        let viewController = storyboard.instantiateViewController(withIdentifier: "configureiMac") as! ConfigureiMacViewController

        // present VC
        firstNavigationController.pushViewController(viewController, animated: true, completion: {
            viewController.image = UIImage(named: "iMac" + iMacConfig)
        })

        completionHandler(.noData)


    }
}

这是在我的视图控制器中声明图像的方式:

var image: UIImage! 

override func viewDidLoad() {
     super.viewDidLoad()
     imageView.image = image 
}

【问题讨论】:

  • 请添加包括didReceiveRemoteNotification在内的周边代码...
  • 我刚刚编辑了帖子以包含我的整个 didReceiveRemoteNotification 方法。
  • 既然你设置了viewController.image,你能说明这个变量是如何在视图控制器中声明的吗?
  • 当然。再次更新了帖子。感谢您抽出宝贵时间帮助我。

标签: ios swift


【解决方案1】:

在您的应用委托中,执行以下操作:

  weak var configureiMacViewController: ConfigureiMacViewController?

创建帮助函数以保持您的代码简洁易读:

private func updateiMacImage(_ image: UIImage, in existingViewController: ConfigureiMacViewController) {
    existingViewController.image = image
}

private func showiMacImage(_ image: UIImage) {
    let storyboard = UIStoryboard(name: "Main", bundle: nil)
    let rootTabBarController = self.window?.rootViewController as! UITabBarController
    let firstNavigationController = storyboard.instantiateViewController(withIdentifier: "initialVC1") as! UINavigationController
    rootTabBarController.viewControllers![0] = firstNavigationController

    //the viewController to present
    let viewController = storyboard.instantiateViewController(withIdentifier: "configureiMac") as! ConfigureiMacViewController
    configureiMacViewController = viewController

    // present VC
    firstNavigationController.pushViewController(viewController, animated: true, completion: {
        viewController.image = UIImage(named: "iMac" + iMacConfig)
    })
}  

然后更新:

func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
    if let data = userInfo["showiMac"] as? [String: String], let iMacConfig = data["iMacConfig"] {
        let image = UIImage(named: "iMac" + iMacConfig)
        if let existingViewController = configureiMacViewController {
           updateiMacImage(image, in: existingViewController)
        } else {
           showiMacImage(image)
        }    
        completionHandler(.noData)
    }
}

AppDelegate 中的弱变量将存储对视图控制器的引用,但“弱”关键字将允许视图控制器在被解除时从内存中释放,在这种情况下,下次你的变量将为零尝试访问它。如果视图控制器仍然可见,那么它的值仍然会被定义,并且您将能够重新使用它来更新图像。

您很可能还必须将您的 ConfigureiMacViewController 代码更新为:

var image: UIImage! {
    didSet {
        imageView.image = image
    }
}

override func viewDidLoad() {
     super.viewDidLoad()
     imageView.image = image 
}

这确保如果视图控制器已经加载并显示,但您更新了图像变量,则图像视图会加载最新的图像。

祝你好运!

【讨论】:

  • 感谢您如此彻底地回复。这对我来说非常接近工作,根据您的回答,我可以感觉到自己接近解决方案。但是,当我尝试更改图像时,我不断收到错误消息“在 ConfigureiMacViewController 中展开可选值时意外发现 nil”。关于如何避免这种情况的任何想法?
  • 当你使用 !代替 ?定义或使用变量时。至于是哪一个,我不确定
  • 啊,你完全正确。以为我有我所有的变量?最后,但我错过了一个。非常感谢你,你是一个巨大的帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-12
相关资源
最近更新 更多