Skip to content

feat(ios): Add Swift Package Manager (SPM) support#235

Open
TheoGermain wants to merge 2 commits into
mixpanel:mainfrom
TheoGermain:feat/swift-package-manager-support
Open

feat(ios): Add Swift Package Manager (SPM) support#235
TheoGermain wants to merge 2 commits into
mixpanel:mainfrom
TheoGermain:feat/swift-package-manager-support

Conversation

@TheoGermain
Copy link
Copy Markdown

@TheoGermain TheoGermain commented May 5, 2026

Closes #176.

Summary

Adds a Package.swift manifest for the iOS plugin so apps using Flutter's
Swift Package Manager integration can resolve mixpanel_flutter natively
instead of falling back to CocoaPods. CocoaPods consumers are unaffected —
the .podspec still works and is unchanged in semantics.

The scope of this PR is iOS only. macOS still uses CocoaPods; SPM support
for macOS can be added in a follow-up since it is largely the same pattern.

What changed

Area Change
ios/mixpanel_flutter/Package.swift New SPM manifest. Single pure-Swift target. Depends on mixpanel-swift 6.3.0 (pinned to the same exact version as the podspec). iOS 12.0 minimum (matches the podspec).
ios/mixpanel_flutter/Sources/mixpanel_flutter/ Swift sources moved to the SPM-expected layout. The two files are symlinks back to the canonical shared sources in swift/Classes/, mirroring the pattern already used by macos/Classes/.
ios/mixpanel_flutter.podspec source_files updated to point at the new Sources/ directory.
swift/Classes/SwiftMixpanelFlutterPlugin.swift Added @objc(MixpanelFlutterPlugin) to expose the Swift class to Obj-C registrants under the same name as the previous Obj-C wrapper. This preserves backwards compatibility for projects with an Obj-C AppDelegate.
ios/Classes/ Removed. The Obj-C wrapper (.h/.m) is no longer needed since the Swift class is now @objc-exposed under the expected name. The old Swift symlinks here are replaced by the equivalent ones under the new Sources/ layout.

Why eliminate the Obj-C wrapper

The previous MixpanelFlutterPlugin.{h,m} only existed to bridge from
Obj-C-named MixpanelFlutterPlugin → Swift SwiftMixpanelFlutterPlugin.
Mixed Swift+Obj-C SPM targets are awkward (SPM does not natively support
mixed-language targets in a single module).

By annotating the Swift class with @objc(MixpanelFlutterPlugin):

  • Obj-C consumers (legacy AppDelegate.m projects) still find the class as
    MixpanelFlutterPlugin — no behavior change.
  • Swift consumers continue to use either name.
  • The SPM manifest can stay simple (single Swift target).

This mirrors the approach already taken on macOS (where a Swift typealias
serves the same purpose, no Obj-C wrapper).

Verification

  • flutter pub get succeeds in example/ with SPM enabled
    (flutter config --enable-swift-package-manager)
  • flutter run builds and launches on an iOS simulator with SPM enabled
  • flutter run builds and launches on an iOS simulator with SPM disabled
    (CocoaPods path)
  • pod lib lint ios/mixpanel_flutter.podspec still passes
  • Obj-C AppDelegate consumers still resolve MixpanelFlutterPlugin
    via the auto-generated registrant

Follow-ups (out of scope here)

References

Adds a Package.swift manifest for the iOS plugin so apps using Flutter's
Swift Package Manager integration can resolve mixpanel_flutter natively
instead of falling back to CocoaPods.

Closes mixpanel#176

Changes:
- ios/mixpanel_flutter/Package.swift: SPM manifest declaring a single
  pure-Swift target that depends on Mixpanel-swift 6.3.0 (matches the
  existing podspec dependency exactly).
- ios/mixpanel_flutter/Sources/mixpanel_flutter/: Swift sources moved
  into the SPM-expected layout. Files are symlinks back to the canonical
  shared sources in swift/Classes/, mirroring the pattern already used
  by macos/Classes/.
