-
Notifications
You must be signed in to change notification settings - Fork 59
Add Swift Package Manager (SPM) support for Flutter-SDK #356
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: feat/release_4.2.0
Are you sure you want to change the base?
Changes from 12 commits
b3d30e8
2a7a415
5d96862
203c1e3
b91d176
c0b7ecf
dfd2cf9
52d2d8e
a7c16ee
8751ec8
9e9fdf6
74ecaa9
c22b0dc
8230f92
8922ed1
7fa5ea4
25a953a
c021559
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,104 @@ | ||
| ## 📦 iOS Integration via Swift Package Manager (SPM) | ||
|
|
||
| Starting from Flutter 3.27, Flutter supports resolving plugin dependencies via Swift Package Manager in addition to CocoaPods. The CleverTap Flutter plugin ships a `Package.swift` alongside its podspec, so both package managers resolve the same native SDK version (`CleverTap-iOS-SDK 7.7.1`). | ||
|
|
||
| > **Minimum requirements** | ||
| > - Flutter 3.27+ | ||
| > - Xcode 15+ | ||
| > - iOS deployment target: 13.0+ | ||
|
|
||
| --- | ||
|
|
||
| ### How it works | ||
|
|
||
| Flutter's SPM support detects plugins that declare a `swiftPackageName` in their `pubspec.yaml`. The CleverTap plugin sets: | ||
|
|
||
| ```yaml | ||
| # pubspec.yaml (inside the plugin) | ||
| ios: | ||
| pluginClass: CleverTapPlugin | ||
| swiftPackageName: clevertap_plugin | ||
| ``` | ||
|
|
||
| Flutter then looks for a `Package.swift` under `ios/<swiftPackageName>/` (`ios/clevertap_plugin/Package.swift`). That manifest pins the CleverTap iOS SDK: | ||
|
|
||
| ```swift | ||
| .package( | ||
| url: "https://github.com/CleverTap/clevertap-ios-sdk", | ||
| exact: "7.7.1" | ||
| ) | ||
| ``` | ||
|
|
||
| When your app is built, Flutter resolves this package automatically — no manual entry in `Package.swift` of your app is required. | ||
|
|
||
| --- | ||
|
|
||
| ### Enabling SPM in your Flutter app | ||
|
|
||
| SPM support in Flutter is opt-in. Enable it by setting the `FLTEnableSwiftPackageManagerIntegration` flag in your iOS app's `Info.plist`: | ||
|
|
||
| ```xml | ||
| <key>FLTEnableSwiftPackageManagerIntegration</key> | ||
| <true/> | ||
| ``` | ||
|
|
||
| Or via the Flutter CLI environment variable when running or building: | ||
|
|
||
| ```bash | ||
| flutter run --enable-swift-package-manager | ||
| flutter build ios --enable-swift-package-manager | ||
| ``` | ||
|
|
||
| After enabling, run `flutter pub get` and then open your `.xcworkspace` in Xcode. Xcode will resolve the CleverTap iOS SDK via SPM automatically. | ||
|
|
||
| --- | ||
|
|
||
| ### AppDelegate changes when using SPM | ||
|
|
||
| When Flutter resolves the plugin via SPM, the module name changes. Use conditional imports in your `AppDelegate` to support both CocoaPods and SPM builds: | ||
|
|
||
| ###### Objective-C | ||
|
coderabbitai[bot] marked this conversation as resolved.
Outdated
|
||
|
|
||
| ```objc | ||
| #if __has_include(<CleverTapSDK/CleverTap.h>) | ||
| #import <CleverTapSDK/CleverTap.h> | ||
| #else | ||
| #import "CleverTap.h" | ||
| #endif | ||
|
|
||
| #if __has_include(<clevertap_plugin/CleverTapPlugin.h>) | ||
| #import <clevertap_plugin/CleverTapPlugin.h> | ||
| #else | ||
| #import "CleverTapPlugin.h" | ||
| #endif | ||
| ``` | ||
|
|
||
| ###### Swift | ||
|
|
||
| ```swift | ||
| import CleverTapSDK | ||
| import clevertap_plugin | ||
| ``` | ||
|
|
||
| These guards ensure your app compiles correctly regardless of which package manager resolved the dependency. | ||
|
|
||
| --- | ||
|
|
||
| ### CocoaPods vs SPM | ||
|
|
||
| | | CocoaPods | SPM | | ||
| |---|---|---| | ||
| | Config file | `ios/clevertap_plugin.podspec` | `ios/clevertap_plugin/Package.swift` | | ||
| | SDK version pinned | `7.7.1` | `7.7.1` | | ||
| | Deployment target | `13.0` | `13.0` | | ||
|
reshab-code marked this conversation as resolved.
Outdated
|
||
| | Opt-in required | No (default) | Yes (see above) | | ||
|
|
||
| Both package managers resolve the same CleverTap iOS SDK version to ensure no drift between the two integration paths. | ||
|
|
||
| --- | ||
|
|
||
| ### Troubleshooting | ||
|
|
||
| - **Xcode doesn't resolve the package**: Run `flutter pub get`, then in Xcode go to **File → Packages → Resolve Package Versions**. | ||
| - **Duplicate symbol errors**: Ensure you are not using both CocoaPods and SPM for the same plugin simultaneously. If you have a `Podfile` and SPM enabled, Flutter will prefer SPM for plugins that support it. | ||
| - **Build fails with missing headers**: Verify your deployment target is set to `13.0` or higher in both your Xcode project and `Podfile`/`Package.swift`. | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| // swift-tools-version: 5.9 | ||
| import PackageDescription | ||
|
|
||
| let package = Package( | ||
| name: "clevertap_plugin", | ||
| platforms: [ | ||
| .iOS("13.0") | ||
| ], | ||
| products: [ | ||
| .library(name: "clevertap-plugin", targets: ["clevertap_plugin"]) | ||
| ], | ||
| dependencies: [ | ||
| .package( | ||
| url: "https://github.com/CleverTap/clevertap-ios-sdk", | ||
| exact: "7.7.1" | ||
|
reshab-code marked this conversation as resolved.
Outdated
|
||
| ) | ||
| ], | ||
| targets: [ | ||
| .target( | ||
| name: "clevertap_plugin", | ||
| dependencies: [ | ||
| .product(name: "CleverTapSDK", package: "clevertap-ios-sdk") | ||
| ], | ||
| publicHeadersPath: "include/clevertap_plugin", | ||
|
reshab-code marked this conversation as resolved.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why is publicHeadersPath added even if not stated in flutter docs? Is it needed? Have you tested this on sample app?
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. publicHeadersPath is required for Objective-C targets in SPM as iit tells the package manager where the public headers are so it can generate a module map. The headers physically live at Sources/clevertap_plugin/include/clevertap_plugin/ and the path "include/clevertap_plugin" is relative to that sources dir. Without it, ObjC imports would break. It was tested and verified in the example app with SPM enabled. |
||
| cSettings: [ | ||
| .headerSearchPath("include/clevertap_plugin") | ||
| ] | ||
| ) | ||
| ] | ||
| ) | ||
Uh oh!
There was an error while loading. Please reload this page.