我实施了这些过程,以便使用firebase云消息传递服务。我设置
firebaseappdelegateproxyenabled to no(deskling disabled(
我想通过使用" data "的结构来自定义发送消息以发送到设备,而不是" Notification "结构。我可以从调试输出中看到此回调中收到消息:
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any],
fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
// With swizzling disabled you must let Messaging know about the message, for Analytics
Messaging.messaging().appDidReceiveMessage(userInfo)
// Print message ID.
if let messageID = userInfo[gcmMessageIDKey] {
print("Message ID: (messageID)")
}
// Print full message.
print(userInfo)
// I want to play a sound
// create a sound ID, in this case its the SMSReceived sound.
let systemSoundID: SystemSoundID = 1007 // file:// /System/Library/Audio/UISounds/sms-received1.caf
// to play sound
AudioServicesPlaySystemSound(systemSoundID)
if let title = userInfo["title"] as? NSString {
let myalert = MyAlert(title: "New message received!", message: title as String, preferredStyle: UIAlertControllerStyle.alert)
myalert.addAction(UIAlertAction(title: "Cancel", style: UIAlertActionStyle.cancel, handler: nil))
myalert.addAction(UIAlertAction(title: "Open app", style: .default, handler: { _ in
print("The "OK" alert occured.")
}))
self.window?.rootViewController?.present(myalert, animated: true, completion: nil)
}// END if let title = alert["title"]
completionHandler(UIBackgroundFetchResult.newData)
}
在两种情况下(前后(都会提高。一切都在前景中完美无缺,但在背景中没有声音,也没有警报。我很确定我错过了一些东西,但我不明白什么...也许我需要操作系统的"授权"以显示,警报和播放声音?
编辑1:我实施了UnusernotificationCenterDelegate来申请:
func application(_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
FirebaseApp.configure()
// [START set_messaging_delegate]
Messaging.messaging().delegate = self
// [END set_messaging_delegate]
// Register for remote notifications. This shows a permission dialog on first run, to
// show the dialog at a more appropriate time move this registration accordingly.
// [START register_for_notifications]
if #available(iOS 10.0, *) {
// For iOS 10 display notification (sent via APNS)
UNUserNotificationCenter.current().delegate = self
let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound]
UNUserNotificationCenter.current().requestAuthorization(
options: authOptions,
completionHandler: {_, _ in })
} else {
let settings: UIUserNotificationSettings =
UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil)
application.registerUserNotificationSettings(settings)
}
application.registerForRemoteNotifications()
// [END register_for_notifications]
if launchOptions?[UIApplicationLaunchOptionsKey.remoteNotification] != nil {
// show alert
let myalert = MyAlert(title: "New message!", message: "MyApp" as String, preferredStyle: UIAlertControllerStyle.alert)
myalert.addAction(UIAlertAction(title: "Cancel", style: UIAlertActionStyle.cancel, handler: nil))
myalert.addAction(UIAlertAction(title: "Open MyApp", style: .default, handler: { _ in
print("The "OK" alert occured.")
}))
self.window?.rootViewController?.present(myalert, animated: true, completion: nil)
}
return true
}
解决!我使用了带有"通知"结构的内置系统,并启用了swizzling(info.plist中的FirebaseAppDelegateProxyEnabled = YES
(,这是我创建的JSON消息:
{
"message":
{
"topic":"topic",
"notification":
{
"body":"body",
"title":"title"
},
"apns":
{
"payload":
{
"aps":
{
"sound":"default"
}
}
}
}
}
这是我使用的AppDelegate.swift类...
import UIKit
import StoreKit
import UserNotifications
import Firebase
import AVFoundation
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate,UNUserNotificationCenterDelegate,MessagingDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
self.registerForRemoteNotification()
//Firebase initialization
FirebaseApp.configure()
// To receive registration tokens on app start we need to implement the messaging delegate protocol in
// a class and provide it to the delegate property after calling FirebaseApp.Configure
Messaging.messaging().delegate = self
let token = Messaging.messaging().fcmToken
print("FCM TOKEN = (String(describing: token))")
if let remote = launchOptions?[UIApplicationLaunchOptionsKey.remoteNotification] as? [AnyHashable : Any] {
self.sendToNewsPage()
}
return true
}
func application(_ application: UIApplication, didRegister notificationSettings: UIUserNotificationSettings) {
//
print("Application didRegister notificationSettings")
}
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
// Disable swizzling, explicitly map the APNs token to the FCM registration token.
//Messaging.messaging().apnsToken = deviceToken
Messaging.messaging().subscribe(toTopic: "topic")
print("Subcribed to topic")
}
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 invalidate graphics rendering callbacks. Games should use this method to pause the game.
}
func applicationDidEnterBackground(_ application: UIApplication) {
// 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.
}
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.
}
func applicationWillTerminate(_ application: UIApplication) {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
// MARK: Remote Notifications
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any]) {
#if DEBUG
print(userInfo)
#endif
let state: UIApplicationState = UIApplication.shared.applicationState
if state == .active {
// create a sound ID, in this case its the SMSReceived sound.
let systemSoundID: SystemSoundID = 1007
// to play sound
AudioServicesPlaySystemSound(systemSoundID)
if let aps = userInfo["aps"] as? NSDictionary {
if let alert = aps["alert"] as? NSDictionary {
if let title = alert["title"] as? NSString {
let myalert = MyAlert(title: "New message received!", message: title as String, preferredStyle: UIAlertControllerStyle.alert)
myalert.addAction(UIAlertAction(title: "Cancel", style: UIAlertActionStyle.cancel, handler: nil))
myalert.addAction(UIAlertAction(title: "Open ViewController", style: .default, handler: { _ in
print("The "OK" alert occured.")
self.sendToNewsPage()
}))
self.window?.rootViewController?.present(myalert, animated: true, completion: nil)
}// END if let title = alert["title"]
}// END if let alert = aps["alert"]
}// END if let aps = userInfo["aps"]
}// END else if state == .active
else {
self.sendToNewsPage()
}
}
func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String) {
print("Firebase NEW registration token: (fcmToken)")
// Note: This callback is fired at each app startup and whenever a new token is generated.
}
func messaging(_ messaging: Messaging, didRefreshRegistrationToken fcmToken: String) {
print("Firebase registration token REFRESH: (fcmToken)")
}
func registerForRemoteNotification() {
let application:UIApplication = UIApplication.shared
if #available(iOS 10.0, *) {
// For iOS 10 display notification (sent via APNS)
UNUserNotificationCenter.current().delegate = self
let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound]
UNUserNotificationCenter.current().requestAuthorization(
options: authOptions,
completionHandler: {_, _ in })
} else {
let settings: UIUserNotificationSettings =
UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil)
application.registerUserNotificationSettings(settings)
}
application.registerForRemoteNotifications()
}
// We need to implement this code only if swizzling id disabled - (FirebaseAppDelegateProxyEnabled = NO)
// @available(iOS 10.0, *)
// func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
//
// completionHandler([.alert, .badge, .sound])
// }
//
// @available(iOS 10.0, *)
// func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
//
// completionHandler()
// }
//MARK : Notification
func sendToNewsPage() {
let newsMessage = UIStoryboard(name: "MenuInfo", bundle: nil).instantiateViewController(withIdentifier: "SWRevealViewController")
self.window?.rootViewController = newsMessage
}
}
此JSON让通知在背景中播放声音!