使用 GCM 在 IO 中实现推送通知

Posted

技术标签:

【中文标题】使用 GCM 在 IO 中实现推送通知【英文标题】:Implement push notification in IOs using GCM 【发布时间】:2016-06-06 09:00:23 【问题描述】:

我已经实现了 Google Cloud Messaging。我收到通知。但我不知道如何将其转换为推送通知。谁能帮我这个?我从 GCM 收到此结果收到通知:[消息:Simon Swiped yes for your profile,collapse_key:do_not_collapse, from:857170554763]

这是代码。有人可以帮我吗?

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)
// [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: (error:NSError?) -> Void in
                                                  if let error = error 
                                                    // 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) 
// 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_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]
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.


 

【问题讨论】:

通知!= 推送通知?你的实际问题是什么? 我必须在 iphone 的通知栏中将消息显示为推送通知@Shubhank 它们仅在应用程序处于后台时出现。在前台 - 如果需要,您可以简单地显示警报。 应用在后台时不起作用 您的代码格式很差。我认为没有人会考虑它,而且你的问题也不清楚。您可能会问我没有收到通知,但您要求显示错误的通知。 【参考方案1】:

在GCM Notifications docs 上找到了这个。

如果您想将仅包含自定义键/值的消息发送到 应用在后台时的 iOS 设备,设置自定义键/值 在数据中配对并将"content_available" 设置为true。看起来 可能是您的代码中缺少的部分。

样本:

 
  "to": "gcm_token_of_the_device",
  "content_available":true,
  "notification": 
    "sound": "default",
    "badge": "2",
    "title": "default",
    "body": "Test Push!"
  

您也可以查看此SO thread 以获取更多信息。

【讨论】:

以上是关于使用 GCM 在 IO 中实现推送通知的主要内容,如果未能解决你的问题,请参考以下文章

使用 django 和 GCM 推送通知

iOS 推送通知和 GCM

GCM 推送通知不适用于 xamarin android

Android:在 GCM 中检查待处理的推送通知?

Swift - GCM:不显示 iOS 远程推送通知

如何使用 Java GCM API 在 android 设备上获取失败推送通知的注册 ID