Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion doc/Installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ This will download the AppsFlyer flutter plugin to your project, you may observe

Starting with v6.18.0, the plugin's **Core** integration supports Swift Package Manager on iOS, alongside continued full CocoaPods support. If your app has SPM enabled (the default on Flutter 3.44+, or via `flutter config --enable-swift-package-manager` on Flutter 3.24+), no extra setup is needed — Flutter's tooling picks up the plugin's `Package.swift` automatically.

**Purchase Connector is CocoaPods-only.** If your app uses the [Purchase Connector](PurchaseConnector.md), it must stay on CocoaPods for now — there is no SPM opt-in path for it yet, pending resolution of an upstream Flutter limitation ([flutter/flutter#161182](https://github.com/flutter/flutter/issues/161182)). Apps that need both SPM (for Core) and Purchase Connector (via CocoaPods) can use both simultaneously; Flutter's tooling handles this automatically as long as your `Podfile` still exists.
**If you use Purchase Connector, do not enable SPM for this plugin.** [Purchase Connector](PurchaseConnector.md) requires CocoaPods for the entire plugin (Core included) — it cannot currently be combined with SPM, pending resolution of an upstream Flutter limitation ([flutter/flutter#161182](https://github.com/flutter/flutter/issues/161182)). SPM is recommended only for apps that don't use Purchase Connector at all; if you don't, keep CocoaPods and the `$AppsFlyerPurchaseConnector` Podfile flag as documented in [PurchaseConnector.md](PurchaseConnector.md).

---
## Huawei Referrer
Expand Down
2 changes: 1 addition & 1 deletion doc/PurchaseConnector.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ appsflyer.enable_purchase_connector=true
```
Once you set these properties, the Purchase Validation feature will be integrated into your project and you can utilize its functionality in your app.

> ⚠️ **iOS + Swift Package Manager**: Purchase Connector requires **CocoaPods** — there is no Swift Package Manager opt-in path for it. This is a temporary limitation pending an upstream Flutter fix ([flutter/flutter#161182](https://github.com/flutter/flutter/issues/161182)). If your app has adopted SPM for the Core integration (see [Installation.md](Installation.md#ios-swift-package-manager-spm-support)), keep your `Podfile` in place and set `$AppsFlyerPurchaseConnector = true` there as above — Flutter's tooling will use SPM for Core and CocoaPods for Purchase Connector at the same time. If you skip the Podfile entirely (SPM-only), calling any Purchase Connector API will silently fail with a `MissingPluginException` — see the next section.
> ⚠️ **iOS + Swift Package Manager**: Purchase Connector requires **CocoaPods for the entire plugin** — there is no Swift Package Manager path for it, and it cannot currently be combined with Swift Package Manager for the Core integration either. This is a temporary limitation pending an upstream Flutter fix ([flutter/flutter#161182](https://github.com/flutter/flutter/issues/161182)). **If your app uses Purchase Connector, do not enable Swift Package Manager for this plugin — keep your `Podfile` and use CocoaPods for both Core and Purchase Connector.** If you enable SPM anyway, calling any Purchase Connector API will silently fail with a `MissingPluginException` — see the next section. SPM is only recommended for apps that don't use Purchase Connector at all (see [Installation.md](Installation.md#ios-swift-package-manager-spm-support)).

### What Happens if You Use Dart Files Without Opting In?

Expand Down
12 changes: 6 additions & 6 deletions internal-docs/features/F-060-swift-package-manager-support.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,20 +76,20 @@ No dedicated automated test — this is a build-configuration/distribution-mecha
- `swift package describe` — genuine dependency resolution against the live `AppsFlyerFramework` GitHub repository, confirming the manifest resolves product `AppsFlyerLib` at `Exact: 6.18.0` (corrected from an earlier `from:` range pin during review — see Known Limitations) and picks up all 3 Core `.m` sources correctly.
- `pod spec lint --quick --allow-warnings` — passed, confirming the podspec's repointed `source_files`/`public_header_files` globs resolve correctly against the moved tree.
- `flutter test test` — all 38 existing Dart tests pass unaffected (this change touches only iOS native file locations and build manifests, not Dart code).
- **Real-device iOS E2E, dispatched via GitHub Actions with real credentials, 3 of the tech design's 4 combinations — all 6 scenario phases PASS in each:**
- SPM, Core only, `.exact("6.18.0")` pin — [run 30191649705](https://github.com/AppsFlyerSDK/appsflyer-flutter-plugin/actions/runs/30191649705). `getSDKVersion` confirmed resolving `6.18.0`, not a drifted patch release (an earlier run against the pre-fix `from:` pin had resolved `6.18.1` — see Known Limitations).
- Hybrid: SPM Core + CocoaPods PurchaseConnector simultaneously (realistic config for an app that wants both) — [run 29848672331](https://github.com/AppsFlyerSDK/appsflyer-flutter-plugin/actions/runs/29848672331).
- Pure CocoaPods, Core + PurchaseConnector, SPM explicitly disabled — [run 29901950273](https://github.com/AppsFlyerSDK/appsflyer-flutter-plugin/actions/runs/29901950273).
- **Real-device iOS E2E, dispatched via GitHub Actions with real credentials — all 6 scenario phases PASS in each:**
- SPM, Core only, `.exact("6.18.0")` pin — [run 30191649705](https://github.com/AppsFlyerSDK/appsflyer-flutter-plugin/actions/runs/30191649705). `getSDKVersion` confirmed resolving `6.18.0`, not a drifted patch release (an earlier run against the pre-fix `from:` pin had resolved `6.18.1` — see Known Limitations). **This is the only SPM configuration we recommend or support.**
- Pure CocoaPods, Core + PurchaseConnector, SPM explicitly disabled — [run 29901950273](https://github.com/AppsFlyerSDK/appsflyer-flutter-plugin/actions/runs/29901950273). **This is the only supported configuration for apps using Purchase Connector.**
- SPM Core + CocoaPods PurchaseConnector configured simultaneously — [run 29848672331](https://github.com/AppsFlyerSDK/appsflyer-flutter-plugin/actions/runs/29848672331). This run only demonstrates the app builds and links without a crash when both are configured at once (no duplicate-symbol failure) — it does **not** demonstrate Purchase Connector actually functions in this configuration, and CI's own logs suggest Flutter's tooling may silently drop the CocoaPods `PurchaseConnector` pod entirely once it detects the plugin has a `Package.swift`. **This combination is explicitly not supported or recommended** — see doc/Installation.md and doc/PurchaseConnector.md, both updated to state that apps using Purchase Connector must not enable SPM for this plugin at all.

> **Remaining gap**: the 4th combination — actively calling a Purchase Connector API from an SPM-only integration and confirming it raises `MissingPluginException` rather than crashing or hanging — has not been exercised by a real test, only reasoned through statically (see the tech design's corrected failure-mode analysis). This is a low-risk, non-blocking gap: the mechanism (`ENABLE_PURCHASE_CONNECTOR` never defined under SPM) is the same one already exercised today by the CocoaPods not-opted-in path, just reached a third way.
> **Remaining gap**: whether SPM+PurchaseConnector configured simultaneously silently drops Purchase Connector or actively fails with `MissingPluginException` has not been conclusively confirmed either way — investigation was inconclusive (see above) and this combination is now explicitly unsupported regardless of the answer, so it was not pursued further.

---

## Known Limitations
- **Purchase Connector is not available via SPM this release, with no opt-in mechanism at all.** `Package.swift` never references `ios/PurchaseConnector/` and has no equivalent of the podspec's `pod_target_xcconfig` macro injection, so `ENABLE_PURCHASE_CONNECTOR` is never defined for an SPM build under any configuration. Calling a Purchase Connector Dart API from an SPM-only integration fails with the same generic Flutter `MissingPluginException` that F-054 already documents for the CocoaPods not-opted-in case — this is not a new or worse failure mode, but it is a third, permanent path to it (not something a developer can fix by setting a flag, unlike the other two paths). Apps that need Purchase Connector must stay on CocoaPods until flutter/flutter#161182 is resolved.
- **SPM and Purchase Connector cannot be combined, even though nothing prevents an app from *configuring* both at once.** An app can set `$AppsFlyerPurchaseConnector = true` in its Podfile while also having SPM enabled — this doesn't crash or error at build time (verified: [run 29848672331](https://github.com/AppsFlyerSDK/appsflyer-flutter-plugin/actions/runs/29848672331) built and linked successfully) — but CI's logs suggest Flutter's tooling may silently drop the CocoaPods `PurchaseConnector` pod once it decides the plugin is SPM-eligible, meaning the feature may silently not be present despite looking configured. This was not conclusively resolved either way; instead of continuing to investigate, this combination is explicitly documented as unsupported (`doc/Installation.md`, `doc/PurchaseConnector.md`): **apps using Purchase Connector must not enable SPM for this plugin at all.**
- **flutter/flutter#161182 (Flutter's own plugin tooling lacking conditional-compilation support under SPM) is the real blocker**, not a SwiftPM limitation — investigated during research (`internal-docs/researches/R-001-spm-support.md`), including whether SwiftPM Package Traits (Swift tools 6.1+) could work around it. They cannot: the issue's own text states Flutter would need to add trait support to its plugin tooling first, which it has not.
- **Three architectural alternatives to bring Purchase Connector onto SPM were evaluated and rejected for this release** (see `internal-docs/researches/R-001-spm-support.md` addendum): a second product in the same `Package.swift` (not viable — Flutter's tooling only links one product per plugin, no documented support for a second), an environment-variable-gated compile flag (technically usable but fragile — requires every consuming app to set an env var on every build/CI run with silent failure if forgotten), and splitting Purchase Connector into its own federated pub.dev package (architecturally sound, no hidden blocker, but a separate, larger initiative with its own versioning/release pipeline — a candidate future initiative, not part of this ticket).
- **Real-device build verification is outstanding** — see Tests section above. Static/network verification (Swift manifest resolution, podspec lint, Dart test suite) passed, but the tech design's full 4-path device build has not yet run.

---

Expand Down