Shachar
Shachar

Reputation: 127

Not receiving silent notifications while app is in the foreground

I have a flutter app using OneSignal notifications. The android app works perfectly.

The issue i have is in the native code of the IOS app. While the app is in the foreground it will receive non silent notifications from OneSignal and it handles them in the flutter code. This works well. I have written native ios code to receive silent notifications (as flutter doesnt receive them directly) and i will pass the notification to the flutter code.

Right now i do not receive any of the notifications in the native code (when app is in the foreground). I setup the project according to the instructions here

I checked the setting to enable background notifications. To bypass OneSignal I am sending notifications thru the APN console. This is my native code

AppDelegate.swift

import Flutter
import UIKit

@main
@objc class AppDelegate: FlutterAppDelegate {
    override func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
    ) -> Bool {
        print("**** didFinishLaunchingWithOptions ****");
        let center = UNUserNotificationCenter.current()
        center.requestAuthorization(options: [.alert, .badge, .sound]) { (granted, error) in
            if granted {
                DispatchQueue.main.async {
                    UIApplication.shared.registerForRemoteNotifications()
                }
            }
        }
        
        GeneratedPluginRegistrant.register(with: self)
        return super.application(application, didFinishLaunchingWithOptions: launchOptions)
    }

    override func application(
        _ application: UIApplication,
        didReceiveRemoteNotification userInfo: [AnyHashable: Any],
        fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void
    ) {
        print("**** didReceiveRemoteNotification ****");
               
        DispatchQueue.main.async {
                // Log or print messages here
                print("Received silent notification: \(userInfo)")
        }        
        // Process the silent notification
        if let aps = userInfo["aps"] as? [String: Any],
           aps["content-available"] as? Int == 1 {
            // Call Flutter through a method channel
            if let flutterViewController = window?.rootViewController as? FlutterViewController {
                let channel = FlutterMethodChannel(name: "com.shachardev.vivencia/notifications", binaryMessenger: flutterViewController.binaryMessenger)
                channel.invokeMethod("notificationReceived", arguments: userInfo)
            }
            completionHandler(.newData)
            return
        }

        completionHandler(.noData)
    }
}

NotificationService.swift

import UserNotifications
 
import OneSignal
 
class NotificationService: UNNotificationServiceExtension {
  
   var contentHandler: ((UNNotificationContent) -> Void)?
   var receivedRequest: UNNotificationRequest!
   var bestAttemptContent: UNMutableNotificationContent?
  
   override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
       self.receivedRequest = request
       self.contentHandler = contentHandler
       self.bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)
      
       if let bestAttemptContent = bestAttemptContent {         
           /* DEBUGGING: Uncomment the 2 lines below to check this extension is excuting
                         Note, this extension only runs when mutable-content is set
                         Setting an attachment or action buttons automatically adds this */
           OneSignal.setLogLevel(.LL_VERBOSE, visualLevel: .LL_NONE)
           print("Running NotificationServiceExtension")
           //bestAttemptContent.body = "[Modified] " + bestAttemptContent.body
          
           OneSignal.didReceiveNotificationExtensionRequest(self.receivedRequest, with: bestAttemptContent, withContentHandler: self.contentHandler)
       }
   }
  
   override func serviceExtensionTimeWillExpire() {
       // Called just before the extension will be terminated by the system.
       // Use this as an opportunity to deliver your "best attempt" at modified content, otherwise the original push payload will be used.
       if let contentHandler = contentHandler, let bestAttemptContent =  bestAttemptContent {
           OneSignal.serviceExtensionTimeWillExpireRequest(self.receivedRequest, with: self.bestAttemptContent)
           contentHandler(bestAttemptContent)
       }
   }
  
}

My expectation is that the native code will receive all notifications while app is in the foreground and i should be able to see the print messages in the console.

Upvotes: 0

Views: 61

Answers (0)

Related Questions