You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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>
Copy file name to clipboardExpand all lines: docs/features/F-060-swift-package-manager-support.md
+2-2Lines changed: 2 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -39,7 +39,7 @@ Shared source tree (used by both paths, single copy — no duplication):
39
39
40
40
SPM path (resolved by `flutter build`/`swift build` at build configuration time):
41
41
ios/appsflyer_sdk/Package.swift
42
-
→ target "appsflyer_sdk" depends on product "AppsFlyerLib" from AppsFlyerFramework, pinned from: "6.18.0"
42
+
→ target "appsflyer_sdk" depends on product "AppsFlyerLib" from AppsFlyerFramework, pinned exactly to 6.18.0
43
43
→ compiles the shared Sources/ tree above as a ClangTarget, iOS 12.0 minimum
44
44
→ does NOT reference ios/PurchaseConnector/ at all — no PurchaseConnector target/product exists in this manifest
45
45
@@ -54,7 +54,7 @@ CocoaPods path (resolved by `pod install` at install time, unchanged behavior):
54
54
## Files
55
55
| File | Role |
56
56
|------|------|
57
-
|`ios/appsflyer_sdk/Package.swift`| New SPM manifest. `swift-tools-version:5.9` (Xcode 15.0+), `platforms: [.iOS("12.0")]` (matches the podspec's existing deployment target). Declares one product/target depending on `AppsFlyerFramework`'s `AppsFlyerLib` product, `from: "6.18.0"`. |
57
+
|`ios/appsflyer_sdk/Package.swift`| New SPM manifest. `swift-tools-version:5.9` (Xcode 15.0+), `platforms: [.iOS("12.0")]` (matches the podspec's existing deployment target). Declares one product/target depending on `AppsFlyerFramework`'s `AppsFlyerLib` product, pinned `.exact("6.18.0")`, matching the podspec's exact CocoaPods pin. |
58
58
|`ios/appsflyer_sdk/Sources/appsflyer_sdk/*.m`| Core implementation files, moved verbatim from `ios/Classes/` via `git mv` (confirmed zero content diff) — now the single shared source tree for both CocoaPods and SPM. |
59
59
|`ios/appsflyer_sdk/Sources/appsflyer_sdk/include/appsflyer_sdk/*.h`| Public headers, moved verbatim from `ios/Classes/` — `AppsflyerSdkPlugin.h` is where `pluginClass: AppsflyerSdkPlugin` (declared in `pubspec.yaml`, unchanged) resolves from in both integration paths. |
60
60
|`ios/appsflyer_sdk.podspec`|`Core` subspec's `source_files`/`public_header_files` repointed to the new shared path; `PurchaseConnector` subspec is untouched. No marker added to declare SPM availability — Flutter's tooling detects it purely by the presence of `Package.swift` at the conventional path. |
**Correction to draft PR #454**: its PR description names the dependency product `AppsFlyerLib-Static`. I fetched `AppsFlyerFramework`'s actual `Package.swift` at tag `6.18.0` directly via GitHub API — the declared product name is `AppsFlyerLib`, not `AppsFlyerLib-Static` (that string only appears in the *binary artifact's zip filename*, not the SPM product). Using the wrong product name would fail dependency resolution outright. Pin `from: "6.18.0"` to match the podspec's existing `ss.ios.dependency 'AppsFlyerFramework','6.18.0'` — no native SDK version bump required (R-001 confirmed the 6.18.0 tag's own Package.swift resolves and is valid).
72
+
**Correction to draft PR #454**: its PR description names the dependency product `AppsFlyerLib-Static`. I fetched `AppsFlyerFramework`'s actual `Package.swift` at tag `6.18.0` directly via GitHub API — the declared product name is `AppsFlyerLib`, not `AppsFlyerLib-Static` (that string only appears in the *binary artifact's zip filename*, not the SPM product). Using the wrong product name would fail dependency resolution outright. Pin `.exact("6.18.0")` to match the podspec's existing `ss.ios.dependency 'AppsFlyerFramework','6.18.0'` exactly — no native SDK version bump required (R-001 confirmed the 6.18.0 tag's own Package.swift resolves and is valid).
73
+
74
+
**Correction (post-review)**: the original design used `from: "6.18.0"`, a semver-range requirement (`6.18.0..<7.0.0`) rather than an exact pin. This was caught during PR review — the CI E2E run cited in the PR's test plan actually resolved and ran against `AppsFlyerFramework`**6.18.1**, not 6.18.0, exposing a real asymmetry: CocoaPods consumers get exactly 6.18.0, SPM consumers could silently float onto any untested patch/minor release below 7.0.0. Changed to `.exact("6.18.0")` so both distribution paths pin identically. Re-verified via `swift package describe`: `Requirement: Exact: 6.18.0`.
73
75
74
76
### `ios/appsflyer_sdk.podspec` — path updates only, no marker needed
Copy file name to clipboardExpand all lines: plans/01-ios-spm-core-support.md
+5-5Lines changed: 5 additions & 5 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -16,8 +16,8 @@ Add a `Package.swift` for the plugin's **Core** module so SPM-enabled Flutter ap
16
16
17
17
| PR | Approach | Verdict |
18
18
|---|---|---|
19
-
|[#454](https://github.com/AppsFlyerSDK/appsflyer-flutter-plugin/pull/454) (`nurlangarash`) | True `git mv` of `Classes/*` → `ios/appsflyer_sdk/Sources/appsflyer_sdk/` (+headers → `.../include/appsflyer_sdk/`), podspec updated to match, single source of truth. Depends on `AppsFlyerFramework-Static` / product `AppsFlyerLib-Static` (matches `static_framework = true`). Copilot flagged `.iOS("12.0")`(invalid) and product/target name mismatch — **both already fixed** in follow-up commit `98d9938dd2`. PurchaseConnector explicitly untouched. |**Use this as the base.**|
20
-
|[#455](https://github.com/AppsFlyerSDK/appsflyer-flutter-plugin/pull/455) (`TeddyYeung`) | Duplicates Core sources into a second tree, leaves podspec pointing at old `Classes/` — two copies to maintain forever. Same `.iOS("12.0")`bug, **never fixed**. Adds `.gitignore` entries (`.build/`, `.swiftpm/`) — worth cherry-picking. | Reject the architecture; take only the `.gitignore` hunk. |
19
+
|[#454](https://github.com/AppsFlyerSDK/appsflyer-flutter-plugin/pull/454) (`nurlangarash`) | True `git mv` of `Classes/*` → `ios/appsflyer_sdk/Sources/appsflyer_sdk/` (+headers → `.../include/appsflyer_sdk/`), podspec updated to match, single source of truth. Depends on `AppsFlyerFramework-Static` / product `AppsFlyerLib-Static` (matches `static_framework = true`) — this product name is wrong, corrected to `AppsFlyerLib` during implementation. Copilot flagged `.iOS("12.0")`as invalid and a product/target name mismatch — the name mismatch was real, but the `.iOS("12.0")` flag was itself wrong (verified valid via `swift package describe`; not something that needed fixing). PurchaseConnector explicitly untouched. |**Use this as the base.**|
20
+
|[#455](https://github.com/AppsFlyerSDK/appsflyer-flutter-plugin/pull/455) (`TeddyYeung`) | Duplicates Core sources into a second tree, leaves podspec pointing at old `Classes/` — two copies to maintain forever. Uses the same `.iOS("12.0")`syntax, which is valid (see #454's corrected note) and was never actually a bug. Adds `.gitignore` entries (`.build/`, `.swiftpm/`) — worth cherry-picking. | Reject the architecture; take only the `.gitignore` hunk. |
21
21
|[#370](https://github.com/AppsFlyerSDK/appsflyer-flutter-plugin/pull/370) (`alejandro-all-win-software`, oldest) | Tried to fold PurchaseConnector itself into SPM via an env-var-gated target (`ENABLE_PURCHASE_CONNECTOR=1`) + dependency on `appsflyer-apple-purchase-connector`. Author's own comment: *"blocked by flutter/flutter#161182... if you find another way to opt in to Purchase Connector, I'd be happy to close this PR in favor of that approach."*|**Do not repeat this.** This is exactly the dead end DELIVERY-125462 tells us to route around by staying CocoaPods-only for PurchaseConnector. |
22
22
23
23
None of the three have maintainer review; all are `REVIEW_REQUIRED`/`BLOCKED` on branch protection only (CI/security scans pass on all three).
@@ -66,7 +66,7 @@ let package = Package(
66
66
]
67
67
)
68
68
```
69
-
Anti-pattern guard (from Copilot's actual review on #454): `.iOS("12.0")` is **not** valid SwiftPM API — must be `.iOS(.v12)`. Library name uses hyphens (`appsflyer-sdk`), target/package name keeps underscores (`appsflyer_sdk`) — this is Flutter's documented convention, not a typo.
69
+
~~Anti-pattern guard (from Copilot's actual review on #454): `.iOS("12.0")` is **not** valid SwiftPM API — must be `.iOS(.v12)`.~~**Corrected during implementation review**: this claim is wrong. `SupportedPlatform.IOSVersion` conforms to `ExpressibleByStringLiteral`, so `.iOS("12.0")` is valid and compiles. Verified directly: the shipped `Package.swift` uses `.iOS("12.0")` and `swift package describe` resolves `Platforms: Name: ios, Version: 12.0` with no error. Both `.iOS("12.0")` and `.iOS(.v12)` work; this repo uses the former. Library name uses hyphens (`appsflyer-sdk`), target/package name keeps underscores (`appsflyer_sdk`) — this is Flutter's documented convention, not a typo.
2. Confirm `Package.swift` matches the corrected form in Phase 0.B exactly (`.iOS(.v12)`, not `.iOS("12.0")`; product `AppsFlyerLib-Static` from `AppsFlyerFramework-Static`, pinned `exact: "6.18.0"` to match the podspec's `AppsFlyerFramework` pin).
124
+
2. Confirm `Package.swift` matches the shipped, verified form: `.iOS("12.0")` (confirmed valid — see Phase 0.B correction); product `AppsFlyerLib` from `AppsFlyerFramework` (not `AppsFlyerLib-Static`/`AppsFlyerFramework-Static` — that naming was wrong, see #454 correction above), pinned `.exact("6.18.0")` to match the podspec's `AppsFlyerFramework` pin exactly.
125
125
3. Confirm `cSettings: [.headerSearchPath("include/appsflyer_sdk")]` is present (required for the `.m` files' `#import` statements to resolve).
126
126
4. Confirm all 4 public headers live under `Sources/appsflyer_sdk/include/appsflyer_sdk/` and the 3 `.m` files live directly under `Sources/appsflyer_sdk/` (not under `include/`).
127
127
@@ -197,6 +197,6 @@ This is a **plugin-only** change (adds SPM plumbing, does not touch native SDK v
197
197
2. All four build-matrix rows in Phase 5 verified with evidence (CI logs or local build output).
198
198
3.`CHANGELOG.md` and `pubspec.yaml` version bumped per Phase 3.
199
199
4.`doc/Installation.md` and `doc/PurchaseConnector.md` updated per Phase 4, explicitly stating the PurchaseConnector/SPM limitation.
200
-
5. No `.iOS("12.0")`-style invalid SwiftPM API left in `Package.swift` (`grep -n '\.iOS(\"' ios/appsflyer_sdk/Package.swift`should return nothing).
200
+
5.~~No `.iOS("12.0")`-style invalid SwiftPM API left in `Package.swift`~~ — retracted: `.iOS("12.0")` is valid (verified via `swift package describe`); the shipped `Package.swift`intentionally uses this form.
201
201
6. No duplicate source files between `ios/Classes/` (should no longer exist) and `ios/appsflyer_sdk/Sources/`.
202
202
7. Ready to open a PR against DELIVERY-125462, referencing and closing out #454/#455/#370 in the description (crediting their work, explaining why #454 was chosen as base).
0 commit comments