I'm trying to implement GCM in my iOS app. Everything seems to work fine, the app is connecting to GCM and getting a registration ID back. If I send a notification to that regid using Postman it works and I get a success response back from Google. However, whatever I try, the notification isn't actually shown on the device.
The post messsage to the GCM servers I'm using is
{
"to" : "RegID",
"content_available" : true,
"notification" : {
"body" : "Test Body",
"title" : "Test Title"
}
}
which gives me the response:
{
"multicast_id": 6594175386712804014,
"success": 1,
"failure": 0,
"canonical_ids": 0,
"results": [
{
"message_id": "0:1443445858075083%c4cfa24dc4cfa24d"
}
]
}
This makes me believe there is something wrong with the code in my app. Below I've pasted all the relevant code. I've written the code 3 times without success, first following the tutorial and editing it to fit in my app properly, second time I copied the code from the tutorial and the third time I got the example app from the Github repo and copied everything relevant to GCM over.
AppDelegate:
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
var connectedToGCM = false
var gcmSenderID: String?
var registrationToken: String?
var registrationOptions = [String: AnyObject]()
let defaults = NSUserDefaults.standardUserDefaults()
let registrationKey = "onRegistrationCompleted"
let messageKey = "onMessageReceived"
let notification = "isNotificationEnabled"
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
// Google Cloud Messaging
var configureError:NSError?
GGLContext.sharedInstance().configureWithError(&configureError)
assert(configureError == nil, "Error configuring Google services: \(configureError)")
gcmSenderID = GGLContext.sharedInstance().configuration.gcmSenderID
var types: UIUserNotificationType = UIUserNotificationType.Badge |
UIUserNotificationType.Alert |
UIUserNotificationType.Sound
var settings: UIUserNotificationSettings =
UIUserNotificationSettings( forTypes: types, categories: nil )
application.registerUserNotificationSettings( settings )
application.registerForRemoteNotifications()
var gcmConfig = GCMConfig.defaultConfig()
GCMService.sharedInstance().startWithConfig(gcmConfig)
return true
}
func applicationDidBecomeActive(application: UIApplication) {
GCMService.sharedInstance().connectWithHandler({
(NSError error) -> Void in
if error != nil {
println("Could not connect to GCM: \(error.localizedDescription)")
} else {
self.connectedToGCM = true
println("Connected to GCM")
// ...
}
})
}
func application( application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken
deviceToken: NSData ) {
println(deviceToken)
// [END receice_apns_token]
// [START get_gcm_reg_token]
// Create a config and set a delegate that implements the GGLInstaceIDDelegate protocol.
var instanceIDConfig = GGLInstanceIDConfig.defaultConfig()
// Start the GGLInstanceID shared instance with that config and request a registration
// token to enable reception of notifications
GGLInstanceID.sharedInstance().startWithConfig(instanceIDConfig)
registrationOptions = [kGGLInstanceIDRegisterAPNSOption:deviceToken,
kGGLInstanceIDAPNSServerTypeSandboxOption:true]
GGLInstanceID.sharedInstance().tokenWithAuthorizedEntity(gcmSenderID,
scope: kGGLInstanceIDScopeGCM, options: registrationOptions, handler: registrationHandler)
// [END get_gcm_reg_token]
}
func registrationHandler(registrationToken: String!, error: NSError!) {
if (registrationToken != nil) {
self.registrationToken = registrationToken
println("Registration Token: \(registrationToken)")
let userInfo = ["registrationToken": registrationToken]
NSNotificationCenter.defaultCenter().postNotificationName(
self.registrationKey, object: nil, userInfo: userInfo)
} else {
println("Registration to GCM failed with error: \(error.localizedDescription)")
let userInfo = ["error": error.localizedDescription]
NSNotificationCenter.defaultCenter().postNotificationName(
self.registrationKey, object: nil, userInfo: userInfo)
}
}
func onTokenRefresh() {
// A rotation of the registration tokens is happening, so the app needs to request a new token.
println("The GCM registration token needs to be changed.")
GGLInstanceID.sharedInstance().tokenWithAuthorizedEntity(gcmSenderID,
scope: kGGLInstanceIDScopeGCM, options: registrationOptions, handler: registrationHandler)
}
func application( application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {
println("Notification received: \(userInfo)")
// This works only if the app started the GCM service
GCMService.sharedInstance().appDidReceiveMessage(userInfo);
// Handle the received message
// Invoke the completion handler passing the appropriate UIBackgroundFetchResult value
// [START_EXCLUDE]
NSNotificationCenter.defaultCenter().postNotificationName(messageKey, object: nil,
userInfo: userInfo)
}
If anyone asked a similar question before let me know, I wasn't able to find one that described my situation properly.
Thanks in advance!
You haven't implemented the appropriate notification callback. You need to implement
func application(_ application: UIApplication,
didReceiveRemoteNotification userInfo: [NSObject : AnyObject],
fetchCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void) {
// Do something with userInfo
// call fetchCompletionHandler with the appropriate UIBackgroundFetchResult
}
Silent Push Notifications(i.e. ones with content-available flag set) call the above UIApplicationDelegate method instead of application:didReceiveRemoteNotification:.
Also make sure you've added remote-notification value to the UIBackgroundModes in your Info.plist.
Related
Update: Ok so I redid all my certs and now I am getting this by testing the GCM at this site http://techzog.com/development/gcm-notification-test-tool-android/
URL: http://android.googleapis.com/gcm/send
Headers: Array ( [0] => Authorization: key=AIzaSyBPTQGXlyImFWPda1s2LVUKIN98uMS0Bac [1] => Content-Type: application/json ) 1
Fields: Array ( [registration_ids] => Array ( [0] => fBspb1tyYDg:APA91bE0-pzjJrJodW2JuNvnEZSkUaw0rBjf0gkwu2Yi9GaS8WcrhZII2LnDcclwd4K5W51osjxfBCM7E76Ck7EDG4YHEESAesXZBgrSrHDQNAjGPv1VgOi-zkFi1biZSQzeaEbS3xch ) [data] => Array ( [message] => Koimute [] => ) ) 1
Result:
Unauthorized
Error 401
So this means that it is being basically stopped from getting to the phone I think.
UPDATE: Ok so I have been working at it and have tried to change the cert around and fool with the settings. now my console is printing out that I am connected to the GCM. But, still I do not receive any notification from the server at all. Here is what my console is printing
0028-05-24 12:21:32.829: GCM | GCM library version 1.1.4
0028-05-24 12:21:32.841: GCM | Invalid key in checkin plist: GMSInstanceIDDeviceDataVersion
2016-05-24 12:21:32.856 MyApp[560:] <GMR/INFO> App measurement v.2003000 started
2016-05-24 12:21:32.857 MuApp[560:] <GMR/INFO> To enable debug logging set the following application argument: -GMRDebugEnabled
0028-05-24 12:21:32.920: GCM | Invalid key in checkin plist: GMSInstanceIDDeviceDataVersion
2016-05-24 12:21:33.053 MyApp[560:106171] INFO: GoogleAnalytics 3.14 -[GAIReachabilityChecker reachabilityFlagsChanged:] (GAIReachabilityChecker.m:159): Reachability flags update: 0X000002
Registration Token: My token i get from GCM
2016-05-24 12:21:33.067 MyApp[560:] <GMR/INFO> App measurement enabled
Connected to GCM
2016-05-24 12:21:33.937 MyApp[560:106213] INFO: GoogleAnalytics 3.14 -[GAIBatchingDispatcher hitsForDispatch] (GAIBatchingDispatcher.m:368): No pending hits.
The GCM | Invalid key in checkin plist: GMSInstanceIDDeviceDataVersion error from what I gathered means that it is working and is fine. They said that they will fix this in a later release
OLD:
So I have set up the GCM as well as a Google Analytics in my iOS project. The Analytics works perfect and all. Thats why I don't think its my Google service json that is the problem.
I can successfully register to receive a token from the GCM server. But when I try to send a push notification nothing happens. I do receive a notification when it registers successfully so I think that my notification centre is working too. I follows the steps for creating the certificates as well. So I do not know where the problem is.: I am also using a third party APNs tester to rule out my server being the issues. I am using APN Tester. The APN tester returns this from doing a push notification:
gateway.sandbox.push.apple.com:2195
2016-05-23 07:56:02 +0000: Connected to server gateway.sandbox.push.apple.com
2016-05-23 07:56:02 +0000: Set SSL connection
2016-05-23 07:56:02 +0000: Set peer domain name gateway.sandbox.push.apple.com
2016-05-23 07:56:02 +0000: Keychain Opened
2016-05-23 07:56:02 +0000: Certificate data for Apple Development IOS Push Services: com.mywebpage.jp.MyClient initialized successfully
2016-05-23 07:56:02 +0000: Sec Identity created
2016-05-23 07:56:02 +0000: Client certificate created
2016-05-23 07:56:03 +0000: Connected
2016-05-23 07:56:03 +0000: Token: <0000000c 00000003 00001bff ff1b0000 00001bff ff1b0000 00001bff ff1b0000 00001bff ff1b0000 00001bff 00000e82 000000ef 0000003a 3a000000 0000003a 3a000000 0000003a 3a000000>
2016-05-23 07:56:03 +0000: Written 92 bytes sending data to gateway.sandbox.push.apple.com:2195
2016-05-23 07:56:03 +0000: Disconnected from server gateway.sandbox.push.apple.com:2195
This is my AppDeligate file
import UIKit
import Foundation
#UIApplicationMain
//add this for GCM
//, GGLInstanceIDDelegate, GCMReceiverDelegate
class AppDelegate: UIResponder, UIApplicationDelegate, GGLInstanceIDDelegate, GCMReceiverDelegate{
let loginInformation = NSUserDefaults.standardUserDefaults()
var window: UIWindow?;
//MARK: Varaibles for GCM
var connectedToGCM = false
var subscribedToTopic = false
var gcmSenderID: String?
var registrationToken: String?
var registrationOptions = [String: AnyObject]()
let registrationKey = "onRegistrationCompleted"
let messageKey = "onMessageReceived"
let subscriptionTopic = "/topics/global"
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
// Override point for customization after application launch.
APIManager.sharedInstance.setAuthorization(Config.API_USERNAME, password: Config.API_PASSWORD)
// [START_EXCLUDE]
// Configure the Google context: parses the GoogleService-Info.plist, and initializes
// the services that have entries in the file
var configureError:NSError?
GGLContext.sharedInstance().configureWithError(&configureError)
assert(configureError == nil, "Error configuring Google services: \(configureError)")
gcmSenderID = GGLContext.sharedInstance().configuration.gcmSenderID
// [END_EXCLUDE]
// Register for remote notifications
let settings: UIUserNotificationSettings = UIUserNotificationSettings(forTypes: [.Alert, .Badge, .Sound], categories: nil)
application.registerUserNotificationSettings(settings)
application.registerForRemoteNotifications()
// [END register_for_remote_notifications]
// [START start_gcm_service]
let gcmConfig = GCMConfig.defaultConfig()
gcmConfig.receiverDelegate = self
GCMService.sharedInstance().startWithConfig(gcmConfig)
// [END start_gcm_service]
//Google Analyitics functions
// [START tracker_swift]
// Configure tracker from GoogleService-Info.plist.
//var configureGAError:NSError?
GGLContext.sharedInstance().configureWithError(&configureError)
assert(configureError == nil, "Error configuring Google services: \(configureError)")
// Optional: configure GAI options.
let gai = GAI.sharedInstance()
gai.trackUncaughtExceptions = true // report uncaught exceptions
gai.logger.logLevel = GAILogLevel.Verbose // remove before app release
// [END tracker_swift]
return true
}
func applicationDidEnterBackground(application: UIApplication) {
GCMService.sharedInstance().disconnect()
// [START_EXCLUDE]
self.connectedToGCM = false
// [END_EXCLUDE]
}
func applicationDidBecomeActive(application: UIApplication) {
// Connect to the GCM server to receive non-APNS notifications
GCMService.sharedInstance().connectWithHandler({(error:NSError?) -> Void in
if let error = error {
print("Could not connect to GCM: \(error.localizedDescription)")
} else {
self.connectedToGCM = true
print("Connected to GCM")
}
})
}
// [START receive_apns_token]
func application( application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken
deviceToken: NSData ) {
// [END receive_apns_token]
// [START get_gcm_reg_token]
// Create a config and set a delegate that implements the GGLInstaceIDDelegate protocol.
let instanceIDConfig = GGLInstanceIDConfig.defaultConfig()
instanceIDConfig.delegate = self
// Start the GGLInstanceID shared instance with that config and request a registration
// token to enable reception of notifications
GGLInstanceID.sharedInstance().startWithConfig(instanceIDConfig)
registrationOptions = [kGGLInstanceIDRegisterAPNSOption:deviceToken,
kGGLInstanceIDAPNSServerTypeSandboxOption:true]
GGLInstanceID.sharedInstance().tokenWithAuthorizedEntity(gcmSenderID,
scope: kGGLInstanceIDScopeGCM, options: registrationOptions, handler: registrationHandler)
// [END get_gcm_reg_token]
}
// [START ack_message_reception]
func application( application: UIApplication,
didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {
print("Notification received: \(userInfo)")
// This works only if the app started the GCM service
GCMService.sharedInstance().appDidReceiveMessage(userInfo);
// Handle the received message
// [START_EXCLUDE]
NSNotificationCenter.defaultCenter().postNotificationName(messageKey, object: nil,
userInfo: userInfo)
// [END_EXCLUDE]
}
func application( application: UIApplication,
didReceiveRemoteNotification userInfo: [NSObject : AnyObject],
fetchCompletionHandler handler: (UIBackgroundFetchResult) -> Void) {
print("Notification received: \(userInfo)")
// This works only if the app started the GCM service
GCMService.sharedInstance().appDidReceiveMessage(userInfo);
// Handle the received message
// Invoke the completion handler passing the appropriate UIBackgroundFetchResult value
// [START_EXCLUDE]
NSNotificationCenter.defaultCenter().postNotificationName(messageKey, object: nil,
userInfo: userInfo)
handler(UIBackgroundFetchResult.NoData);
// [END_EXCLUDE]
}
// [END ack_message_reception]
func registrationHandler(registrationToken: String!, error: NSError!) {
if (registrationToken != nil) {
self.registrationToken = registrationToken
print("Registration Token: \(registrationToken)")
//store the registation token for use in the postData function in the login page
self.loginInformation.setObject(self.registrationToken, forKey: "GCMToken")
self.loginInformation.synchronize()
let userInfo = ["registrationToken": registrationToken]
NSNotificationCenter.defaultCenter().postNotificationName(
self.registrationKey, object: nil, userInfo: userInfo)
} else {
print("Registration to GCM failed with error: \(error.localizedDescription)")
let userInfo = ["error": error.localizedDescription]
NSNotificationCenter.defaultCenter().postNotificationName(
self.registrationKey, object: nil, userInfo: userInfo)
}
}
// [START on_token_refresh]
func onTokenRefresh() {
// A rotation of the registration tokens is happening, so the app needs to request a new token.
print("The GCM registration token needs to be changed.")
GGLInstanceID.sharedInstance().tokenWithAuthorizedEntity(gcmSenderID,
scope: kGGLInstanceIDScopeGCM, options: registrationOptions, handler: registrationHandler)
}
// [END on_token_refresh]
// [START upstream_callbacks]
func willSendDataMessageWithID(messageID: String!, error: NSError!) {
if (error != nil) {
// Failed to send the message.
} else {
// Will send message, you can save the messageID to track the message
}
}
// [START receive_apns_token_error]
func application( application: UIApplication, didFailToRegisterForRemoteNotificationsWithError
error: NSError ) {
print("Registration for remote notification failed with error: \(error.localizedDescription)")
// [END receive_apns_token_error]
let userInfo = ["error": error.localizedDescription]
NSNotificationCenter.defaultCenter().postNotificationName(
registrationKey, object: nil, userInfo: userInfo)
}
func didSendDataMessageWithID(messageID: String!) {
// Did successfully send message identified by messageID
}
// [END upstream_callbacks]
func didDeleteMessagesOnServer() {
// Some messages sent to this device were deleted on the GCM server before reception, likely
// because the TTL expired. The client should notify the app server of this, so that the app
// server can resend those messages.
}
//MRAK: End of GCM Function
func applicationWillTerminate(application: UIApplication) {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
func applicationWillEnterForeground(application: UIApplication) {
// Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
}
func applicationWillResignActive(application: UIApplication) {
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}
}
And this is my testing page where it receives the notification of a successful registration:
class PlayGroundController: UIViewController{
#IBOutlet weak var registeringLabel: UILabel!
#IBOutlet weak var registrationProgressing: UIActivityIndicatorView!
override func viewDidLoad() {
super.viewDidLoad()
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(PlayGroundController.updateRegistrationStatus(_:)),
name: appDelegate.registrationKey, object: nil)
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(PlayGroundController.showReceivedMessage(_:)),
name: appDelegate.messageKey, object: nil)
registrationProgressing.hidesWhenStopped = true
registrationProgressing.startAnimating()
}
func updateRegistrationStatus(notification: NSNotification) {
registrationProgressing.stopAnimating()
if let info = notification.userInfo as? Dictionary<String,String> {
if let error = info["error"] {
registeringLabel.text = "Error registering!"
showAlert("Error registering with GCM", message: error)
} else if let _ = info["registrationToken"] {
registeringLabel.text = "Registered!"
let message = "Check the xcode debug console for the registration token that you " +
" can use with the demo server to send notifications to your device"
showAlert("Registration Successful!", message: message)
}
} else {
print("Software failure. Guru meditation.")
}
}
func showReceivedMessage(notification: NSNotification) {
if let info = notification.userInfo as? Dictionary<String,AnyObject> {
if let aps = info["aps"] as? Dictionary<String, String> {
showAlert("Message received", message: aps["alert"]!)
}
} else {
print("Software failure. Guru meditation.")
}
}
func showAlert(title:String, message:String) {
//Set up for the title color
let attributedString = NSAttributedString(string: title, attributes: [
NSFontAttributeName : UIFont.systemFontOfSize(15), //your font here,
NSForegroundColorAttributeName : UIColor.whiteColor()
])
//Set up for the Message Color
let attributedString2 = NSAttributedString(string: message, attributes: [
NSFontAttributeName : UIFont.systemFontOfSize(15), //your font here,
NSForegroundColorAttributeName : UIColor.whiteColor()
])
let alert = UIAlertController(title: title,message: message, preferredStyle: .Alert)
alert.setValue(attributedString, forKey: "attributedTitle")
alert.setValue(attributedString2, forKey: "attributedMessage")
//alert.view.tintColor = UIColor.whiteColor()
let dismissAction = UIAlertAction(title: "Dismiss", style: .Destructive, handler: nil)
alert.addAction(dismissAction)
self.presentViewController(alert, animated: true, completion: nil)
//set the color of the Alert
//let subview = alert.view.subviews.first! as UIView
//let alertContentView = subview.subviews.first! as UIView
//alertContentView.backgroundColor = UIColor.blackColor()
let subview :UIView = alert.view.subviews.last! as UIView
let alertContentView = subview.subviews.last! as UIView
alertContentView.backgroundColor = UIColor.blackColor()
//alertContentView.backgroundColor = UIColor.greenColor()
//Changes is to a grey color :(
/*
alertContentView.backgroundColor = UIColor(
red: 0,
green: 0,
blue: 0,
alpha: 1.0)
//Also another Grey Color Not batman black
*/
//alertContentView.backgroundColor = UIColor.blueColor()
//turns into a purple
}
override func preferredStatusBarStyle() -> UIStatusBarStyle {
return UIStatusBarStyle.LightContent
}
deinit {
NSNotificationCenter.defaultCenter().removeObserver(self)
}
I have what seems like should be a working push notification in an iOS app. Here's the meat of it. What's driving me nuts is that everything appears to work, except that my breakpoints are never hit in the message receiver functions; device registration with Google Cloud Notifications is successful, the initialization code appears to work and I even get "Success" messages back from the GCM service.
STILL, I never seem to actually get the message in my app. Note, I'm running it in an iPad connected to my Mac and everything seems kosher/enabled in Notifications settings. Also, I'm using the dev certificate to match the kGGLInstanceIDAPNSServerTypeSandboxOption:true option.
What could I be missing?
import UIKit
import Google
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, GGLInstanceIDDelegate {
var window: UIWindow?
var gcmSenderID: String?
var registrationToken: String?
var registrationOptions = [String: AnyObject]()
let messageKey = "onMessageReceived"
let registrationKey = "onRegistrationCompleted"
func application( application: UIApplication,
didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {
//********************************
//*** Never Hits Breakpoint ******
//********************************
print("Notification received: \(userInfo)")
// Handle the received message
NSNotificationCenter.defaultCenter().postNotificationName(messageKey, object: nil,
userInfo: userInfo)
}
func application( application: UIApplication,
didReceiveRemoteNotification userInfo: [NSObject : AnyObject],
fetchCompletionHandler handler: (UIBackgroundFetchResult) -> Void) {
//********************************
//*** Never Hits Breakpoint ******
//********************************
NSNotificationCenter.defaultCenter().postNotificationName(messageKey, object: nil,
userInfo: userInfo)
handler(UIBackgroundFetchResult.NoData);
}
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
var configureError:NSError?
GGLContext.sharedInstance().configureWithError(&configureError)
assert(configureError == nil, "Error configuring Google services: \(configureError)")
gcmSenderID = GGLContext.sharedInstance().configuration.gcmSenderID
// ...
// Register for remote notifications
let settings: UIUserNotificationSettings =
UIUserNotificationSettings(forTypes: [.Alert, .Badge, .Sound], categories: nil)
application.registerUserNotificationSettings(settings)
application.registerForRemoteNotifications()
// Override point for customization after application launch.
return true
}
func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {
// Create a config and set a delegate that implements the GGLInstaceIDDelegate protocol.
let instanceIDConfig = GGLInstanceIDConfig.defaultConfig()
instanceIDConfig.delegate = self
// Start the GGLInstanceID shared instance with that config and request a registration
// token to enable reception of notifications
GGLInstanceID.sharedInstance().startWithConfig(instanceIDConfig)
registrationOptions = [kGGLInstanceIDRegisterAPNSOption:deviceToken,
kGGLInstanceIDAPNSServerTypeSandboxOption:true]
GGLInstanceID.sharedInstance().tokenWithAuthorizedEntity(gcmSenderID,
scope: kGGLInstanceIDScopeGCM, options: registrationOptions, handler: registrationHandler)
}
func application( application: UIApplication, didFailToRegisterForRemoteNotificationsWithError
error: NSError ) {
print("Registration for remote notification failed with error: \(error.localizedDescription)")
// [END receive_apns_token_error]
let userInfo = ["error": error.localizedDescription]
NSNotificationCenter.defaultCenter().postNotificationName(
registrationKey, object: nil, userInfo: userInfo)
}
func registrationHandler(registrationToken: String!, error: NSError!) {
if (registrationToken != nil) {
self.registrationToken = registrationToken
print("Registration Token: \(registrationToken)")
let userInfo = ["registrationToken": registrationToken]
NSNotificationCenter.defaultCenter().postNotificationName(
self.registrationKey, object: nil, userInfo: userInfo)
} else {
print("Registration to GCM failed with error: \(error.localizedDescription)")
let userInfo = ["error": error.localizedDescription]
NSNotificationCenter.defaultCenter().postNotificationName(
self.registrationKey, object: nil, userInfo: userInfo)
}
}
func onTokenRefresh() {
// A rotation of the registration tokens is happening, so the app needs to request a new token.
print("The GCM registration token needs to be changed.")
GGLInstanceID.sharedInstance().tokenWithAuthorizedEntity(gcmSenderID,
scope: kGGLInstanceIDScopeGCM, options: registrationOptions, handler: registrationHandler)
}
}
Message sent to https://gcm-http.googleapis.com/gcm/send. The payload is arbitrary/copied from a sample.
{
"content-available":1,
"data": {
"score": "5x1",
"time": "15:10"
},
"to" : "<<the registration token resulting from the code above>>"
}
...which results in the reply:
{
"multicast_id": 12345...,
"success": 1,
"failure": 0,
"canonical_ids": 0,
"results": [
{
"message_id": "some ID"
}
]
}
Any ideas?
Please try following command in your terminal by substituting your GCM registration token and Server API key.. this command helps me.
Please make sure payload dictionary must be notification not
data
curl --header "Authorization: key=” https://android.googleapis.com/gcm/send -d '{"to”:””,”priority":"high”, “notification":{"title”:”TEST TITLES”,”body":"Wow ! your first message tested.","badge":"1","sound":"default"}}'
Also try checking by app sending in background CMD + H
Using GCM for push notification in iOS. Everything is set up nicely. I'm getting registrationToken value & also subscribeToTopic successfully. Connected to GCM. didRegisterForRemoteNotificationsWithDeviceToken method also called. But not getting push notification. didReceiveRemoteNotification method never called. On my android app I'm getting the push notification without any problem. But in iOS notification never received. Here is the source code:
class AppDelegate: UIResponder, UIApplicationDelegate, GGLInstanceIDDelegate, GCMReceiverDelegate{
var gcmSenderID: String?
var registrationToken: String?
let registrationKey = "onRegistrationCompleted"
let messageKey = "onMessageReceived"
var registrationOptions = [String: AnyObject]()
var connectedToGCM = false
let subscriptionTopic = "/topics/global"
var subscribedToTopic = false
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
var configureError:NSError?
GGLContext.sharedInstance().configureWithError(&configureError)
gcmSenderID = GGLContext.sharedInstance().configuration.gcmSenderID
if application.respondsToSelector("registerUserNotificationSettings:") {
let types:UIUserNotificationType = (.Alert | .Badge | .Sound)
let settings:UIUserNotificationSettings = UIUserNotificationSettings(forTypes: types, categories: nil)
application.registerUserNotificationSettings(settings)
application.registerForRemoteNotifications()
} else {
// Register for Push Notifications before iOS 8
application.registerForRemoteNotificationTypes(.Alert | .Badge | .Sound)
}
let gcmConfig = GCMConfig.defaultConfig()
gcmConfig.receiverDelegate = self
GCMService.sharedInstance().startWithConfig(gcmConfig)
return true
}
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {
print("remote notification")
GCMService.sharedInstance().appDidReceiveMessage(userInfo);
}
func application( application: UIApplication,
didReceiveRemoteNotification userInfo: [NSObject : AnyObject],
fetchCompletionHandler handler: (UIBackgroundFetchResult) -> Void) {
GCMService.sharedInstance().appDidReceiveMessage(userInfo);
NSNotificationCenter.defaultCenter().postNotificationName(messageKey, object: nil,
userInfo: userInfo)
handler(UIBackgroundFetchResult.NoData);
}
func application( application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken
deviceToken: NSData ) {
let instanceIDConfig = GGLInstanceIDConfig.defaultConfig()
instanceIDConfig.delegate = self
GGLInstanceID.sharedInstance().startWithConfig(instanceIDConfig)
registrationOptions = [kGGLInstanceIDRegisterAPNSOption:deviceToken,
kGGLInstanceIDAPNSServerTypeSandboxOption:true]
GGLInstanceID.sharedInstance().tokenWithAuthorizedEntity(gcmSenderID,
scope: kGGLInstanceIDScopeGCM, options: registrationOptions, handler: registrationHandler)
// [END get_gcm_reg_token]
}
func onTokenRefresh() {
// A rotation of the registration tokens is happening, so the app needs to request a new token.
print("The GCM registration token needs to be changed.")
GGLInstanceID.sharedInstance().tokenWithAuthorizedEntity(gcmSenderID,
scope: kGGLInstanceIDScopeGCM, options: registrationOptions, handler: registrationHandler)
}
func registrationHandler(registrationToken: String!, error: NSError!) {
if (registrationToken != nil) {
self.registrationToken = registrationToken
print("Registration Token: \(registrationToken)")
self.subscribeToTopic()
let userInfo = ["registrationToken": registrationToken]
NSNotificationCenter.defaultCenter().postNotificationName(
self.registrationKey, object: nil, userInfo: userInfo)
} else {
print("Registration to GCM failed with error: \(error.localizedDescription)")
let userInfo = ["error": error.localizedDescription]
NSNotificationCenter.defaultCenter().postNotificationName(
self.registrationKey, object: nil, userInfo: userInfo)
}
}
func subscribeToTopic() {
// topic
if(registrationToken != nil && connectedToGCM) {
GCMPubSub.sharedInstance().subscribeWithToken(self.registrationToken, topic: subscriptionTopic,
options: nil, handler: {(NSError error) -> Void in
if (error != nil) {
// Treat the "already subscribed" error more gently
if error.code == 3001 {
print("Already subscribed to \(self.subscriptionTopic)")
} else {
print("Subscription failed: \(error.localizedDescription)");
}
} else {
self.subscribedToTopic = true;
NSLog("Subscribed to \(self.subscriptionTopic)");
}
})
}
}
func applicationDidBecomeActive(application: UIApplication) {
print("applicationDidBecomeActive")
self.globalPrice = CartLocalData.getTotalPrice()
GCMService.sharedInstance().connectWithHandler({
(NSError error) -> Void in
if error != nil {
print("Could not connect to GCM: \(error.localizedDescription)")
} else {
self.connectedToGCM = true
self.subscribeToTopic()
print("Connected to GCM")
// ...
}
})
}
}
What am I doing wrong. Can anyone suggest??
you should have the option to turn on push from capabilities section. You also need to build separate key/cert pair in the apple member center and have those included on your machine. here is a screenshot from a new project i made.
It sounds like maybe one of the steps in the process might not be done.
Start over again and try to figure out what your missing. here is a ray wenderlich tutorial that walks you through the steps here
And the link to Apple developer site that talks about it in depth here
I use this code to get GCM token (APNS and then GCM tokens).
Does retry happens automatically when GCM doesn't return token?
If so - where can i see it in code? and how often does this happen?
//push
// [START register_for_remote_notifications]
func registerForRemoteNotifications(application: UIApplication, launchOptions:[NSObject: AnyObject]?) -> Bool {
// [START_EXCLUDE]
// Configure the Google context: parses the GoogleService-Info.plist, and initializes
// the services that have entries in the file
var configureError:NSError?
GGLContext.sharedInstance().configureWithError(&configureError)
assert(configureError == nil, "Error configuring Google services: \(configureError)")
pushManager.gcmSenderID = GGLContext.sharedInstance().configuration.gcmSenderID
// [END_EXCLUDE]
// Register for remote notifications
if #available(iOS 8.0, *) {
let settings: UIUserNotificationSettings =
UIUserNotificationSettings(forTypes: [.Alert, .Badge, .Sound], categories: nil)
application.registerUserNotificationSettings(settings)
application.registerForRemoteNotifications()
} else {
// Fallback
let types: UIRemoteNotificationType = [.Alert, .Badge, .Sound]
application.registerForRemoteNotificationTypes(types)
}
// [END register_for_remote_notifications]
// [START start_gcm_service]
let gcmConfig = GCMConfig.defaultConfig()
gcmConfig.receiverDelegate = pushManager
GCMService.sharedInstance().startWithConfig(gcmConfig)
// [END start_gcm_service]
return true
}
func application(application: UIApplication, didRegisterUserNotificationSettings notificationSettings: UIUserNotificationSettings)
{
UIApplication.sharedApplication().registerForRemoteNotifications()
}
func subscribeToTopic() {
// If the app has a registration token and is connected to GCM, proceed to subscribe to the
// topic
if(pushManager.registrationToken != nil && pushManager.connectedToGCM) {
GCMPubSub.sharedInstance().subscribeWithToken(pushManager.registrationToken, topic: pushManager.subscriptionTopic,
options: nil, handler: {(NSError error) -> Void in
if (error != nil) {
// Treat the "already subscribed" error more gently
if error.code == 3001 {
print("Already subscribed to \(self.pushManager.subscriptionTopic)")
} else {
print("Subscription failed: \(error.localizedDescription)");
}
} else {
self.pushManager.subscribedToTopic = true;
NSLog("Subscribed to \(self.pushManager.subscriptionTopic)");
}
})
}
}
// [START connect_gcm_service]
func connectGcmService( application: UIApplication) {
if (self.pushManager.connectedToGCM == true)
{
return
}
// Connect to the GCM server to receive non-APNS notifications
GCMService.sharedInstance().connectWithHandler({
(NSError error) -> Void in
if error != nil {
print("Could not connect to GCM: \(error.localizedDescription)")
} else {
self.pushManager.connectedToGCM = true
print("Connected to GCM")
// [START_EXCLUDE]
self.subscribeToTopic()
// [END_EXCLUDE]
}
})
}
// [END connect_gcm_service]
// [START disconnect_gcm_service]
func disconnectGcmService(application: UIApplication) {
GCMService.sharedInstance().disconnect()
// [START_EXCLUDE]
self.pushManager.connectedToGCM = false
// [END_EXCLUDE]
}
// [END disconnect_gcm_service]
func application( application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken
deviceToken: NSData ) {
let tokenChars = UnsafePointer<CChar>(deviceToken.bytes)
var tokenString = ""
for i in 0..<deviceToken.length {
tokenString += String(format: "%02.2hhx", arguments: [tokenChars[i]])
}
print("tokenString: \(tokenString)")
pushManager.receiveApnsToken( application, deviceToken: deviceToken)
}
func application( application: UIApplication, didFailToRegisterForRemoteNotificationsWithError
error: NSError ) {
pushManager.receiveApnsTokenError( application, error: error)
}
func application( application: UIApplication,
didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {
pushManager.ackMessageReception( application, userInfo: userInfo)
}
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject], fetchCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void) {
pushManager.ackMessageReception( application, userInfo: userInfo)
}
and PushManager class:
public class PushManager: NSObject, GGLInstanceIDDelegate, GCMReceiverDelegate {
var connectedToGCM = false
var subscribedToTopic = false
var gcmSenderID: String?
var registrationToken: String?
var registrationOptions = [String: AnyObject]()
let registrationKey = "onRegistrationCompleted"
let messageKey = "onMessageReceived"
let subscriptionTopic = "/topics/global"
// // [START register_for_remote_notifications]
func registerForRemoteNotifications(application: UIApplication, launchOptions: [NSObject: AnyObject]?) -> Bool {
// [START_EXCLUDE]
// Configure the Google context: parses the GoogleService-Info.plist, and initializes
// the services that have entries in the file
var configureError:NSError?
GGLContext.sharedInstance().configureWithError(&configureError)
assert(configureError == nil, "Error configuring Google services: \(configureError)")
gcmSenderID = GGLContext.sharedInstance().configuration.gcmSenderID
// [END_EXCLUDE]
// Register for remote notifications
if #available(iOS 8.0, *) {
let settings: UIUserNotificationSettings =
UIUserNotificationSettings(forTypes: [.Alert, .Badge, .Sound], categories: nil)
application.registerUserNotificationSettings(settings)
application.registerForRemoteNotifications()
} else {
// Fallback
let types: UIRemoteNotificationType = [.Alert, .Badge, .Sound]
application.registerForRemoteNotificationTypes(types)
}
// [END register_for_remote_notifications]
// [START start_gcm_service]
let gcmConfig = GCMConfig.defaultConfig()
gcmConfig.receiverDelegate = self
GCMService.sharedInstance().startWithConfig(gcmConfig)
// [END start_gcm_service]
return true
}
func subscribeToTopic() {
// If the app has a registration token and is connected to GCM, proceed to subscribe to the
// topic
if(registrationToken != nil && connectedToGCM) {
GCMPubSub.sharedInstance().subscribeWithToken(self.registrationToken, topic: subscriptionTopic,
options: nil, handler: {(NSError error) -> Void in
if (error != nil) {
// Treat the "already subscribed" error more gently
if error.code == 3001 {
print("Already subscribed to \(self.subscriptionTopic)")
} else {
print("Subscription failed: \(error.localizedDescription)");
}
} else {
self.subscribedToTopic = true;
NSLog("Subscribed to \(self.subscriptionTopic)");
}
})
}
}
// [START connect_gcm_service]
func connectGcmService( application: UIApplication) {
// Connect to the GCM server to receive non-APNS notifications
GCMService.sharedInstance().connectWithHandler({
(NSError error) -> Void in
if error != nil {
print("Could not connect to GCM: \(error.localizedDescription)")
} else {
self.connectedToGCM = true
print("Connected to GCM")
// [START_EXCLUDE]
self.subscribeToTopic()
// [END_EXCLUDE]
}
})
}
// [END connect_gcm_service]
// [START disconnect_gcm_service]
func applicationDidEnterBackground(application: UIApplication) {
GCMService.sharedInstance().disconnect()
// [START_EXCLUDE]
self.connectedToGCM = false
// [END_EXCLUDE]
}
// [END disconnect_gcm_service]
// [START receive_apns_token]
public func receiveApnsToken( application: UIApplication, deviceToken: NSData ) {
// [END receive_apns_token]
// [START get_gcm_reg_token]
// Create a config and set a delegate that implements the GGLInstaceIDDelegate protocol.
let instanceIDConfig = GGLInstanceIDConfig.defaultConfig()
instanceIDConfig.delegate = self
// Start the GGLInstanceID shared instance with that config and request a registration
// token to enable reception of notifications
GGLInstanceID.sharedInstance().startWithConfig(instanceIDConfig)
registrationOptions = [kGGLInstanceIDRegisterAPNSOption:deviceToken,
kGGLInstanceIDAPNSServerTypeSandboxOption:true]
GGLInstanceID.sharedInstance().tokenWithAuthorizedEntity(gcmSenderID,
scope: kGGLInstanceIDScopeGCM, options: registrationOptions, handler: registrationHandler)
// [END get_gcm_reg_token]
}
// [START receive_apns_token_error]
public func receiveApnsTokenError( application: UIApplication, error: NSError ) {
print("Registration for remote notification failed with error: \(error.localizedDescription)")
// [END receive_apns_token_error]
let userInfo = ["error": error.localizedDescription]
NSNotificationCenter.defaultCenter().postNotificationName(
registrationKey, object: nil, userInfo: userInfo)
}
// [START ack_message_reception]
func ackMessageReception( application: UIApplication, userInfo: [NSObject : AnyObject]) {//, fetchCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void) {
print("Notification received: \(userInfo)")
// This works only if the app started the GCM service
GCMService.sharedInstance().appDidReceiveMessage(userInfo);
...
}
func application( application: UIApplication,
didReceiveRemoteNotification userInfo: [NSObject : AnyObject],
fetchCompletionHandler handler: (UIBackgroundFetchResult) -> Void) {
print("Notification received: \(userInfo)")
// This works only if the app started the GCM service
GCMService.sharedInstance().appDidReceiveMessage(userInfo);
// Handle the received message
// Invoke the completion handler passing the appropriate UIBackgroundFetchResult value
// [START_EXCLUDE]
NSNotificationCenter.defaultCenter().postNotificationName(messageKey, object: nil,
userInfo: userInfo)
handler(UIBackgroundFetchResult.NoData);
// [END_EXCLUDE]
}
// [END ack_message_reception]
func registrationHandler(registrationToken: String!, error: NSError!) {
if (registrationToken != nil) {
self.registrationToken = registrationToken
print("Registration Token: \(registrationToken)")
self.subscribeToTopic()
let userInfo = ["registrationToken": registrationToken]
NSNotificationCenter.defaultCenter().postNotificationName(
self.registrationKey, object: nil, userInfo: userInfo)
} else {
print("Registration to GCM failed with error: \(error.localizedDescription)")
let userInfo = ["error": error.localizedDescription]
NSNotificationCenter.defaultCenter().postNotificationName(
self.registrationKey, object: nil, userInfo: userInfo)
}
}
// [START on_token_refresh]
public func onTokenRefresh() {
// A rotation of the registration tokens is happening, so the app needs to request a new token.
print("The GCM registration token needs to be changed.")
GGLInstanceID.sharedInstance().tokenWithAuthorizedEntity(gcmSenderID,
scope: kGGLInstanceIDScopeGCM, options: registrationOptions, handler: registrationHandler)
}
Based on the docs, If registration fails, the client app is recommended to retry. In cases where GCM is not essential to the client app's functioning, the app could ignore the registration error and try to register again the next time it starts. Otherwise, it should retry the registration operation using exponential back-off (the client app should wait twice the previous amount of time before retrying). Once your client app has a registration token, it can receive messages through the GCM APNs interface.
To handle cases where registration token has been refreshed, the GGLInstanceIDDelegate protocol declares an onTokenRefresh method that is called when the system determines that tokens need to be refreshed.
func onTokenRefresh() {
// A rotation of the registration tokens is happening, so the app needs to request a new token.
print("The GCM registration token needs to be changed.")
GGLInstanceID.sharedInstance().tokenWithAuthorizedEntity(gcmSenderID,
scope: kGGLInstanceIDScopeGCM, options: registrationOptions, handler: registrationHandler)
}
In my project I have to get GCM push-notifications and I done everything perfect and also server sent to me registration token and GCM server connected perfectly but notifications are not coming in my device.
my xcode console showing like this:
2015-07-17 11:20:41.701 GCMSwift[1134:421304] You've implemented -[<UIApplicationDelegate> application:didReceiveRemoteNotification:fetchCompletionHandler:], but you still need to add "remote-notification" to the list of your supported UIBackgroundModes in your Info.plist.
2015-07-17 11:20:41.718 GCMSwift[1134:421304] Attempted to configure [Identity, Analytics, AdMob, SignIn, AppInvite, CloudMessaging].
2015-07-17 11:20:41.719 GCMSwift[1134:421304] Successfully configured [CloudMessaging].
2015-07-17 11:20:41.720 GCMSwift[1134:421304] Failed to configure [].
2015-07-17 11:20:41.721 GCMSwift[1134:421304] Subspecs not present, so not configured [Identity, Analytics, AdMob, SignIn, AppInvite].
Registration Token: l3OcbsTm5nQ:APA91bGs6cUSE8GeJZcsW3pL6i-O4VIwDqifLFzfwnKjZDQy6bD0zlxiqAH-XfErDzmZka5q5o01YnN9a8roCfQnP0QGarpZk2dtt5ebL0GImkSCQYfqrrK1VCshT8Jo7MMYuEHvktUE
Connected to GCM
Already subscribed to /topics/global
And this is my code:
import UIKit
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate,GGLInstanceIDDelegate {
var window: UIWindow?
// GCM iVars.
var registrationOptions = [String: AnyObject]()
var gcmSenderID: String?
var connectedToGCM = false
var subscribedToTopic = false
var registrationToken: String?
let registrationKey = "onRegistrationCompleted"
let messageKey = "onMessageReceived"
let subscriptionTopic = "/topics/global"
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
// Override point for customization after application launch.
/**************** GCM Google service. ***********************/
// [START_EXCLUDE]
// Configure the Google context: parses the GoogleService-Info.plist, and initializes
// the services that have entries in the file
var configureError:NSError?
GGLContext.sharedInstance().configureWithError(&configureError)
if configureError != nil {
println("Error configuring the Google context: \(configureError)")
}
gcmSenderID = GGLContext.sharedInstance().configuration.gcmSenderID
// [END_EXCLUDE]
// Register for remote notifications
var types: UIUserNotificationType = UIUserNotificationType.Badge | UIUserNotificationType.Alert | UIUserNotificationType.Sound
var settings: UIUserNotificationSettings =
UIUserNotificationSettings( forTypes: types, categories: nil )
application.registerUserNotificationSettings(settings)
application.registerForRemoteNotifications()
// [START start_gcm_service]
GCMService.sharedInstance().startWithConfig(GCMConfig.defaultConfig())
// [END start_gcm_service]
return true
}
func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {
// Start the GGLInstanceID shared instance with the default config and request a registration token to enable reception of notifications
GGLInstanceID.sharedInstance().startWithConfig(GGLInstanceIDConfig.defaultConfig())
registrationOptions = [kGGLInstanceIDRegisterAPNSOption:deviceToken,
kGGLInstanceIDAPNSServerTypeSandboxOption:true]
GGLInstanceID.sharedInstance().tokenWithAuthorizedEntity(gcmSenderID, scope: kGGLInstanceIDScopeGCM, options: registrationOptions, handler: registrationHandler)
}
// [START receive_apns_token_error]
func application( application: UIApplication, didFailToRegisterForRemoteNotificationsWithError
error: NSError ) {
println("Registration for remote notification failed with error: \(error.localizedDescription)")
// [END receive_apns_token_error]
let userInfo = ["error": error.localizedDescription]
NSNotificationCenter.defaultCenter().postNotificationName(
registrationKey, object: nil, userInfo: userInfo)
}
func onTokenRefresh() {
// A rotation of the registration tokens is happening, so the app needs to request a new token.
println("The GCM registration token needs to be changed.")
GGLInstanceID.sharedInstance().tokenWithAuthorizedEntity(gcmSenderID,
scope: kGGLInstanceIDScopeGCM, options: registrationOptions, handler: registrationHandler)
}
func registrationHandler(registrationToken: String!, error: NSError!){
// registration handeler.
if (registrationToken != nil) {
self.registrationToken = registrationToken
println("Registration Token: \(registrationToken)")
self.subscribeToTopic()
let userInfo = ["registrationToken": registrationToken]
NSNotificationCenter.defaultCenter().postNotificationName(
self.registrationKey, object: nil, userInfo: userInfo)
} else {
println("Registration to GCM failed with error: \(error.localizedDescription)")
let userInfo = ["error": error.localizedDescription]
NSNotificationCenter.defaultCenter().postNotificationName(
self.registrationKey, object: nil, userInfo: userInfo)
}
}
func subscribeToTopic() {
// If the app has a registration token and is connected to GCM, proceed to subscribe to the
// topic
if(registrationToken != nil && connectedToGCM) {
GCMPubSub.sharedInstance().subscribeWithToken(self.registrationToken, topic: subscriptionTopic,
options: nil, handler: {(NSError error) -> Void in
if (error != nil) {
// Treat the "already subscribed" error more gently
if error.code == 3001 {
println("Already subscribed to \(self.subscriptionTopic)")
} else {
println("Subscription failed: \(error.localizedDescription)");
}
} else {
self.subscribedToTopic = true;
NSLog("Subscribed to \(self.subscriptionTopic)");
}
})
}
}
/******************** DID RECIEVE PUSH NOTIFICATION ************************/
// [START ack_message_reception]
func application( application: UIApplication,
didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {
println("Notification received: \(userInfo)")
// This works only if the app started the GCM service
GCMService.sharedInstance().appDidReceiveMessage(userInfo);
// Handle the received message
// [START_EXCLUDE]
NSNotificationCenter.defaultCenter().postNotificationName(messageKey, object: nil,
userInfo: userInfo)
// [END_EXCLUDE]
}
func application( application: UIApplication,
didReceiveRemoteNotification userInfo: [NSObject : AnyObject],
fetchCompletionHandler handler: (UIBackgroundFetchResult) -> Void) {
println("Notification received: \(userInfo)")
// This works only if the app started the GCM service
GCMService.sharedInstance().appDidReceiveMessage(userInfo);
// Handle the received message
// Invoke the completion handler passing the appropriate UIBackgroundFetchResult value
// [START_EXCLUDE]
NSNotificationCenter.defaultCenter().postNotificationName(messageKey, object: nil,
userInfo: userInfo)
handler(UIBackgroundFetchResult.NoData);
// [END_EXCLUDE]
}
// [END ack_message_reception]
func applicationWillResignActive(application: UIApplication) {
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}
func applicationDidEnterBackground(application: UIApplication) {
GCMService.sharedInstance().disconnect()
// [START_EXCLUDE]
self.connectedToGCM = false
// [END_EXCLUDE]
println("Stop executing app and whent into background!")
}
func applicationWillEnterForeground(application: UIApplication) {
// Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
}
func applicationDidBecomeActive(application: UIApplication) {
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
GCMService.sharedInstance().connectWithHandler({
(NSError error) -> Void in
if error != nil {
println("Could not connect to GCM: \(error.localizedDescription)")
} else {
self.connectedToGCM = true
println("Connected to GCM")
// [START_EXCLUDE]
self.subscribeToTopic()
// [END_EXCLUDE]
}
})
}
func applicationWillTerminate(application: UIApplication) {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
}
But notifications are not receiving to my device, do I have to do anything extra here? and did I forget to add anything? and I uploaded .p12 certificate and I have created APNs certificate perfectly why I did not get GCM notifications and "didReceiveRemoteNotification" method is not calling do I have to attach server API key or SenderId along with code what I written above.
If you see your console first line:
2015-07-17 11:20:41.701 GCMSwift[1134:421304] You've implemented -[<UIApplicationDelegate> application:didReceiveRemoteNotification:fetchCompletionHandler:], but you still need to add "remote-notification" to the list of your supported UIBackgroundModes in your Info.plist
You need to enable the Required background modes. Follow the steps:
In the Project Navigator click the project
In the Projects and Targets list click the target.
Click Capabilities
Expand and turn on Background Modes
Click Remote Notifications
This will add the background mode support in your Info.plist.