gpt4 book ai didi

ios - 如何在应用程序未运行/应用程序终止时获取推送通知

转载 作者:搜寻专家 更新时间:2023-10-31 21:49:37 25 4
gpt4 key购买 nike

我试过了Google 开发人员的“在 iOS 上设置 GCM 客户端应用程序”。我的应用程序有一个 android 版本,服务器成功向 Android 发送推送通知。在 ios 中,我可以将消息检索到 didRecieveRemoteNotification 函数。打印时如下所示,

aps: {
alert = {
body = tyyy;
title = "2 is going out at 03/24/2016 15:02:48";
};
badge = 2;
sound = default;
}

当应用程序处于前台和后台时,它会收到此消息。当应用程序处于后台时,系统托盘中不显示任何内容。

当应用程序终止并且服务器正在发送推送通知时,我什么也没有收到,也没有显示任何事件。

我的代码如下。

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 = "AIzaSy-.....-11bSP6v72UvyKY"
var registrationOptions = [String: AnyObject]()

let registrationKey = "onRegistrationCompleted"
let messageKey = "onMessageReceived"
let subscriptionTopic = "/topics/global"


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

NSUserDefaults.standardUserDefaults().setBool(true, forKey: "APP_RUNNING")


// Override point for customization after application launch.

// [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]

application.registerUserNotificationSettings(UIUserNotificationSettings(forTypes: [.Alert, .Badge, .Sound],categories: nil))

if let options = launchOptions {
if let notification = options[UIApplicationLaunchOptionsLocalNotificationKey] as? UILocalNotification {
if let userInfo = notification.userInfo {

// do something neat here
}
}
}

return true
}

func subscribeToTopic() {
// If the app has a registration token and is connected to GCM, proceed to subscribe to the
// topic
if(registrationToken != "" && 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)");
}
})
}
}

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("reloadTableEvent", object: nil)
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)")
NSUserDefaults.standardUserDefaults().setValue(registrationToken, forKey: "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.
}

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

NSUserDefaults.standardUserDefaults().setBool(false, forKey: "APP_RUNNING")

// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.

GCMService.sharedInstance().disconnect()
// [START_EXCLUDE]
self.connectedToGCM = false
// [END_EXCLUDE]
}

func applicationWillEnterForeground(application: UIApplication) {

NSUserDefaults.standardUserDefaults().setBool(true, forKey: "APP_RUNNING")

// 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) {

NSUserDefaults.standardUserDefaults().setBool(true, forKey: "APP_RUNNING")

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

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

func applicationWillTerminate(application: UIApplication) {

NSUserDefaults.standardUserDefaults().setBool(false, forKey: "APP_RUNNING")

// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}

func application(application: UIApplication, didReceiveLocalNotification notification: UILocalNotification) {
if let userInfo = notification.userInfo {
NSNotificationCenter.defaultCenter().postNotificationName(
"LoadEventViewController", object: nil, userInfo: userInfo)
}
}




}

ViewController,弹出本地通知

func scheduleLocal(message: String) {
let settings = UIApplication.sharedApplication().currentUserNotificationSettings()

if settings!.types == .None {
let ac = UIAlertController(title: "Can't schedule", message: "Either we don't have permission to schedule notifications, or we haven't asked yet.", preferredStyle: .Alert)
ac.addAction(UIAlertAction(title: "OK", style: .Default, handler: nil))
presentViewController(ac, animated: true, completion: nil)
return
}

// create a corresponding local notification
let notification = UILocalNotification()
notification.alertBody = message // text that will be displayed in the notification
notification.alertAction = "open" // text that is displayed after "slide to..." on the lock screen - defaults to "slide to view"
notification.fireDate = NSDate(timeIntervalSinceNow: 0) // todo item due date (when notification will be fired)
notification.soundName = UILocalNotificationDefaultSoundName // play default sound
notification.userInfo = ["UUID": 1, ] // assign a unique identifier to the notification so that we can retrieve it later
notification.category = "TODO_CATEGORY"
UIApplication.sharedApplication().scheduleLocalNotification(notification)
}

我有两个问题,

  1. 是否可以在应用程序处于终止状态时接收和显示推送通知?如果是,怎么做?
  2. 我在代码中做错了什么吗?

最佳答案

这是您的推送通知 JSON?

aps: { "content-available" = 1; }

如果是,那么您正在发送静默推送。静默推送意味着用户不会收到任何视觉通知,只会调用您应用的应用委托(delegate)回调。删除内容可用标签并改为传递消息文本。

如果应用程序在前台,iOS 不会显示推送通知,而只是调用委托(delegate)。然后您可以显示警报 View 或您喜欢的其他内容。

或者你可以显示这个:https://github.com/avielg/AGPushNote

关于“由用户终止”的状态,这里是 Apple 文档(用于静默推送):

Apple documentation

Use this method to process incoming remote notifications for your app. Unlike the application:didReceiveRemoteNotification: method, which is called only when your app is running in the foreground, the system calls this method when your app is running in the foreground or background. In addition, if you enabled the remote notifications background mode, the system launches your app (or wakes it from the suspended state) and puts it in the background state when a remote notification arrives. However, the system does not automatically launch your app if the user has force-quit it. In that situation, the user must relaunch your app or restart the device before the system attempts to launch your app automatically again.

关于ios - 如何在应用程序未运行/应用程序终止时获取推送通知,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36195624/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com