I implemented the procedures in order to use Firebase Cloud Messaging service. I set
FirebaseAppDelegateProxyEnabled to NO (swizzling disabled)
because I want to customize the message to send to the device by using the structure "data" instead of "notification" structure. I can see from the debug output that a message is received in this callback:
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)
}
It raises in both cases (fore and back). Everything goes perfectly in foreground but no sound and no alert in background. I am pretty sure I missed something but I cannot understand what... Maybe I need some "authorization" from the operating system to display and alert and play sound?
EDIT 1: I implemented the UNUserNotificationCenterDelegate to requestAuthorization:
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
}