单击应用程序图标时,推送通知应用内徽章图标不会更新

时间:2015-08-03 04:17:33

标签: ios swift parse-platform push-notification badge

我在使应用程序徽章图标标签正确更新时遇到了一些麻烦。我想要这样做:

只要收到推送通知,就会出现此红色图标。我正确地在iPhone上的应用程序图标上获得推送通知徽章;但是,如果我按下推送通知的横幅,或者如果我已经在应用程序中,则应用程序中的此红色图标才会出现。

我的问题是,如果我按下实际的应用程序图标,它就不会出现。我希望应用程序中的标签能够更新,即使应用程序处于背景中,就像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:

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 个答案:

答案 0 :(得分: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
}

最后,但绝对不是最不重要的,每当您收到远程通知时,您都会将其传递到 AppDelegate 中的func handleRemoteNotifications(application: UIApplication, userInfo: NSDictionary)。这又会将NSNotification发布到正在侦听它的对象。但是,可能有也可能没有ViewController,因为它可能在应用程序处于后台时被释放。因此,当您收到远程通知时,这些代码行永远不会被调用:

NSUserDefaults.standardUserDefaults().setInteger(followLabelNumber!, forKey: "followNumberKey")
NSUserDefaults.standardUserDefaults().synchronize()

尝试将上面的行移到 AppDelegate func handleRemoteNotifications(application: UIApplication, userInfo: NSDictionary)方法。