1

I have been following the google GCM tutorials for push notification. All seems to be working except for the notification to show on the screen. on the xcode output it shows the information has been send. Please can some one help I have included the php and the swift.app

Appdelegate.swift

  {

  import UIKit

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, GGLInstanceIDDelegate, GCMReceiverDelegate {

    var window: UIWindow?

    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 application(application: UIApplication, didFinishLaunchingWithOptions 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)

            GCMService.sharedInstance().startWithConfig(GCMConfig.defaultConfig())
            // [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 applicationDidBecomeActive( application: UIApplication) {
        GCMService.sharedInstance().connectWithHandler({
            (NSError error) -> Void in
            if error != nil {
                print("Could not connect to GCM: \(error.localizedDescription)")
            } else {
                print("Connected to GCM")
            }
        })
    }
    // [END connect_gcm_service]

    // [START disconnect_gcm_service]
    func applicationDidEnterBackground(application: UIApplication) {
        GCMService.sharedInstance().disconnect()
        // [START_EXCLUDE]
        self.connectedToGCM = true
        // [END_EXCLUDE]
    }
    // [END disconnect_gcm_service]

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

    // [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)")
            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]
    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
        }
    }

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

php

<?php


define("GOOGLE_API_KEY", "AIzaSyD5xxxxxxxxx4mp28rpU8Nw");
define("GOOGLE_GCM_URL", "https://gcm-http.googleapis.com/gcm/send");

//https://android.googleapis.com/gcm/send

function send_gcm_notify($reg_id, $message) {

 $message = "test";
    $fields = array(
        'registration_ids'  => array( $reg_id ),
        'data'              => array( 'price' => $message, 'sound' => 'default', 'body' => 'helloworld', 'title' => 'default', 'badge' => 12, 'content-available' => 'true', 'priority'=> 'high'),


    );



//$data = array( 'price' => $message, 'sound' => 'default', 'body' => 'helloworld', 'title' => 'default', 'badge' => 12, 'content-available' => 1);


    $headers = array(
        'Authorization: key=' . GOOGLE_API_KEY,
        'Content-Type: application/json'
    );

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, GOOGLE_GCM_URL);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($fields));

    $result = curl_exec($ch);
    if ($result === FALSE) {
        die('Problem occurred: ' . curl_error($ch));
    }

    curl_close($ch);
    echo $result;
 }

$reg_id ="kiIp-2Q3en4:APA91bEaFJxxxxxxxxxLBNT8rDsyxyTmW97hiDQSouQI6nNC7JwUPBxzRmHpjx2BHQcvgEiaO0J4dS_2dHy2mfCoEgej3SevQFJ4eMMTUSgwvP634KMmK8vgy2DwtdxfvkBck";
$msg = "Google 123";

send_gcm_notify($reg_id, $msg);


?>

Here are my outputs results: php: {"multicast_id":81418xxxxxx136054,"success":1,"failure":0,"canonical_ids":0,"results":[{"message_id":"0:144724xxxxxx3ef9fd7ecd"}]}

xcode output view

Notification received: [from: 76c1241cc5, badge: 12, price: test, title: default, collapse_key: do_not_collapse, sound: default, content-available: true, body: helloworld, priority: high]

So, I just have a blank screen with no notification, please let me know where i am going wrong thanks in advance Hesh

hesh
  • 65
  • 4
  • 12
  • Was your application terminated? If so, your app wont receive the notification unless the priority is set to high in your HTTP request body. Also, have you tried to send HTTP request using curl or Postman? Also, can you post your HTTP request? – ztan Nov 11 '15 at 18:12
  • HI Ztan I been using the php to send the notification, as you can see the 'priority'=> 'high' is set to high, using curl No the app wasnt terminated – hesh Nov 11 '15 at 18:47
  • If your app is not terminated, then you should see a banner appear at top of your phone screen when your app is in background. If your app is actively in foreground, you might need to notify your view controller or app delegate to show an alert or some UI Changes. If you see a dictionary printed in your XCode log, that means your app receive the payload as dictionary format, you just need to handle it correctly to show in your UI. – ztan Nov 11 '15 at 18:51
  • thanks.. good to know its there, the problem is i am not sure how i get it to notify the view controller. I was looking at the gcm tutorial ... would you know? – hesh Nov 11 '15 at 18:56
  • I can show the text from the view contoller of the tutorial? there are functions there, but its not reading the override func viewDidLoad() { – hesh Nov 11 '15 at 19:01
  • You just just make an UIAlertView in your `didReceiveRemoteNotification` method, when a push notification arrives – ztan Nov 11 '15 at 19:09
  • Sorry many thanks for your help on this, could you give a example of the simple uialertview? – hesh Nov 11 '15 at 19:37
  • http://stackoverflow.com/a/24022696/4195406 this answer can help – ztan Nov 11 '15 at 19:57
  • Thankyou for your help, Was awesome gave me help no end! – hesh Nov 12 '15 at 15:34

2 Answers2

1

On iOS, if you want a system notification to be shown you MUST send a Notification Message. In your question you are sending a data message so try including the notification payload as a sibling of the "to" field and "data" field if you also want to send data with your message.

Change this:

$fields = array(
        'registration_ids'  => array( $reg_id ),
        'data'              => array( 'price' => $message, 'sound' => 'default', 'body' => 'helloworld', 'title' => 'default', 'badge' => 12, 'content-available' => 'true', 'priority'=> 'high'),


    );

To this:

$fields = array(
        'registration_ids'  => array( $reg_id ),
        'priority'=> array( 'high' ),
        'content_available' => array( 'true' ),
        'data'              => array( 'price' => $message ),
        'notification'      => array( 'sound' => 'default', 'body' => 'helloworld', 'title' => 'default', 'badge' => 12 )
    );
Arthur Thompson
  • 9,087
  • 4
  • 29
  • 33
0

Its not a solution but a better way to troubleshoot. I highly recommend installing a Google Chrome Extention called Advanced REST Client:

Advanced REST Client Extention

With it you can send notifications easily. My theory is that your payload is not set right. I had the exact same problem and all I had to do was introduce "priority":"high" into the payload. I know you have it, but im just afraid its not formatted properly. Try the extention and try to follow the format as mine.

enter image description here

VBaarathi
  • 793
  • 8
  • 12
  • Thankyou! this was a big help! Yes it works perfectly using the Advanced REST Client Extension, but like you said its the formatting. I am trying the same fomat on the php script but still no go :( – hesh Nov 12 '15 at 15:36
  • ok I have to give credit to all three here, The information from ztan, the testing information and recommendation from VBaarathi and the code from Arthur. Big thanks All! – hesh Nov 12 '15 at 17:52