> ## Documentation Index
> Fetch the complete documentation index at: https://docs.userpilot.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Updating to Swift Package Manager

> Migrate your Userpilot Flutter app from CocoaPods to Swift Package Manager, update iOS configuration, and handle existing app extensions.

The [Userpilot Flutter example](https://github.com/Userpilot/userpilot-flutter/tree/main/example) already uses Swift Package Manager (SPM). Follow these steps when updating an older copy of the example or a Flutter app that still uses CocoaPods.

Run the Flutter commands from your app directory (`example/` if you are using the Userpilot Flutter repository). Save your existing iOS project configuration before migrating so you can restore it if needed.

```sh theme={null}
flutter config --enable-swift-package-manager
flutter clean
flutter pub get
flutter run
```

Flutter 3.44 and later enable SPM by default. The configuration command above also enables it if you previously turned it off. See [Flutter's SPM guide for app developers](https://docs.flutter.dev/packages-and-plugins/swift-package-manager/for-app-developers).

During migration, you may see output such as:

```text theme={null}
Adding Swift Package Manager integration...
Running pod install...
```

Your Xcode project now has a `FlutterGeneratedPluginSwiftPackage` dependency. It includes `userpilot_flutter`, which installs the native Userpilot iOS SDK through its own `Package.swift`. You do not need to add the Userpilot package separately to the main app target.

Custom CocoaPods dependencies, including dependencies belonging to an app extension, may still need to be migrated manually. On another `flutter run`, you may see a notice like this:

```text theme={null}
All plugins found for ios are Swift Packages, but your project still has
CocoaPods integration. Your project uses a non-standard Podfile and will need to
be migrated to Swift Package Manager manually. Some steps you may need to
complete include:
  * In the ios/ directory run "pod deintegrate"
  * Transition any Pod dependencies to Swift Package equivalents. See
  https://developer.apple.com/documentation/xcode/adding-package-dependencies-to
  -your-app
  * Transition any custom logic
  * Remove the include to "Pods/Target Support
  Files/Pods-Runner/Pods-Runner.debug.xcconfig" in your
  ios/Flutter/Debug.xcconfig
  * Remove the include to "Pods/Target Support
  Files/Pods-Runner/Pods-Runner.release.xcconfig" in your
  ios/Flutter/Release.xcconfig

Removing CocoaPods integration will improve the project's build time.
```

## Removing CocoaPods integration

Before removing CocoaPods, confirm that every plugin and custom Pod dependency has an SPM equivalent, and transfer any custom build settings or scripts from your `Podfile`.

From your app directory:

```sh theme={null}
cd ios
pod deintegrate
rm -f Podfile Podfile.lock

# Remove CocoaPods xcconfig includes on macOS.
sed -i '' '/^[[:space:]]*#include.*Pods\//d' Flutter/Debug.xcconfig
sed -i '' '/^[[:space:]]*#include.*Pods\//d' Flutter/Release.xcconfig

open Runner.xcworkspace
```

Keep the `Generated.xcconfig` includes. Remove any remaining CocoaPods includes from custom configuration files as well. Delete the generated `ios/Pods/` and `ios/.symlinks/` directories if they remain.

In Xcode:

1. If you manually configure push notifications and still reference `SwiftUserpilotFlutterPlugin`, rename it to `UserpilotFlutterPlugin`. The compiler provides a rename diagnostic. See [Push Notifications](./push-notifications) for the current callbacks.
2. Remove any remaining reference to `Pods.xcodeproj` from the workspace.
3. Remove any remaining `Pods` group from the `Runner` project.
4. Confirm that `FlutterGeneratedPluginSwiftPackage` is linked to `Runner` and that its scheme includes the **Run Prepare Flutter Framework Script** build pre-action.
5. If your app has a notification service extension, migrate its dependencies as described below.

### Apps with a notification service extension

The Userpilot Flutter example has no notification service extension target. The Userpilot iOS 1.4.0 package exposes the `Userpilot` library and does not provide a separate notification service extension product. Skip this section for the standard example.

If your own app has an extension for another dependency:

1. Select **Runner > Project > Runner > Package Dependencies**.

2. Add that dependency's Swift package and assign its extension-compatible product to your notification service extension target, following the dependency's integration guide.

3. Keep the extension's build number aligned with the containing app. If Xcode reports a warning such as:

   ```text theme={null}
   The CFBundleVersion of an app extension (null) must match that of its containing parent app ('4.3.7').
   ```

   Set the extension's `Info.plist` value to:

   ```xml theme={null}
   <key>CFBundleVersion</key>
   <string>$(FLUTTER_BUILD_NUMBER)</string>
   ```

4. Under **Runner > Project > Runner > Info > Configurations**, set the extension's **Based on Configuration File** to the corresponding Flutter xcconfig for each build configuration. If the extension already has its own xcconfig, retain it and include the Flutter-generated settings there so `FLUTTER_BUILD_NUMBER` is defined.

Return to the app directory, then build and run:

```sh theme={null}
cd ..
flutter clean
flutter pub get
flutter run
```

## Going back to CocoaPods

From the app directory:

```sh theme={null}
flutter config --no-enable-swift-package-manager
flutter clean
```

Disabling SPM does not remove its Xcode integration. Follow [Flutter's SPM removal instructions](https://docs.flutter.dev/packages-and-plugins/swift-package-manager/for-app-developers#how-to-remove-swift-package-manager-integration) to remove the generated package reference, linked product, and build pre-action.

Restore your pre-migration `Podfile`, CocoaPods xcconfig includes, and any custom target configuration. Restore only the migration-related changes from version control, preserving other work. Then reinstall dependencies:

```sh theme={null}
flutter pub get
cd ios
pod install
cd ..
flutter run
```

## References

* [Swift Package Manager for Flutter app developers](https://docs.flutter.dev/packages-and-plugins/swift-package-manager/for-app-developers)
* [Swift Package Manager for Flutter plugin authors](https://docs.flutter.dev/packages-and-plugins/swift-package-manager/for-plugin-authors)
* [Adding package dependencies to your app in Xcode](https://developer.apple.com/documentation/xcode/adding-package-dependencies-to-your-app)
* [Userpilot Flutter package manifest](https://github.com/Userpilot/userpilot-flutter/blob/main/ios/userpilot_flutter/Package.swift)
* [Userpilot iOS 1.4.0 package manifest](https://github.com/Userpilot/ios-sdk/blob/1.4.0/Package.swift)
