WebEngage/webengage-flutter

Redundant conformance of 'AppDelegate' to protocol 'UNUserNotificationCenterDelegate' in iOS

Opened this issue · 13 comments

Use case: When clicking on notification in iOS, app opens and I should be able to read payload data so that I can perform various actions upon opening the app like re-route, etc.

For this use case I have followed iOS notification setup provided by WebEngage.
This includes
calbacks for ios - https://docs.webengage.com/docs/flutter-callbacks#for-ios
disable swizzling - https://docs.webengage.com/docs/ios-advanced#7-disable-swizzling

my info.plist has -
<key>WEGLicenseCode</key> <string>xxxxx</string> <key>WEGLogLevel</key> <string>VERBOSE</string> <key>WEGEnvironment</key> <string>xx</string> <key>WEGManualIntegration</key> <true/>

appdelegate.swift file -

import UIKit
import Flutter
import flutter_local_notifications
import WebEngage
import webengage_flutter

@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
  var bridge:WebEngagePlugin? = nil
  override func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
  ) -> Bool {
    

FlutterLocalNotificationsPlugin.setPluginRegistrantCallback { (registry) in
        GeneratedPluginRegistrant.register(with: registry)
    }
var bridge = WebEngagePlugin()
// for push notif payload fetch callback
    WebEngage.sharedInstance().pushNotificationDelegate = self.bridge
// init weg sdk
WebEngage.sharedInstance().application(application, didFinishLaunchingWithOptions: launchOptions)

if #available(iOS 10.0, *) {
          UNUserNotificationCenter.current().delegate = self as? UNUserNotificationCenterDelegate
        }
        }

    GeneratedPluginRegistrant.register(with: self)
    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
  }
}

extension AppDelegate: UNUserNotificationCenterDelegate {

    @available(iOS 10.0, *)
    override func userNotificationCenter(_ center: UNUserNotificationCenter,
                                willPresent notification: UNNotification,
                                withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {

        print("center: ", center, "\nnotification: ", notification)
        WEGManualIntegration.userNotificationCenter(center, willPresent: notification)
        //Handle any other services messages with method swizzling disabled
        // example : firebase 
        //Messaging.messaging().appDidReceiveMessage(userInfo)
        completionHandler([.alert, .badge, .sound])
    }

    @available(iOS 10.0, *)
    override func userNotificationCenter(_ center: UNUserNotificationCenter,
                                didReceive response: UNNotificationResponse,
                                withCompletionHandler completionHandler: @escaping () -> Void) {

        print("center: ", center, " response: ", response)
        WEGManualIntegration.userNotificationCenter(center, didReceive: response)
        //Handle any other services messages with method swizzling disabled
        // example : firebase 
        //Messaging.messaging().appDidReceiveMessage(userInfo)
        completionHandler()
    }
}

but upon trying to build in simulator i get -

Swift Compiler Error (Xcode): Redundant conformance of 'AppDelegate' to protocol 'UNUserNotificationCenterDelegate'
/path/project_name/ios/Runner/AppDelegate.swift:33:23

Could not build the application for the simulator.
Error launching application on iPhone 14 Pro Max.

@yashpalzala
Please remove the declaration of conformance to the UNUserNotificationCenterDelegate protocol from line 33 of the AppDelegate class. Instead, utilize an extension to declare conformance, as demonstrated below:


extension AppDelegate {
    // Your code here
}

Hi @MilindWebEngage , This above solution resolved the issue but still not able to redirect the user on notification click.
Actions done -

  1. calbacks for ios - https://docs.webengage.com/docs/flutter-callbacks#for-ios
  2. disable swizzling - https://docs.webengage.com/docs/ios-advanced#7-disable-swizzling
  3. Manual Integration in info.plist file. -
<key>WEGManualIntegration</key>
	<true/>
  1. Implmentation of pushStream on flutter side (this same code works on android so doubt if any issues on flutter side)
  2. Also mentioned key-valu pair acc. to doc for ios - https://docs.webengage.com/docs/ios-customizing-push-notifications#setting-key-value-pairs
Screenshot 2024-03-06 at 12 36 56 PM

Hi @yashpalzala , are you receiving the callbacks in the function below upon clicking the Push Notification?

` _webEngagePlugin.pushStream.listen((event) {
//here
});

_webEngagePlugin.pushActionStream.listen((event) {
//here
}); `

Also, try adding logs or toasts and check in all three states - Foreground, Background, and Killed.
Please let us know in which state you are not receiving the callback.
Docs Link

@MilindWebEngage nope not receiving any callbacks in

_webEngagePlugin.pushStream.listen((event) {
//here
});

Added toast in pushStream.listen but can't see the toast in Foreground, Background, and Killed state.

@yashpalzala Could you please share the AppDelegate file? Please hide your code by typing // your code, and include only the WebEngage Code before sharing the file.

@MilindWebEngage
I have already shared it above in the first message. Is there anything missing in that? Let me know if you want me to reshare or something.
It's standard code that comes with every flutter app there's no custom code as such.

@yashpalzala In your above file, there is an exact curly bracket:
if #available(iOS 10.0, *) {
UNUserNotificationCenter.current().delegate = self as? UNUserNotificationCenterDelegate
}
}

So, try to open the project in Xcode and check if there are any other issues in the file.

If you have any queries then you can reach out to us on support@webengage.com.

@MilindWebEngage
that is fixed, project wouldn't build if that was the case.
Screenshot 2024-03-07 at 12 33 10 PM

@yashpalzala Please create a ticket on support@webengage.com so that we can connect and figure out the problem.

@yashpalzala Hey, did you find any solution. I'm facing the same issue.

@Pranit1804 Can you tell which issue you are encountering? Is it related to the redundant conformance of 'AppDelegate' to the protocol 'UNUserNotificationCenterDelegate', or to redirecting the user on notification click?

Hi @MilindWebEngage It is redirecting the user on notification click.

@Pranit1804

  1. Check if you are not getting the callbacks in the push callback function mentioned in the documentation below, in which state (foreground, background, or killed) you are. Link to documentation.

  2. Upon clicking on a WebEngage push notification, you should receive a callback on either the pushStream or pushActionStream function mentioned in the link above.

  3. If you are not getting callbacks in all three states, that means the push notification on which you are clicking is displayed by Firebase and not by WebEngage.

  4. To fix the above scenario, you need to disable Swizzling for both WebEngage and Firebase so that the push can be displayed by the correct plugin.

WebEngage Disable Swizzling docs - Link
Firebase Disable Swizzling docs - Link
Below is a sample app delegate file(swift file in txt format).
AppDelegate.txt

  1. It is recommended to add a toast on the click function so that you can check in the killed state if you are receiving callbacks or not.

  2. Note: If after receiving the callback in the WebEngage function, redirection is not happening, then you need to investigate this issue, as redirection is handled by your team.

  3. If, after following the above steps, you are still not receiving the callback, then you can create a ticket at support@webengage.com so that we can connect and figure out the problem.