How do I register a "specific plug-in" with Workmanager in my AppDelegate.swift?

Viewed 1248

I have been following the Flutter Workmanager iOS setup and at the bottom of the page they show how to use plug-ins with the Workmanager for background tasks.

I have this exact code in my AppDelegate.swift:

class AppDelegate: FlutterAppDelegate {
    /// Registers all pubspec-referenced Flutter plugins in the given registry.  
    static func registerPlugins(with registry: FlutterPluginRegistry) {
            GeneratedPluginRegistrant.register(with: registry)
    }
    
    override func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        
        // ... Initialization code
        
        AppDelegate.registerPlugins(with: self) // Register the app's plugins in the context of a normal run
        
        WorkmanagerPlugin.setPluginRegistrantCallback { registry in  
            // The following code will be called upon WorkmanagerPlugin's registration.
            // Note : all of the app's plugins may not be required in this context ;
            // instead of using GeneratedPluginRegistrant.register(with: registry),
            // you may want to register only specific plugins.
            AppDelegate.registerPlugins(with: registry)
        }
    }
}

Their comment at the end implies that I can register specific plugins, which I want to do instead of loading every plug-in that I have installed.

I have tried to do something within the .setPluginRegistrantCallback brackets like:

GeolocatorPlugin.register(with: registry.registrar(forPlugin: "GeolocatorPlugin"))

but this doesn't seem to work since the Workmanager keeps returning with a failed result after I simulate a background fetch in xCode:

[<workmanager.SwiftWorkmanagerPlugin: 0x600003b5b060>] application(_:performFetchWithCompletionHandler:) -> UIBackgroundFetchResult.failed (finished in 0.24 seconds)

If someone could help me register a specific plug-in, like Geolocator or anything else, that would be great. Instead of registering all the plug-ins through the GeneratedPluginRegistrant.

1 Answers

I figured out my own answer after a couple days in case anyone needs a solution.

In order to register a specific plugin to the Workmanager you need to find the "fully qualified name" of the plugin. You can see the description of the parameters for plugin registration here.

In order to find the fully qualified name, visit your Android's GeneratedPluginRegistrant.java where you'll see a handful of registrations to the Flutter Engine. This is what it'll look like:

flutterEngine.getPlugins().add(new io.flutter.plugins.googlemaps.GoogleMapsPlugin());
flutterEngine.getPlugins().add(new vn.hunghd.flutter.plugins.imagecropper.ImageCropperPlugin());
flutterEngine.getPlugins().add(new io.flutter.plugins.imagepicker.ImagePickerPlugin());
flutterEngine.getPlugins().add(new com.baseflow.location_permissions.LocationPermissionsPlugin());

There could be more or less depending on how many plugins you have. However, these parts: io.flutter.plugins.firebaseadmob.FirebaseAdMobPlugin or vn.hunghd.flutter.plugins.imagecropper.ImageCropperPlugin are the fully qualified name that you will use to register specific plugins on iOS.

Then, in the AppDelegate.swift file, within the Workmanager.setPluginRegistrantCallback brackets you can add the plugins like so:

WorkmanagerPlugin.setPluginRegistrantCallback { registry in  
        GeolocatorPlugin.register(with: registry.registrar(forPlugin: "
        com.baseflow.geolocator.GeolocatorPlugin"))
        
        LocationPermissionsPlugin.register(with: registry.registrar(forPlugin: "
        com.baseflow.location_permissions.LocationPermissionsPlugin"))
        
        FLTCloudFirestorePlugin.register(with: registry.registrar(forPlugin: "
        io.flutter.plguins.firebase.cloudfirestore.CloudFirestorePlugin"))
    }

This will register those specific plugins to the Dart Isolate that runs in the background so that you can use a Geolocator or query a Database while the app is hidden. Basically whatever you want to run within the Workmanager isolate or your own Dart isolate on iOS.

Be sure to include import statements for your plugins and the Workmanager itself at the top of the AppDelegate.swift file. Here is what mine looks like with those 3 plugins:

import UIKit
import Flutter
import GoogleMaps
import workmanager
import location_permissions
import geolocator
Related