- ios/mixpanel_flutter.podspec: source_files path updated to point at
  the new Sources directory. CocoaPods consumers are unaffected.
- swift/Classes/SwiftMixpanelFlutterPlugin.swift: added
  @objc(MixpanelFlutterPlugin) to expose the Swift class to Obj-C
  registrants under the same name as the previous wrapper. This
  preserves backwards compatibility for projects with an Obj-C
  AppDelegate.
- ios/Classes/: removed. The Obj-C wrapper (.h/.m) is no longer needed
  since the Swift class is now @objc-exposed under the expected name.
  The old Swift symlinks here are replaced by the equivalent ones under
  the new Sources/ layout.

macOS is unchanged (Pod-only) — left for a follow-up.
@TheoGermain TheoGermain requested review from a team and tylerjroach May 5, 2026 14:08
@ketanmixpanel
Copy link
Copy Markdown
Contributor

Thanks for the detailed PR @TheoGermain, really appreciate the writeup and the verification checklist. I'll review and update here.

@ketanmixpanel ketanmixpanel self-requested a review May 7, 2026 16:45
@ketanmixpanel
Copy link
Copy Markdown
Contributor

Hi @TheoGermain, I tried running the example app with SPM enabled and the build is failing with the error below. Can you confirm if it works on your end?

An error occurred when adding Swift Package Manager integration:
  Error: Unable to get Xcode project information:
 2026-05-12 14:41:08.488 xcodebuild[48151:426773] Writing error result bundle to
 /var/folders/zt/q91rmj8551b03mjskx4k5_cw0000gn/T/ResultBundle_2026-12-05_14-41-0008.xcresult
xcodebuild: error: Could not resolve package dependencies:
  unable to override package 'mixpanel_flutter' because its identity 'mixpanel-flutter' doesn't match override's identity (directory name) 'mixpanel_flutter'
  fatalError

Thanks!

…RL identity

SPM derives a package's identity from the directory name for local path
dependencies. The repository URL is `github.com/mixpanel/mixpanel-flutter`
(hyphen), so the expected identity is `mixpanel-flutter`. Flutter's SPM
integration was pointing at the `mixpanel_flutter` directory (underscore),
causing an identity mismatch:

  unable to override package 'mixpanel_flutter' because its identity
  'mixpanel-flutter' doesn't match override's identity (directory
  name) 'mixpanel_flutter'

Changes:
- Rename ios/mixpanel_flutter/ → ios/mixpanel-flutter/
- Update Package.swift name: "mixpanel_flutter" → "mixpanel-flutter"
- Add swiftPackageName: mixpanel-flutter to pubspec.yaml iOS platform
- Update podspec source_files path to match new directory name
@TheoGermain
Copy link
Copy Markdown
Author

Hi @ketanmixpanel, good catch — thank you for testing!

The root cause is an SPM package identity mismatch. SPM derives a package's identity from the directory name for local path overrides. Flutter was pointing at the ios/mixpanel_flutter/ directory (underscore), but the canonical identity from the repository URL github.com/mixpanel/mixpanel-flutter is mixpanel-flutter (hyphen). These two identities don't match, hence the error.

I just pushed a fix (aae8970) that makes three changes:

  1. Renames ios/mixpanel_flutter/ios/mixpanel-flutter/ so the directory-based identity matches the URL identity.
  2. Updates Package.swift name: "mixpanel_flutter"name: "mixpanel-flutter" to be consistent.
  3. Adds swiftPackageName: mixpanel-flutter to pubspec.yaml under the ios: platform so Flutter's toolchain knows to look in ios/mixpanel-flutter/ rather than the default ios/mixpanel_flutter/.

The podspec source_files path is also updated accordingly. Could you try re-running the example with the updated branch? Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add support to Swift Package Manager

3 participants