Cannot Use Plugins In Flutter IOS Share Extension: 'GeneratedPluginRegistrant' Not Found

by ADMIN 89 views

Cannot use plugins in Flutter iOS Share Extension: 'GeneratedPluginRegistrant' not found

Introduction

When developing a Flutter application that includes an iOS Share Extension, integrating Flutter UI is a straightforward process. However, when attempting to use a Flutter plugin within the Share Extension, you may encounter the error 'GeneratedPluginRegistrant' not found. This issue arises due to the lack of automatic generation of the GeneratedPluginRegistrant files in the Share Extension target.

Steps to Reproduce

To reproduce this issue, follow these steps:

  1. Create a Flutter project: Start by creating a new Flutter project using the command flutter create my_app.
  2. Add an iOS Share Extension target in Xcode: Open the project in Xcode and follow the steps in the official Flutter documentation to add an iOS Share Extension target.
  3. Integrate Flutter into the Share Extension: Initialize a FlutterEngine and embed a FlutterViewController in the Share Extension.
  4. Attempt to use a Flutter plugin: Try to use a Flutter plugin, such as path_provider, within the Share Extension.

Expected Results

The Share Extension should be able to utilize Flutter plugins without encountering the 'GeneratedPluginRegistrant' error.

Actual Results

The build fails with the error:

Launching lib/main.dart on iPhone 16 Pro in debug mode...
Updating project for Xcode compatibility.
Upgrading project.pbxproj
Upgrading Runner.xcscheme
Xcode build done.                                            6.6s
Failed to build iOS app
Swift Compiler Error (Xcode): Cannot find 'GeneratedPluginRegistrant' in scope
/Users/ghilan/Development/Lab/ios_share_extension/ios/PixelBookmarksShare/ShareViewController.swift:24:12

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

Exited (1).

Code Sample

Here is the code of the extension ShareViewController.swift that should run Flutter engine and register plugins if GeneratedPluginRegistrant was exists without issues:

//
//  ShareViewController.swift
//  PixelBookmarksShare
//
//  Created by Ghilan on 03/05/2025.
//
import UIKit
import Flutter


@objc(ShareViewController)
class ShareViewController: UIViewController {
    private var flutterEngine: FlutterEngine?

    override func viewDidLoad() {
        super.viewDidLoad()
        launchFlutter()
    }

    func launchFlutter() {
        flutterEngine = FlutterEngine(name: "share_extension_engine")
        
        if let engine = flutterEngine {
            engine.run(withEntrypoint: "shareExtensionEntrypoint")
            GeneratedPluginRegistrant.register(with: engine)

            let flutterViewController = FlutterViewController(engine: engine, nibName: nil, bundle: nil)
            addChild(flutterViewController)
            view.addSubview(flutterViewController.view)
            flutterViewController.view.frame = view.bounds
            flutterViewController.didMove(toParent: self)
        } else {
            // Handle the case where flutterEngine is nil
            print("Failed to initialize FlutterEngine.")
        }
    }


    override func viewDidDisappear(_ animated: Bool) {
        super.viewDidDisappear(animated)
        self.extensionContext?.cancelRequest(
            withError: NSError(domain: Bundle.main.bundleIdentifier ?? "com.example.share code: 0, userInfo: nil))
    }
}

Flutter Doctor Output

Here is the output of flutter doctor:

ghilan@Mac ~ % flutter doctor
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 3.29.3, on macOS 15.3.1 24D70 darwin-arm64, locale
    en-YE)
[✓] Android toolchain - develop for Android devices (Android SDK version 35.0.1)
[✓] Xcode - develop for iOS and macOS (Xcode 16.2)
[✓] Chrome - develop for the web
[✓] Android Studio (version 2024.2)
[✓] VS Code (version 1.99.3)
[✓] Connected device (4 available)
[✓] Network resources

• No issues found!

Solution

To resolve this issue, you need to manually generate the GeneratedPluginRegistrant files in the Share Extension target. You can do this by adding the following code to the Info.plist file of the Share Extension target:

<key>FlutterPluginRegistrant</key>
<string>GeneratedPluginRegistrant</string>

Additionally, you need to add the following code to the ShareViewController.swift file:

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    GeneratedPluginRegistrant.register(with: FlutterEngine(name: "share_extension_engine"))
    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}

By following these steps, you should be able to use Flutter plugins within the Share Extension without encountering the 'GeneratedPluginRegistrant' error.
Cannot use plugins in Flutter iOS Share Extension: 'GeneratedPluginRegistrant' not found

Q&A

Q: What is the 'GeneratedPluginRegistrant' error?

A: The 'GeneratedPluginRegistrant' error occurs when the Flutter engine is unable to find the GeneratedPluginRegistrant file, which is responsible for registering plugins in the Flutter app.

Q: Why is the 'GeneratedPluginRegistrant' file not generated automatically in the Share Extension target?

A: The GeneratedPluginRegistrant file is not generated automatically in the Share Extension target because the Share Extension is a separate target from the main app, and the plugin registration process is not triggered automatically in this target.

Q: How can I manually generate the 'GeneratedPluginRegistrant' file in the Share Extension target?

A: To manually generate the GeneratedPluginRegistrant file in the Share Extension target, you need to add the following code to the Info.plist file of the Share Extension target:

<key>FlutterPluginRegistrant</key>
<string>GeneratedPluginRegistrant</string>

Additionally, you need to add the following code to the ShareViewController.swift file:

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    GeneratedPluginRegistrant.register(with: FlutterEngine(name: "share_extension_engine"))
    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}

Q: What are the benefits of manually generating the 'GeneratedPluginRegistrant' file?

A: Manually generating the GeneratedPluginRegistrant file allows you to control the plugin registration process in the Share Extension target, which can be useful in certain scenarios where the automatic plugin registration process is not sufficient.

Q: Are there any potential drawbacks to manually generating the 'GeneratedPluginRegistrant' file?

A: Yes, manually generating the GeneratedPluginRegistrant file can lead to additional complexity in the plugin registration process, which can make it more difficult to manage and maintain the plugins in the Share Extension target.

Q: How can I troubleshoot the 'GeneratedPluginRegistrant' error?

A: To troubleshoot the 'GeneratedPluginRegistrant' error, you can try the following steps:

  1. Check the Info.plist file of the Share Extension target to ensure that the FlutterPluginRegistrant key is present and correctly configured.
  2. Verify that the GeneratedPluginRegistrant file is present in the Share Extension target and that it is correctly registered with the Flutter engine.
  3. Check the console output for any error messages related to the plugin registration process.
  4. Try to reproduce the error by running the Share Extension target in a simulator or on a physical device.

Q: Can I use the 'GeneratedPluginRegistrant' file in the main app target as well?

A: Yes, you can use the GeneratedPluginRegistrant file in the main app target as well. However, you need to ensure that the plugin registration process is correctly configured in the main app target to avoid any conflicts with the plugin registration process in the Share Extension target.

**Q: Are there any best practices for using the 'GeneratedPluginRegistrant' file in the Share Extension target?A: Yes, here are some best practices for using the GeneratedPluginRegistrant file in the Share Extension target:

  1. Ensure that the FlutterPluginRegistrant key is present and correctly configured in the Info.plist file of the Share Extension target.
  2. Verify that the GeneratedPluginRegistrant file is present in the Share Extension target and that it is correctly registered with the Flutter engine.
  3. Use the GeneratedPluginRegistrant file in conjunction with the FlutterEngine class to ensure that the plugin registration process is correctly configured.
  4. Test the Share Extension target thoroughly to ensure that the plugin registration process is working correctly.