Swift:当应用程序在后台运行时,无法使用 pushNotification 的信息刷新 rootViewController
Posted
技术标签:
【中文标题】Swift:当应用程序在后台运行时,无法使用 pushNotification 的信息刷新 rootViewController【英文标题】:Swift: Unable to refresh rootViewController with pushNotification's info when the application is running in the background 【发布时间】:2016-07-11 22:13:52 【问题描述】:我正在实施一个新闻应用程序。一旦我收到带有突发新闻 id 和消息的通知,我应该打开应用程序并使用推送通知中收到的 id 刷新 rootViewController。
当应用程序不在后台运行时一切正常,而当应用程序在后台运行时出现问题。
在 AppDelegate.swift 中,我将 didReceiveRemoteNotifications 设置如下
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject], fetchCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void)
strNotificationId = (userInfo["id"] as? String)!
在我的 applicationWillEnterForeground 中,我调用了 rootViewController 方法 activeController.request(),该方法使用收到的 id 重新加载页面,如下所示
func applicationWillEnterForeground(application: UIApplication)
print("Push notifications are not supported in the ios Simulator.")
if let navigationController = window?.rootViewController as?UINavigationController
navigationController.popToRootViewControllerAnimated(false)
let navigationController = window?.rootViewController as? UINavigationController
let activeController = navigationController!.visibleViewController as! FeedTableViewController
activeController.request("http://example.net/rsssite.xml")
我的 rootViewController 实现了 request("http://example.net/rsssite.xml") 方法。请求方法读取通知id如下所示
delegate.notificationId = [NSObject: AnyObject]()
notificationId = delegate.strNotificationId as String
我的问题是,每当我单击在 IOS 通知列表中收到的通知时,并且当应用程序恰好在后端运行时,在 rootViewController 中实现的请求(“http://example.net/rsssite.xml”)都不是在我的 rootViewController viewDidLoad 和 applicationWillEnterForeground 中触发
以下是我的 rootViewController 中 request(url) 方法的完整代码,可能对您的反馈无用
//Method to request and parser the rss feeds
func request(urlLink: String)
forceError = false
let alert = UIAlertController(title: nil, message: Util.getMessage("loading"), preferredStyle: .Alert)
alert.view.tintColor = UIColor.blackColor()
let loadingIndicator: UIActivityIndicatorView = UIActivityIndicatorView(frame: CGRectMake(10, 5, 50, 50)) as UIActivityIndicatorView
loadingIndicator.hidesWhenStopped = true
loadingIndicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyle.Gray
loadingIndicator.startAnimating();
alert.view.addSubview(loadingIndicator)
self.view.addSubview(alert.view)
self.view.bringSubviewToFront(loadingIndicator)
let viewsDictionary = ["alert":alert.view]
let loadingMetrics = ["xDimension":(self.view.bounds.size.width - alert.view.frame.width ) / 2, "yDimension": (self.view.bounds.size.height - alert.view.frame.height ) / 2]
let horizontalLoadingConstraint = NSLayoutConstraint.constraintsWithVisualFormat("H:|-50-[alert]", options: NSLayoutFormatOptions.AlignAllCenterX, metrics:loadingMetrics, views: viewsDictionary)
let verticalLoadingConstraint = NSLayoutConstraint.constraintsWithVisualFormat("V:|-100-[alert]", options: NSLayoutFormatOptions.AlignAllCenterX, metrics: loadingMetrics, views: viewsDictionary)
self.view.addConstraints(horizontalLoadingConstraint)
self.view.addConstraints(verticalLoadingConstraint)
presentViewController(alert, animated: true, completion: nil)
let delegate = UIApplication.sharedApplication().delegate as! AppDelegate
let notificationsData = delegate.notificationId
for aButton in notificationsData
let key = aButton.0
let value = aButton.1
if(key == "id")
notificationId = value as! String
delegate.notificationId = [NSObject: AnyObject]()
notificationId = delegate.strNotificationId as String
//notificationId = "17579"
if (notificationId != "" && self.directLoad==false)
//var notificationURLLink = defaults.stringForKey("notificationId")
let diceRoll = Int(arc4random_uniform(9999) + 1) as NSNumber
let notificationURLLink = "http://example.net/"+notificationId+"-rss.xml?_=" + diceRoll.stringValue
let queue = NSOperationQueue()
queue.addOperationWithBlock()
let url = NSURL(string: notificationURLLink)
let feedParser = MWFeedParser(feedURL: url)
feedParser.delegate = self
feedParser.parse()
NSOperationQueue.mainQueue().addOperationWithBlock()
let item = self.feedItems[0] as MWFeedItem
self.slectedItems = item
self.sideBar.showSidebar(false)
self.performSegueWithIdentifier("DetailsViewControllerSegue", sender: self)
self.dismissViewControllerAnimated(false, completion: nil)
self.notificationId = ""
self.directLoad = true
else
let queue = NSOperationQueue()
queue.addOperationWithBlock()
let url = NSURL(string: urlLink)
let feedParser = MWFeedParser(feedURL: url)
feedParser.delegate = self
feedParser.parse()
NSOperationQueue.mainQueue().addOperationWithBlock()
self.tableView.reloadData()
self.dismissViewControllerAnimated(false, completion: nil)
delegate.strNotificationId = ""
谢谢
【问题讨论】:
【参考方案1】:尝试将applicationWillEnterForeground
中的代码移动到didReceiveRemoteNotification
。该过程应在您收到通知后立即完成。
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject], fetchCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void)
strNotificationId = (userInfo["id"] as? String)!
print("Push notifications are not supported in the iOS Simulator.")
if let navigationController = window?.rootViewController as?UINavigationController
navigationController.popToRootViewControllerAnimated(false)
let navigationController = window?.rootViewController as? UINavigationController
let activeController = navigationController!.visibleViewController as! FeedTableViewController
activeController.request("http://example.net/rsssite.xml")
另外请检查当您在后台打开通知时首先执行哪个功能,applicationWillEnterForeground
或didReceiveRemoteNotification
?
【讨论】:
以上是关于Swift:当应用程序在后台运行时,无法使用 pushNotification 的信息刷新 rootViewController的主要内容,如果未能解决你的问题,请参考以下文章
即使应用程序在后台运行,如何使用 swift 在 ios 中获取位置更新