MNM
MNM

Reputation: 2743

IOS app won't display push notification when in background. Swift

Ok so my push notification work like a charm when the app is running in the foreground. But when ever I enter into the background, the app never receives the push notification. Its like the notification falls on deaf ears. So this is what happening. When the app is first started, I can received notification. When I close and reopen the app I can receive notification. But when the app is closed in the background I cannot receive notification. I print off when the app goes into the background and when the app becomes active so I know that its not closing I think. Because its printing that its going into the background, so it should be running. So this is what I have for the app deligate class:

 func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {

 //OTHER THINGS
   //Open the Push note page
    if launchOptions != nil
    {
        print(launchOptions)
        let storyboard = UIStoryboard(name: "Main", bundle: nil)
        let vc = storyboard.instantiateViewControllerWithIdentifier(myPage)
        self.window?.rootViewController = vc
    }

    //handel push note if app is closed
    //Sends it to the regular handler for push notifcaiton
    //didrecivepushnotificaiton
    if let remoteNotification = launchOptions?[UIApplicationLaunchOptionsRemoteNotificationKey] as? NSDictionary
    {
        print("Got A Push Note when I was closed")
        self.application(application, didReceiveRemoteNotification: remoteNotification as [NSObject : AnyObject])
    }

 }

  func application( application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken
    deviceToken: NSData ) {
    print("DEVICE TOKEN = \(deviceToken)")

    //convert the device token into a string
    let tokenChars = UnsafePointer<CChar>(deviceToken.bytes)
    var token = ""

    for i in 0..<deviceToken.length {
        token += String(format: "%02.2hhx", arguments: [tokenChars[i]])
    }
    print("token: " + token)
    //store the user device token for apns push notification
    loginInformation.setObject(token, forKey: "token")
    self.loginInformation.synchronize()

}

// [START ack_message_reception]
func application( application: UIApplication,
                  didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {

    print("Recived Push Notificaion")

    var myMess :String = ""
    var url : String = ""
    var myTitle : String = ""

    if var alertDict = userInfo["aps"] as? Dictionary<String, String> {

        print("Alert Dict")
        print(alertDict)

        url = alertDict["url"]!
        myMess = alertDict["alert"]!
        myTitle = alertDict["mytitle"]!
        //store the url for the push control view
        loginInformation.setObject(url, forKey: "URL")
        loginInformation.setObject(myMess, forKey: "Message")
        loginInformation.setObject(myTitle, forKey: "Title")
        self.loginInformation.synchronize()


    }else{print("No go")}
    application.applicationIconBadgeNumber = 0
    //post notification.
    NSNotificationCenter.defaultCenter().postNotificationName("PushReceived", object: nil, userInfo: userInfo)


    if myTitle == ""
    {
        myTitle = “New Title“
    }
    if myMess == ""
    {
        myMess = “All Hail Gus“
    }

    let alert = UIAlertController(title: myTitle, message: myMess, preferredStyle: UIAlertControllerStyle.Alert)
    //Close Button
     alert.addAction(UIAlertAction(title: "次回", style: UIAlertActionStyle.Default, handler: nil))
     self.window?.rootViewController?.presentViewController(alert, animated: true, completion: nil)


}

func registrationHandler(registrationToken: String!, error: NSError!) {

}

// [START receive_apns_token_error]
func application( application: UIApplication, didFailToRegisterForRemoteNotificationsWithError
    error: NSError ) {
    print(error)
}

I think I have all the right setting on this too. But I am not too sure now. The push notifications did work but I made a lot of changes and haven't tested them in a while.

enter image description here enter image description here enter image description here

And this is an example of the payload

{"aps":{"alert":"Gus Message.","badge":"1", "url":"https://www.gus.com","mytitle":"Gus Title"}}

Upvotes: 1

Views: 5850

Answers (1)

Chen Wei
Chen Wei

Reputation: 521

To fully implement APNS servie, u have to handle three cases:

  1. inactive
  2. foreground
  3. background

the inactive mode should be handled in didFinishLaunchingWithOptions method

//receive apns when app in inactive mode, remaining message hint display task could be sum up by the code in applicationwillenterforeground
    if let options = launchOptions {
        if options[UIApplicationLaunchOptionsRemoteNotificationKey] != nil {
            let userInfo: NSDictionary = options[UIApplicationLaunchOptionsRemoteNotificationKey] as! NSDictionary
            let apsInfo: NSDictionary = userInfo["aps"] as! NSDictionary
            //parse notification body message ...

                    NSNotificationCenter.defaultCenter().postNotificationName(APP_NOTIF_RECEIVE_REMOTE_NOTIF, object: userInfo)
                    APService.handleRemoteNotification(userInfo as! [NSObject : AnyObject])

                    //Update badge number

                    let badgeIndex = apsInfo["badge"] as! Int
                    UIApplication.sharedApplication().applicationIconBadgeNumber = badgeIndex
                }
            }
        } else if options[UIApplicationLaunchOptionsURLKey] != nil {
            if let url = launchOptions?[UIApplicationLaunchOptionsURLKey] as? NSURL {
                print(url)
            }
        }
    }

the remaining two cases should be handle in didReceiveRemoteNotification method

//receive apns when app in background mode
    let apsInfo: NSDictionary = userInfo["aps"] as! NSDictionary
    if UIApplication.sharedApplication().applicationState != UIApplicationState.Active{

        //TODO: temporary method, need further update
        //judge notification type
        if let _ = userInfo["inviterName"] as? String {
            //notification for group invite
        }else{
            //Update badge number
            if let badgeInt = apsInfo["badge"] as? Int {
                UIApplication.sharedApplication().applicationIconBadgeNumber = badgeInt > 0 ? badgeInt: 1
            }else{
                UIApplication.sharedApplication().applicationIconBadgeNumber = 1
            }
            //turn on trigger to enable message hint btn on recorder vc when it appear
            NSUserDefaults.standardUserDefaults().setBool(true, forKey: REMOTE_NOTIF_REMAINING)
        }
    }
   //receive apns when app in forground mode
    else{
        //TODO: temporary method, need further update
        //judge notification type
        if let _ = userInfo["inviterName"] as? String {
            //notification for group invite
            NSNotificationCenter.defaultCenter().postNotificationName(APP_NOTIF_RECEIVE_GROUP_NOTIF, object:nil)
        }else{
            //notificate recorder vc to display message hint directly
            NSNotificationCenter.defaultCenter().postNotificationName(APP_NOTIF_RECEIVE_REMOTE_NOTIF, object: userInfo)
        }
    }
    APService.handleRemoteNotification(userInfo)
    completionHandler(UIBackgroundFetchResult.NewData)

Upvotes: 2

Related Questions