Значок push-уведомления в приложении не обновляется при нажатии на значок приложения
У меня возникли некоторые проблемы с корректным обновлением ярлыка значка в приложении. Я хочу что-то, что делает это:
Этот красный значок появляется каждый раз, когда получено push-уведомление. Я правильно получаю значок push-уведомления на значке приложения на iPhone; однако этот красный значок внутри приложения появляется только в том случае, если я нажимаю на баннер для push-уведомления, ИЛИ, если я уже внутри приложения.
Моя проблема в том, что он не появляется, если я нажимаю на иконку самого приложения. Мне бы хотелось, чтобы ярлык в приложении обновлялся, даже когда приложение находится в фоновом режиме, вроде того, как приложение facebook имеет значки поверх значка глобуса уведомлений.
Я покажу соответствующие методы в AppDelegate (без учета токенов и т. Д.):
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
let userInfo: AnyObject? = launchOptions?[UIApplicationLaunchOptionsRemoteNotificationKey]
if userInfo != nil {
handleRemoteNotifications(application, userInfo: userInfo! as! NSDictionary)
return true
}
if application.applicationState != UIApplicationState.Background {
let oldPushHandlerOnly = !self.respondsToSelector(Selector("application:didReceiveRemoteNotification:fetchCompletionHandler:"))
let noPushPayload: AnyObject? = launchOptions?[UIApplicationLaunchOptionsRemoteNotificationKey]
if oldPushHandlerOnly || noPushPayload != nil {
PFAnalytics.trackAppOpenedWithLaunchOptionsInBackground(launchOptions, block: nil)
}
}
return true
}
func handleRemoteNotifications(application: UIApplication, userInfo: NSDictionary) {
if let type: String = userInfo["type"] as? String {
switch (type) {
case "follow":
NSNotificationCenter.defaultCenter().postNotificationName("commentNotification", object: self)
case "comment":
NSNotificationCenter.defaultCenter().postNotificationName("commentNotification", object: self)
default:
return
}
}
}
func applicationDidBecomeActive(application: UIApplication) {
if (application.applicationIconBadgeNumber != 0) {
application.applicationIconBadgeNumber = 0
}
let installation = PFInstallation.currentInstallation()
if installation.badge != 0 {
installation.badge = 0
installation.saveEventually()
}
}
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject], fetchCompletionHandler handler: (UIBackgroundFetchResult) -> Void) {
if let badgeNumber: Int = userInfo["badge"] as? Int {
application.applicationIconBadgeNumber = badgeNumber
}
handleRemoteNotifications(application, userInfo: userInfo)
if application.applicationState == .Inactive {
PFAnalytics.trackAppOpenedWithRemoteNotificationPayloadInBackground(userInfo, block: nil)
}
handler(.NewData)
}
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {
if application.applicationState == .Inactive {
// The application was just brought from the background to the foreground,
// so we consider the app as having been "opened by a push notification."
PFAnalytics.trackAppOpenedWithRemoteNotificationPayloadInBackground(userInfo, block: nil)
handleRemoteNotifications(application, userInfo: userInfo)
}
}
В ViewController я вызываю методы в viewDidAppear и заставляю его обновлять метку и увеличивать число на 1 при каждом получении push-уведомления:
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
followLabelNumber = NSUserDefaults.standardUserDefaults().integerForKey("followNumberKey")
commentLabelNumber = NSUserDefaults.standardUserDefaults().integerForKey("commentNumberKey")
NSNotificationCenter.defaultCenter().removeObserver(self, name: "followNotification", object: nil)
NSNotificationCenter.defaultCenter().addObserver(self, selector:"followNotificationReceived:", name:"followNotification", object: nil)
NSNotificationCenter.defaultCenter().removeObserver(self, name: "commentNotification", object: nil)
NSNotificationCenter.defaultCenter().addObserver(self, selector:"commentNotificationReceived:", name:"commentNotification", object: nil)
self.navigationController?.navigationBarHidden = true
}
func makeIncrementer(forIncrement amount: Int) -> () -> Int {
var runningTotal = 0
func incrementer() -> Int {
runningTotal += amount
return runningTotal
}
return incrementer
}
func followNotificationReceived(notification: NSNotification) {
if let number = followLabelNumber {
let aNumber = makeIncrementer(forIncrement: 1)
followLabelNumber = number + aNumber()
NSUserDefaults.standardUserDefaults().setInteger(followLabelNumber!, forKey: "followNumberKey")
NSUserDefaults.standardUserDefaults().synchronize()
profileNotificationLabel.hidden = false
profileNotificationLabel.text = String(followLabelNumber!)
hasReceivedFollowNotification = true
}
}
func commentNotificationReceived(notification: NSNotification) {
if let number = commentLabelNumber {
let aNumber = makeIncrementer(forIncrement: 1)
commentLabelNumber = number + aNumber()
NSUserDefaults.standardUserDefaults().setInteger(commentLabelNumber!, forKey: "commentNumberKey")
NSUserDefaults.standardUserDefaults().synchronize()
commentsNotificationLabel.hidden = false
commentsNotificationLabel.text = String(commentLabelNumber!)
hasReceivedCommentNotification = true
}
}
deinit {
NSNotificationCenter.defaultCenter().removeObserver(self)
}
Я был бы очень признателен за любую помощь, так как я застрял на этом в течение нескольких дней.
РЕДАКТИРОВАТЬ: изменил название
1 ответ
Во-первых, вам не нужно обращаться с application.applicationIconBadgeNumber
себя, так как вы используете Parse:
//You don't need these...
if (application.applicationIconBadgeNumber != 0) {
application.applicationIconBadgeNumber = 0
}
//Because these lines will set the application's icon badge to zero
let installation = PFInstallation.currentInstallation()
if installation.badge != 0 {
installation.badge = 0
installation.saveEventually()
}
Вам это тоже не нужно:
//Because Parse handles that for you
if let badgeNumber: Int = userInfo["badge"] as? Int {
application.applicationIconBadgeNumber = badgeNumber
}
Кроме того, проблема заключается в том, что вы не обновляете значок кнопки при загрузке View Controller. Вы обновляете их только тогда, когда вы получаете новое уведомление И Контроллер Представления виден. Короче, попробуйте это на вашем View Controller:
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
followLabelNumber = NSUserDefaults.standardUserDefaults().integerForKey("followNumberKey")
commentLabelNumber = NSUserDefaults.standardUserDefaults().integerForKey("commentNumberKey")
//BEGIN SUGGESTED CODE
profileNotificationLabel.hidden = followLabelNumber > 0
profileNotificationLabel.text = String(followLabelNumber!)
commentsNotificationLabel.hidden = commentLabelNumber > 0
commentsNotificationLabel.text = String(commentLabelNumber!)
//END SUGGESTED CODE
NSNotificationCenter.defaultCenter().removeObserver(self, name: "followNotification", object: nil)
NSNotificationCenter.defaultCenter().addObserver(self, selector:"followNotificationReceived:", name:"followNotification", object: nil)
NSNotificationCenter.defaultCenter().removeObserver(self, name: "commentNotification", object: nil)
NSNotificationCenter.defaultCenter().addObserver(self, selector:"commentNotificationReceived:", name:"commentNotification", object: nil)
self.navigationController?.navigationBarHidden = true
}
И последнее, но не менее важное: когда вы получаете удаленное уведомление, вы передаете его func handleRemoteNotifications(application: UIApplication, userInfo: NSDictionary)
внутри вашего AppDelegate. Это в свою очередь посты NSNotification
к объектам, которые его слушают. Однако может быть или не быть ViewController, потому что он мог быть освобожден, когда приложение находилось в фоновом режиме. Таким образом, эти строки кода никогда не вызываются при получении удаленного уведомления:
NSUserDefaults.standardUserDefaults().setInteger(followLabelNumber!, forKey: "followNumberKey")
NSUserDefaults.standardUserDefaults().synchronize()
Попробуйте переместить строки выше на ваш AppDelegatefunc handleRemoteNotifications(application: UIApplication, userInfo: NSDictionary)
метод.