Skip to content

CioAppDelegateWrapper breaks Flutter addApplicationDelegate method #315

@devgianlu

Description

@devgianlu

SDK version: 3.2.2

Environment: Any

Are logs available?
Not applicable

Describe the bug
When using CioAppDelegateWrapper in iOS, UIApplication.shared.delegate will return an instance of said wrapper which does not conform to FlutterAppLifeCycleProvider, effectively short-circuiting the addApplicationDelegate method. See here.

The result is that application delegates are never added inside the Flutter engine and therefore break that feature completely.

To Reproduce

  1. Use CioAppDelegateWrapper as main:
import CioFirebaseWrapper
import CioMessagingPushFCM
import Flutter
import UIKit

@main
class AppDelegateWrapper: CioAppDelegateWrapper<AppDelegate> {}

@objc class AppDelegate: FlutterAppDelegate {
  override func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
  ) -> Bool {
    GeneratedPluginRegistrant.register(with: self)
    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
  }
}
  1. Write a plugin that uses addApplicationDelegate:
import Flutter
import UIKit

public class SomePlugin: NSObject, FlutterPlugin, UIApplicationDelegate {
    public static func register(with registrar: FlutterPluginRegistrar) {
        let instance = SomePlugin.init()
        registrar.addApplicationDelegate(instance)
    }

    public func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
        return doThingsWhenThisIsCalled()
    }
}
  1. Run the app and cause a deep link to be received, doThingsWhenThisIsCalled is never reached.

Expected behavior
The CioAppDelegateWrapper does not disrupt the normal functionality of Flutter.

I was able to fix this issue like this:

class AppDelegateWrapper: CioAppDelegateWrapper<AppDelegate>, FlutterAppLifeCycleProvider {
  func add(_ delegate: any FlutterApplicationLifeCycleDelegate) {
    let selector = NSSelectorFromString("addApplicationLifeCycleDelegate:")
    if let target = forwardingTarget(for: selector) as? NSObject, target.responds(to: selector) {
      _ = target.perform(selector, with: delegate)
    }
  }
}

Screenshots
Not applicable

Additional context
None

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions