DELIVERY-125462: Add Swift Package Manager (SPM) support for Core - #459
Conversation
Adds ios/appsflyer_sdk/Package.swift for the Core iOS integration, moving ios/Classes/ into an SPM-compatible shared source tree that both CocoaPods and SPM compile from. Purchase Connector stays CocoaPods-only, blocked upstream by flutter/flutter#161182. Updates F-054 and adds F-060 in the feature catalog, plus PRD, research, and tech design docs for the delivery workflow. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Package.swift pinned AppsFlyerFramework with `from: "6.18.0"` (a
semver range, ..<7.0.0), while the podspec pins CocoaPods to exactly
6.18.0. CI's own iOS E2E run exposed the drift: it resolved and ran
against 6.18.1 via SPM. Switch to `.exact("6.18.0")` so both
distribution paths pin identically, and correct the docs/plan that
described the old pin as correct.
Also retracts a stale claim in plans/01-ios-spm-core-support.md that
`.iOS("12.0")` is invalid SwiftPM syntax — verified valid via
`swift package describe`.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Dani-Koza-AF
left a comment
There was a problem hiding this comment.
The core mechanics are sound and, verified against Flutter's official plugin-author SPM guide. Great work.
Additional General note, can we rename docs/ to something clearly internal (e.g. internal-docs/)? It's one letter off from the user-facing doc/, so the two are easy to confuse.
There was a problem hiding this comment.
Shouldn't be commited
There was a problem hiding this comment.
Shouldn't be committed
| .library(name: "appsflyer-sdk", targets: ["appsflyer_sdk"]) | ||
| ], | ||
| dependencies: [ | ||
| .package(url: "https://github.com/AppsFlyerSDK/AppsFlyerFramework.git", .exact("6.18.0")) |
There was a problem hiding this comment.
Pinning .exact here is the right call for parity with the podspec. But the green iOS E2E linked in the description ran before this line changed (it resolved 6.18.1 via from:), so we don't have a passing SPM build for the 6.18.0 we're actually shipping.
Can we re-run the SPM E2E on this commit before RC?
There was a problem hiding this comment.
or just resolve if SPM E2E passed
| - `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). | ||
|
|
||
| > **Outstanding pre-release gate**: the tech design's mandatory 4-path real-device build verification (SPM Core-only / CocoaPods Core-only / CocoaPods Core+PurchaseConnector / confirming SPM+PurchaseConnector is inert, all on real devices, not `--no-codesign` alone) has **not yet been run** — it requires a full macOS/Xcode/iOS-device environment that was unavailable during implementation. This must be completed before this ships (before promoting through the RC pipeline). See `docs/tech-designs/spm-support.md` for the exact verification steps. |
There was a problem hiding this comment.
This says the 4-path device verification hasn't run yet, but the PR description says the E2E "passed in full." Those don't agree. Let's reconcile, and make sure the CocoaPods Core+PurchaseConnector path is re-checked before we promote.
| - Updated iOS SDK from 6.17.9 to 6.18.0 | ||
| - Updated iOS Purchase Connector from 6.17.9 to 6.18.0 | ||
| - Fixed Android warm-app deep link consumption race so `DeepLinkListener` fires reliably when the app is resumed from a `VIEW` intent (forward new intents to `AppsFlyerLib` from the plugin's `onNewIntentListener` before the SDK's `onResume` auto-handler marks them `af_consumed`) | ||
| - Added Swift Package Manager (SPM) support for the Core iOS integration (`ios/appsflyer_sdk/Package.swift`), alongside continued full CocoaPods support — no behavior change for existing CocoaPods consumers. Purchase Connector remains CocoaPods-only for now, pending resolution of an upstream Flutter limitation ([flutter/flutter#161182](https://github.com/flutter/flutter/issues/161182)) that blocks conditionally-compiled plugin features under SPM. |
There was a problem hiding this comment.
Good release note. The ticket also asks for the user-facing guides though, and doc/Installation.md and doc/PurchaseConnector.md still say nothing about SPM or that Purchase Connector needs CocoaPods.
Can we add that so PC users don't just hit a MissingPluginException with no explanation?
| targets: [ | ||
| .target( | ||
| name: "appsflyer_sdk", | ||
| dependencies: [ | ||
| .product(name: "AppsFlyerLib", package: "AppsFlyerFramework") | ||
| ], | ||
| cSettings: [ | ||
| .headerSearchPath("include/appsflyer_sdk") | ||
| ] | ||
| ) |
There was a problem hiding this comment.
Minor: the target declares no PrivacyInfo.xcprivacy. That's fine if our own ObjC doesn't call any required-reason APIs (the SDK xcframework ships its own manifest), but worth a quick confirm rather than assuming.
Same rationale as #460: docs/ was one letter off from the user-facing doc/, easy to confuse. Renames this branch's own docs/prds/, docs/researches/, docs/tech-designs/, and docs/features/ additions (F-054, F-060), fixes the tech design's frontmatter self-references (prd:/research: fields), and picks up two files #460 missed (ai-delivery-workflow-templat/README.md, update-existing-repo.md). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
Thanks @Dani-Koza-AF! Good catch on
Recommend merging #460 first so this PR's diff picks up the rename cleanly. |
* Rename docs/ to internal-docs/ Addresses review feedback on #459: docs/ was one letter off from the user-facing doc/ (per-feature integration guides consumed by SDK users), making the two easy to confuse. Renames the directory and updates every internal reference in CLAUDE.md and .claude/ to match. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> * Fix two files missed in the docs/ rename ai-delivery-workflow-templat/README.md and update-existing-repo.md still referenced the old docs/ path. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
Per Dani's review on #459: plans/01-ios-spm-core-support.md and templates/af-tech-quiz-template.html shouldn't be committed to the repo. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Per Dani's review on #459: - doc/Installation.md: new section on iOS SPM support for Core, with a pointer to the PurchaseConnector CocoaPods-only caveat. - doc/PurchaseConnector.md: explicit warning that Purchase Connector requires CocoaPods even when the app has adopted SPM for Core, and what happens (MissingPluginException) if it's skipped entirely. - F-060: fixed two docs/researches/... references missed in the earlier docs/ -> internal-docs/ rename sweep. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Per Dani's review: F-060 said device verification hadn't run while the PR description said E2E passed in full. Reconciled with links to all 3 real CI runs now completed, and honestly flagged the one remaining gap (SPM+PurchaseConnector inertness was reasoned through, not actively tested). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
@Dani-Koza-AF — sorry, I'd only caught your top-level review comment before, not the inline ones. Went through all of them now:
SPM E2E was tested against the wrong pin — you're right, the originally-linked run tested F-060 vs. PR description contradiction — reconciled ( User-facing docs missing SPM/PurchaseConnector guidance — added ( Privacy manifest — already checked during research, just hadn't reported it back here: I downloaded and inspected the actual Everything above is on this branch — no new PRs. |
Dani-Koza-AF
left a comment
There was a problem hiding this comment.
Looks goof, loved the hybrid approach with PC.
Summary
ios/appsflyer_sdk/Package.swiftfor the plugin's Core iOS integration, movingios/Classes/into an SPM-compatible shared source tree that both CocoaPods and SPM compile from (verified directly against Flutter's official plugin-author SPM migration guide, not just copied from prior draft PRs feat(ios): add Swift Package Manager support for Core #454/feat(ios): add Swift Package Manager support #455).AppsFlyerFramework's actual product nameAppsFlyerLib, notAppsFlyerLib-Staticas that PR's description claimed — verified by resolving live against the upstream repo (swift package describe).docs/researches/R-001-spm-support.md) — none viable for this release; a federated package split is the one real path if this becomes a hard requirement later.F-054(Purchase Connector: Build-Time Opt-in) to document the new SPM path as a third, permanently-excluded gate, and addsF-060(Swift Package Manager Support) to the feature catalog.docs/prds/spm-support.md,docs/researches/R-001-spm-support.md,docs/tech-designs/spm-support.md).Test plan
flutter test test— all 38 existing Dart tests pass, unaffected (iOS-only change).pod spec lint --quick --allow-warnings— passes; confirms the podspec's repointed paths resolve.swift package describe— live dependency resolution against the realAppsFlyerFrameworkrepo confirms the correctedAppsFlyerLibproduct resolves at6.18.0..<7.0.0.ENV_FILEsecret, confirming Flutter actually activated the SPM manifest during the build and the app initializes, links, and drives real attribution traffic end to end. Run: https://github.com/AppsFlyerSDK/appsflyer-flutter-plugin/actions/runs/29748317820🤖 Generated with Claude Code