2015-08-03 1 views
1

J'ai un peu de mal à mettre correctement à jour une étiquette d'icône de badge intégrée à l'application. Je veux quelque chose qui fait cela:Icône de badge de notification push in-app ne pas mettre à jour lorsque vous cliquez sur l'icône de l'application

Cette icône rouge apparaît à chaque fois qu'une notification push est reçue. Je reçois le badge de notification push sur l'icône de l'application sur l'iPhone correctement; Toutefois, cette icône rouge à l'intérieur de l'application apparaît uniquement si j'appuie sur la bannière pour la notification push, OU si je suis déjà dans l'application.

Mon problème est qu'il n'apparaît pas si j'appuie sur l'icône de l'application. Je souhaite que l'étiquette de l'application soit mise à jour même lorsque l'application est en arrière-plan, un peu comme si l'application facebook avait des icônes au-dessus de l'icône du globe des notifications.

Je vais vous montrer les méthodes pertinentes dans le AppDelegate (en omettant les jetons, etc.):

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) 
    } 
} 

Dans le ViewController, j'appelle les méthodes viewDidAppear et d'en faire la mise à jour l'étiquette et augmenter le nombre de 1 à chaque fois qu'une notification push est reçue:

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) 
} 

J'apprécierais l'aide de personne que je suis coincé sur cette question depuis quelques jours maintenant.

EDIT: Titre modifié

Répondre

1

Tout d'abord, vous ne devriez pas avoir à gérer vous-même application.applicationIconBadgeNumber puisque vous utilisez 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() 
} 

Vous n'avez pas besoin cela aussi:

//Because Parse handles that for you 
if let badgeNumber: Int = userInfo["badge"] as? Int { 
    application.applicationIconBadgeNumber = badgeNumber 
} 

En outre, le problème semble être que vous ne mettez pas à jour le badge du bouton lorsque votre View Controller se charge. Vous ne les mettez à jour que lorsque vous recevez une nouvelle notification ET que View Controller est visible. Bref, essayez ceci sur votre contrôleur de vue:

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 
} 

dernier, mais certainement pas moins, chaque fois que vous recevez une notification à distance, vous passez à l'intérieur de votre func handleRemoteNotifications(application: UIApplication, userInfo: NSDictionary)AppDelegate. Ceci à son tour envoie un NSNotification aux objets qui l'écoutent. Cependant, il peut y avoir ou non un ViewController, car il a peut-être été désalloué alors que l'application était en arrière-plan. Ainsi, ces lignes de code ne sont jamais appelées lorsque vous recevez une notification à distance:

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

Essayez de déplacer les lignes ci-dessus à votre méthode de func handleRemoteNotifications(application: UIApplication, userInfo: NSDictionary)AppDelegate.

+0

Vous êtes bien, vous m'avez mis sur la bonne voie! J'ai eu un problème où je pouvais soit afficher l'installation.badge OU l'incrémenteur dans la vue mais je pense que je l'ai eu de sorte qu'il fait les deux juste au cas où l'utilisateur est toujours dans l'application. Je posterai le code plus tard pour tous ceux qui ont une question similaire. – jasonnoahchoi

+0

Je suis content que je puisse être utile. –